// Example_functions draws some functions. func Example_functions() *plot.Plot { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Functions" p.X.Label.Text = "X" p.Y.Label.Text = "Y" quad := plotter.NewFunction(func(x float64) float64 { return x * x }) quad.Color = color.RGBA{B: 255, A: 255} exp := plotter.NewFunction(func(x float64) float64 { return math.Pow(2, x) }) exp.Dashes = []vg.Length{vg.Points(2), vg.Points(2)} exp.Width = vg.Points(2) exp.Color = color.RGBA{G: 255, A: 255} sin := plotter.NewFunction(func(x float64) float64 { return 10*math.Sin(x) + 50 }) sin.Dashes = []vg.Length{vg.Points(4), vg.Points(5)} sin.Width = vg.Points(4) sin.Color = color.RGBA{R: 255, A: 255} p.Add(quad, exp, sin) p.Legend.Add("x^2", quad) p.Legend.Add("2^x", exp) p.Legend.Add("10*sin(x)+50", sin) p.Legend.ThumbnailWidth = 0.5 * vg.Inch p.X.Min = 0 p.X.Max = 10 p.Y.Min = 0 p.Y.Max = 100 return p }
// 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 }
func main() { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Functions" p.X.Label.Text = "X" p.Y.Label.Text = "Y" // A quadratic function x^2 quad := plotter.NewFunction(func(x float64) float64 { return x * x }) quad.Color = color.RGBA{B: 255, A: 255} // An exponential function 2^x exp := plotter.NewFunction(func(x float64) float64 { return math.Pow(2, x) }) exp.Dashes = []vg.Length{vg.Points(2), vg.Points(2)} exp.Width = vg.Points(2) exp.Color = color.RGBA{G: 255, A: 255} // The sine function, shifted and scaled // to be nicely visible on the plot. sin := plotter.NewFunction(func(x float64) float64 { return 10*math.Sin(x) + 50 }) sin.Dashes = []vg.Length{vg.Points(4), vg.Points(5)} sin.Width = vg.Points(4) sin.Color = color.RGBA{R: 255, A: 255} // Add the functions and their legend entries. p.Add(quad, exp, sin) p.Legend.Add("x^2", quad) p.Legend.Add("2^x", exp) p.Legend.Add("10*sin(x)+50", sin) p.Legend.ThumbnailWidth = vg.Inch * 0.5 // Set the axis ranges. Unlike other data sets, // functions don't set the axis ranges automatically // since functions don't necessarily have a // finite range of x and y values. p.X.Min = 0 p.X.Max = 10 p.Y.Min = 0 p.Y.Max = 100 // Save the plot to a PNG file. if err := p.Save(4*vg.Inch, 4*vg.Inch, "functions.png"); err != nil { panic(err) } }
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 } } } }