// Plots the historgram using plotinum func Histogram(r RetCalc) { //eb := all_paths.End_balances() eb := make([]float64, len(r.all_paths), len(r.all_paths)) incs := r.RunIncomes() for i := range incs { eb[i] = incs[i] } v := make(plotter.Values, len(eb)) for i := range v { v[i] = eb[i] } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Histogram" h, err := plotter.NewHist(v, 100) if err != nil { panic(err) } //h.Normalize(1) p.Add(h) if err := p.Save(4, 4, "hist.png"); err != nil { panic(err) } fmt.Println(h) }
// An example of making a histogram. func Example_histogram() *plot.Plot { rand.Seed(int64(0)) n := 10000 vals := make(plotter.Values, n) for i := 0; i < n; i++ { vals[i] = rand.NormFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Histogram" h, err := plotter.NewHist(vals, 16) if err != nil { panic(err) } h.Normalize(1) p.Add(h) // The normal distribution function norm := plotter.NewFunction(stdNorm) norm.Color = color.RGBA{R: 255, A: 255} norm.Width = vg.Points(2) p.Add(norm) return p }
// makePlots creates and saves both histogram plots. func makePlots(v, vl plotter.Values) error { // Create a new plot and set the title. p1, err := plot.New() if err != nil { return errors.Wrap(err, "Could not generate a new plot") } p1.Title.Text = "Histogram of Github Stars" // Create a second plot and set the title. p2, err := plot.New() if err != nil { return errors.Wrap(err, "Could not generate a new plot") } p2.Title.Text = "Histogram of log(Github Stars)" // Create a histogram and add it to plot 1. h1, err := plotter.NewHist(v, 16) if err != nil { return errors.Wrap(err, "Could not create histogram") } p1.Add(h1) // Create a histogram and add it to plot 2. h2, err := plotter.NewHist(vl, 16) if err != nil { return errors.Wrap(err, "Could not create histogram") } p2.Add(h2) // Save plot 1's histogram in the current directory. if err := p1.Save(4*vg.Inch, 4*vg.Inch, "hist1.png"); err != nil { return errors.Wrap(err, "Could not save plot") } // Save plot 2's histogram in the current directory. if err := p2.Save(4*vg.Inch, 4*vg.Inch, "hist2.png"); err != nil { return errors.Wrap(err, "Could not save plot") } return nil }
// Builds a histogram from a []float64 slice :) func HistoFromSlice(slice []float64) *plotter.Histogram { fmt.Println("HistoFromSlice() call - slice analytics:") fmt.Printf("Max: %f\n", analytics.MaxF64(slice)) fmt.Printf("Min: %f\n", analytics.MinF64(slice)) fmt.Printf("Avg: %f\n", analytics.AvgF64(slice)) v := make(plotter.Values, len(slice)) for i := range v { v[i] = slice[i] } h, err := plotter.NewHist(v, 150) if err != nil { panic(err) } return h }
func main() { suppressWarnings := flag.Bool("suppress", false, "suppress warnings in the input data") doPlot := flag.Bool("plot", false, "plot a histogram and the standard normal distribution") flag.Parse() c := csv.NewReader(bufio.NewReader(os.Stdin)) headers, err := c.Read() if err != nil { log.Fatalf("Could not read header: %v", err) } stats := make([]*columnStatistic, 0, len(headers)) for _, name := range headers { stats = append(stats, &columnStatistic{ name: name, }) } line := 0 for { line++ columns, err := c.Read() if err != nil { if err == io.EOF { // Print statistics w := tabwriter.NewWriter(os.Stdout, 5, 8, 1, '\t', tabwriter.AlignRight) fmt.Fprint(w, "\n\tmin\tmax\tmean\tstddev\n") for _, s := range stats { mean, stddev := stat.MeanStdDev(s.obsv, nil) fmt.Fprintf(w, "%s\t%f\t%f\t%f\t%f\n", s.name, s.min, s.max, mean, stddev) } w.Flush() if *doPlot { for _, s := range stats { mean, stddev := stat.MeanStdDev(s.obsv, nil) p, err := plot.New() if err != nil { panic(err) } p.X.Min = s.min - 1.5*stddev p.X.Max = s.max + 1.5*stddev p.Title.Text = fmt.Sprintf("Histogram for %s", s.name) h, err := plotter.NewHist(plotter.Values(s.obsv), 16) if err != nil { panic(err) } h.Normalize(1) p.Add(h) norm := plotter.NewFunction(func(x float64) float64 { return 1.0 / (stddev * math.Sqrt(2*math.Pi)) * math.Exp(-((x-mean)*(x-mean))/(2*stddev*stddev)) }) norm.Samples = int(p.X.Max-p.X.Min) + 100 norm.Color = color.RGBA{R: 255, A: 255} norm.Width = vg.Points(2) p.Add(norm) // Save the plot to a PNG file. if err := p.Save(4*vg.Inch, 4*vg.Inch, fmt.Sprintf("histogram-%s.png", s.name)); err != nil { log.Fatal(err) } } } return } if !*suppressWarnings { fmt.Fprintf(os.Stderr, "Could not parse line (line %d, '%s'): %v\n", line, columns, err) } continue } for i, data := range columns { s := stats[i] if s.typ == unknown { // Determine the column's data type _, err := strconv.ParseFloat(data, 64) switch { case err == nil: // Is numeric s.typ = numeric case err != nil: s.typ = text } } var f float64 switch s.typ { case numeric: f, err = strconv.ParseFloat(data, 64) if err != nil { if !*suppressWarnings { fmt.Fprintf(os.Stderr, "Could not parse numeric value (line %d, '%s'): %v\n", line, data, err) } continue } if math.IsNaN(f) { if !*suppressWarnings { fmt.Fprintf(os.Stderr, "Could not parse numeric value (line %d, '%s'): is not a number\n", line, data) } continue } if math.IsInf(f, 0) { if !*suppressWarnings { fmt.Fprintf(os.Stderr, "Could not parse numeric value (line %d, '%s'): infinity\n", line, data) } continue } case text: // we take the text length as the according metric f = float64(len(data)) default: panic("unknown data type") } s.obsv = append(s.obsv, f) if f < s.min { s.min = f } if f > s.max { s.max = f } } } }