diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/jp/canvas_other.go | 1 | ||||
-rw-r--r-- | cmd/jp/canvas_windows.go | 1 | ||||
-rw-r--r-- | cmd/jp/heatmap.go | 55 | ||||
-rw-r--r-- | cmd/jp/hist.go | 2 | ||||
-rw-r--r-- | cmd/jp/main.go | 13 |
5 files changed, 69 insertions, 3 deletions
diff --git a/cmd/jp/canvas_other.go b/cmd/jp/canvas_other.go index 053cef7..db0b3d4 100644 --- a/cmd/jp/canvas_other.go +++ b/cmd/jp/canvas_other.go @@ -7,4 +7,5 @@ var autoCanvas = map[string]string{ plotTypeLine: canvasTypeQuarter, plotTypeScatter: canvasTypeBraille, plotTypeHist: canvasTypeQuarter, + plotTypeHeatmap: canvasTypeFull, } diff --git a/cmd/jp/canvas_windows.go b/cmd/jp/canvas_windows.go index de22e5b..56cc212 100644 --- a/cmd/jp/canvas_windows.go +++ b/cmd/jp/canvas_windows.go @@ -7,4 +7,5 @@ var autoCanvas = map[string]string{ plotTypeLine: canvasTypeFull, plotTypeScatter: canvasTypeFull, plotTypeHist: canvasTypeFull, + plotTypeHeatmap: canvasTypeFull, } diff --git a/cmd/jp/heatmap.go b/cmd/jp/heatmap.go new file mode 100644 index 0000000..9ebd2fe --- /dev/null +++ b/cmd/jp/heatmap.go @@ -0,0 +1,55 @@ +package main + +import ( + "log" + "reflect" + + "github.com/sgreben/jp/pkg/data" + "github.com/sgreben/jp/pkg/draw" + "github.com/sgreben/jp/pkg/plot" +) + +func heatmapData(xv []reflect.Value, yv []reflect.Value, nbins uint) (heatmap *data.Heatmap) { + var x, y []float64 + for i := range xv { + if xv[i].IsValid() && xv[i].CanInterface() { + xvi, ok := xv[i].Interface().(float64) + if ok { + x = append(x, xvi) + } + } + } + for i := range yv { + if yv[i].IsValid() && yv[i].CanInterface() { + yvi, ok := yv[i].Interface().(float64) + if ok { + y = append(y, yvi) + } + } + } + if len(x) != len(y) { + log.Fatal(len(x), " = len(x) != len(y) = ", len(y)) + } + points := make([][2]float64, len(x)) + for i := 0; i < len(x); i++ { + points[i] = [2]float64{x[i], y[i]} + } + if len(x) == 0 { + log.Fatal("no valid x values given") + } + bins := data.NewBins2D(points) + bins.X.Number = int(nbins) + bins.Y.Number = int(nbins) + if nbins == 0 { + bins.X.Number = data.BinsSturges(len(points)) + bins.Y.Number = data.BinsSturges(len(points)) + } + heatmap = data.NewHeatmap(data.Histogram2D(points, bins)) + return +} + +func heatmap(xv, yv []reflect.Value, c draw.Canvas, nbins uint) string { + heatmap := heatmapData(xv, yv, nbins) + chart := plot.NewHeatMap(c.GetBuffer()) + return chart.Draw(heatmap) +} diff --git a/cmd/jp/hist.go b/cmd/jp/hist.go index 77c04e6..c49f387 100644 --- a/cmd/jp/hist.go +++ b/cmd/jp/hist.go @@ -25,7 +25,7 @@ func histogramData(xv []reflect.Value, nbins uint) (groups []string, counts []fl bins := data.NewBins(x) bins.Number = int(nbins) if nbins == 0 { - bins.ChooseSturges() + bins.Number = data.BinsSturges(len(x)) } hist := data.Histogram(x, bins) groups = make([]string, len(hist)) diff --git a/cmd/jp/main.go b/cmd/jp/main.go index 173ac27..ac5b099 100644 --- a/cmd/jp/main.go +++ b/cmd/jp/main.go @@ -31,6 +31,7 @@ const ( plotTypeBar = "bar" plotTypeScatter = "scatter" plotTypeHist = "hist" + plotTypeHeatmap = "hist2d" ) const ( @@ -53,6 +54,7 @@ var config = configuration{ plotTypeBar, plotTypeScatter, plotTypeHist, + plotTypeHeatmap, }, }, CanvasType: enumVar{ @@ -123,6 +125,11 @@ func init() { } func match(in interface{}, p *jsonpath.JSONPath) [][]reflect.Value { + defer func() { + if r := recover(); r != nil { + log.Println("error evaluating JSONPath", p.String+":", r) + } + }() out, err := p.FindResults(in) if err != nil { log.Println(err) @@ -137,13 +144,13 @@ func main() { dec := json.NewDecoder(os.Stdin) err := dec.Decode(&in) if err != nil { - log.Println(err) + log.Println(inputTypeJSON, "input:", err) } case inputTypeCSV: r := csv.NewReader(os.Stdin) rows, err := r.ReadAll() if err != nil { - log.Println(err) + log.Println(inputTypeCSV, "input:", err) } in = parseRows(rows) } @@ -175,5 +182,7 @@ func main() { fmt.Println(barPlot(x, y, c)) case plotTypeHist: fmt.Println(histogram(x, c, config.HistBins)) + case plotTypeHeatmap: + fmt.Println(heatmap(x, y, c, config.HistBins)) } } |