/
plothist.go
67 lines (56 loc) · 1.85 KB
/
plothist.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package perf
import (
"image/color"
"io"
"github.com/gonum/stat/distuv"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/vg"
)
// PlotHist renders a histogram plot to a writer.
// Param format can be anything supported by gonum.org/v1/plot/vg
func PlotHist(series []float64, writer io.Writer, nBins int, title string, format string) (int64, error) {
norm := false
return plotHistWithNormOpt(series, norm, writer, nBins, title, format)
}
// PlotHistStdNormDist renders a histogram plot to a writer.
// Normalizes the area under the series to 1 and adds a std normal distribution plot.
// Param format can be anything supported by gonum.org/v1/plot/vg
func PlotHistStdNormDist(series []float64, writer io.Writer, nBins int, title string, format string) (int64, error) {
norm := true
return plotHistWithNormOpt(series, norm, writer, nBins, title, format)
}
func plotHistWithNormOpt(series []float64, plotNorm bool, writer io.Writer, nBins int, title string, format string) (int64, error) {
// Copy series values into plotter format
vs := make(plotter.Values, len(series))
for i := range vs {
vs[i] = series[i]
}
// Make a plot and set its title
p := plot.New()
p.Title.Text = title
// Create a histogram of our values
h, err := plotter.NewHist(vs, nBins)
if err != nil {
return 0, err
}
if plotNorm {
// Normalize the area under the histogram to sum to one
// Required to correctly render the additional probability distribution
h.Normalize(1)
p.Add(h)
// Plot normal distribution function and add to hist
norm := plotter.NewFunction(distuv.UnitNormal.Prob)
norm.Color = color.RGBA{R: 255, A: 255}
norm.Width = vg.Points(2)
p.Add(norm)
} else {
p.Add(h)
}
// Render the plot to the writer.
writeTo, err := p.WriterTo(4*vg.Inch, 4*vg.Inch, format)
if err != nil {
return 0, err
}
return writeTo.WriteTo(writer)
}