// AddErrorBars adds XErrorBars and YErrorBars // to a plot. The variadic arguments must be // of type plotter.XYer, and must be either a // plotter.XErrorer, plotter.YErrorer, or both. // Each errorer is added to the plot the color from // the Colors function corresponding to its position // in the argument list. func AddErrorBars(plt *plot.Plot, vs ...interface{}) { for i, v := range vs { added := false if xerr, ok := v.(interface { plotter.XYer plotter.XErrorer }); ok { e := plotter.NewXErrorBars(xerr) e.Color = Color(i) plt.Add(e) added = true } if yerr, ok := v.(interface { plotter.XYer plotter.YErrorer }); ok { e := plotter.NewYErrorBars(yerr) e.Color = Color(i) plt.Add(e) added = true } if added { continue } panic(fmt.Sprintf("AddErrorBars expects plotter.XErrorer or plotter.YErrorer, got %T", v)) } }
// Example_errBars draws points and error bars. func Example_errBars() *plot.Plot { type errPoints struct { plotter.XYs plotter.YErrors plotter.XErrors } rand.Seed(int64(0)) n := 15 data := errPoints{ XYs: randomPoints(n), YErrors: plotter.YErrors(randomError(n)), XErrors: plotter.XErrors(randomError(n)), } p, err := plot.New() if err != nil { panic(err) } scatter := must(plotter.NewScatter(data)).(*plotter.Scatter) scatter.Shape = plot.CrossGlyph{} xerrs, err := plotter.NewXErrorBars(data) if err != nil { panic(err) } yerrs, err := plotter.NewYErrorBars(data) if err != nil { panic(err) } p.Add(scatter, xerrs, yerrs) p.Add(plotter.NewGlyphBoxes()) return p }
// AddXErrorBars adds XErrorBars to a plot. // The variadic arguments must be // of type plotter.XYer, and plotter.XErrorer. // Each errorer is added to the plot the color from // the Colors function corresponding to its position // in the argument list. func AddXErrorBars(plt *plot.Plot, es ...interface { plotter.XYer plotter.XErrorer }) { for i, e := range es { bars := plotter.NewXErrorBars(e) bars.Color = Color(i) plt.Add(bars) } }
// AddXErrorBars adds XErrorBars to a plot. // The variadic arguments must be // of type plotter.XYer, and plotter.XErrorer. // Each errorer is added to the plot the color from // the Colors function corresponding to its position // in the argument list. // // If an error occurs then none of the plotters are added // to the plot, and the error is returned. func AddXErrorBars(plt *plot.Plot, es ...interface { plotter.XYer plotter.XErrorer }) error { var ps []plot.Plotter for i, e := range es { bars, err := plotter.NewXErrorBars(e) if err != nil { return err } bars.Color = Color(i) ps = append(ps, bars) } plt.Add(ps...) return nil }
// AddErrorBars adds XErrorBars and YErrorBars // to a plot. The variadic arguments must be // of type plotter.XYer, and must be either a // plotter.XErrorer, plotter.YErrorer, or both. // Each errorer is added to the plot the color from // the Colors function corresponding to its position // in the argument list. // // If an error occurs then none of the plotters are added // to the plot, and the error is returned. func AddErrorBars(plt *plot.Plot, vs ...interface{}) error { var ps []plot.Plotter for i, v := range vs { added := false if xerr, ok := v.(interface { plotter.XYer plotter.XErrorer }); ok { e, err := plotter.NewXErrorBars(xerr) if err != nil { return err } e.Color = Color(i) ps = append(ps, e) added = true } if yerr, ok := v.(interface { plotter.XYer plotter.YErrorer }); ok { e, err := plotter.NewYErrorBars(yerr) if err != nil { return err } e.Color = Color(i) ps = append(ps, e) added = true } if added { continue } panic(fmt.Sprintf("AddErrorBars expects plotter.XErrorer or plotter.YErrorer, got %T", v)) } plt.Add(ps...) return nil }
func VisualizeSignificantEvents(events SignificantEvents, filename string, options SignificantEventsOptions) { firstTime := events.FirstTime() tr := func(t time.Time) float64 { return t.Sub(firstTime).Seconds() } minX := options.MinX maxX := 0.0 maxY := 0.0 minY := math.MaxFloat64 histograms := map[string]plot.Plotter{} scatters := map[string][]plot.Plotter{} verticalLines := []plot.Plotter{} colorCounter := 0 for _, name := range events.OrderedNames() { xys := plotter.XYs{} xErrs := plotter.XErrors{} for _, event := range events[name] { if event.V > 0 { xys = append(xys, struct{ X, Y float64 }{tr(event.T), event.V}) xErrs = append(xErrs, struct{ Low, High float64 }{-event.V / 2, event.V / 2}) if tr(event.T) > maxX { maxX = tr(event.T) } if event.V > maxY { maxY = event.V } if event.V < minY { minY = event.V } } } if len(xys) == 0 { say.Println(0, "No data for %s", name) continue } if options.MarkedEvents != nil { ls, ok := options.MarkedEvents[name] if ok { for _, event := range events[name] { l := viz.NewVerticalLine(tr(event.T)) l.LineStyle = ls verticalLines = append(verticalLines, l) } } } s, err := plotter.NewScatter(xys) say.ExitIfError("Couldn't create scatter plot", err) s.GlyphStyle = plot.GlyphStyle{ Color: viz.OrderedColor(colorCounter), Radius: 2, Shape: plot.CircleGlyph{}, } xErrsPlot, err := plotter.NewXErrorBars(struct { plotter.XYer plotter.XErrorer }{xys, xErrs}) say.ExitIfError("Couldn't create x errors plot", err) xErrsPlot.LineStyle = viz.LineStyle(viz.OrderedColor(colorCounter), 1) scatters[name] = []plot.Plotter{s, xErrsPlot} durations := events[name].Data() h := viz.NewHistogram(durations, 20, durations.Min(), durations.Max()) h.LineStyle = viz.LineStyle(viz.OrderedColor(colorCounter), 1) histograms[name] = h colorCounter++ } if options.MaxX != 0 { maxX = options.MaxX } maxY = math.Pow(10, math.Ceil(math.Log10(maxY))) minY = math.Pow(10, math.Floor(math.Log10(minY))) b := &viz.Board{} n := len(histograms) + 1 padding := 0.1 / float64(n-1) height := (1.0 - padding*float64(n-1)) / float64(n) histWidth := 0.3 scatterWidth := 0.7 y := 1 - height - padding - height allScatterPlot, _ := plot.New() allScatterPlot.Title.Text = "All Events" allScatterPlot.X.Label.Text = "Time (s)" allScatterPlot.Y.Label.Text = "Duration (s)" allScatterPlot.Y.Scale = plot.LogScale allScatterPlot.Y.Tick.Marker = plot.LogTicks for _, name := range events.OrderedNames() { histogram, ok := histograms[name] if !ok { continue } scatter := scatters[name] allScatterPlot.Add(scatter[0]) allScatterPlot.Add(scatter[1]) histogramPlot, _ := plot.New() histogramPlot.Title.Text = name histogramPlot.X.Label.Text = "Duration (s)" histogramPlot.Y.Label.Text = "N" histogramPlot.Add(histogram) scatterPlot, _ := plot.New() scatterPlot.Title.Text = name scatterPlot.X.Label.Text = "Time (s)" scatterPlot.Y.Label.Text = "Duration (s)" scatterPlot.Y.Scale = plot.LogScale scatterPlot.Y.Tick.Marker = plot.LogTicks scatterPlot.Add(scatter...) scatterPlot.Add(verticalLines...) scatterPlot.X.Min = minX scatterPlot.X.Max = maxX scatterPlot.Y.Min = 1e-5 scatterPlot.Y.Max = maxY b.AddSubPlot(histogramPlot, viz.Rect{0, y, histWidth, height}) b.AddSubPlot(scatterPlot, viz.Rect{histWidth, y, scatterWidth, height}) y -= height + padding } allScatterPlot.Add(verticalLines...) allScatterPlot.X.Min = minX allScatterPlot.X.Max = maxX allScatterPlot.Y.Min = 1e-5 allScatterPlot.Y.Max = maxY fmt.Println("all", minX, maxX) b.AddSubPlot(allScatterPlot, viz.Rect{histWidth, 1 - height, scatterWidth, height}) b.Save(16.0, 5*float64(n), filename) }
func VisualizeSignificantEvents(events SignificantEvents, filename string, options SignificantEventsOptions) { firstTime := events.FirstTime() tr := func(t time.Time) float64 { return t.Sub(firstTime).Seconds() } minX := 0.0 if options.MinX != 0 { minX = options.MinX } if !options.MinT.IsZero() { minX = tr(options.MinT) } maxX := 0.0 maxY := 0.0 minY := math.MaxFloat64 scatters := map[string][]plot.Plotter{} verticalLines := []plot.Plotter{} lineOverlays := []plot.Plotter{} colorCounter := 0 for _, name := range events.OrderedNames() { xys := plotter.XYs{} xErrs := plotter.XErrors{} for _, event := range events[name] { if event.V > 0 { xys = append(xys, struct{ X, Y float64 }{tr(event.T), event.V}) xErrs = append(xErrs, struct{ Low, High float64 }{-event.V / 2, event.V / 2}) if tr(event.T) > maxX { maxX = tr(event.T) } if event.V > maxY { maxY = event.V } if event.V < minY { minY = event.V } } } if len(xys) == 0 { say.Println(0, "No data for %s", name) continue } if options.MarkedEvents != nil { ls, ok := options.MarkedEvents[name] if ok { for _, event := range events[name] { l := viz.NewVerticalLine(tr(event.T)) l.LineStyle = ls verticalLines = append(verticalLines, l) } } } s, err := plotter.NewScatter(xys) say.ExitIfError("Couldn't create scatter plot", err) s.GlyphStyle = plot.GlyphStyle{ Color: viz.OrderedColor(colorCounter), Radius: 2, Shape: plot.CircleGlyph{}, } xErrsPlot, err := plotter.NewXErrorBars(struct { plotter.XYer plotter.XErrorer }{xys, xErrs}) say.ExitIfError("Couldn't create x errors plot", err) xErrsPlot.LineStyle = viz.LineStyle(viz.OrderedColor(colorCounter), 1) scatters[name] = []plot.Plotter{s, xErrsPlot} colorCounter++ } for _, marker := range options.VerticalMarkers { l := viz.NewVerticalLine(tr(marker.T)) l.LineStyle = marker.LineStyle verticalLines = append(verticalLines, l) } for _, lineOverlay := range options.LineOverlays { xys := plotter.XYs{} for _, event := range lineOverlay.Events { if event.V > 0 { xys = append(xys, struct{ X, Y float64 }{tr(event.T), event.V}) } } l, s, err := plotter.NewLinePoints(xys) say.ExitIfError("Couldn't create scatter plot", err) l.LineStyle = lineOverlay.LineStyle s.GlyphStyle = plot.GlyphStyle{ Color: lineOverlay.LineStyle.Color, Radius: lineOverlay.LineStyle.Width, Shape: plot.CrossGlyph{}, } lineOverlays = append(lineOverlays, l, s) } if options.MaxX != 0 { maxX = options.MaxX } if !options.MaxT.IsZero() { maxX = tr(options.MaxT) } maxY = math.Pow(10, math.Ceil(math.Log10(maxY))) if options.MaxY != 0 { maxY = options.MaxY } minY = math.Pow(10, math.Floor(math.Log10(minY))) n := len(scatters) + 1 b := viz.NewUniformBoard(1, n, 0.01) allScatterPlot, _ := plot.New() allScatterPlot.Title.Text = "All Events" allScatterPlot.X.Label.Text = "Time (s)" allScatterPlot.Y.Label.Text = "Duration (s)" allScatterPlot.Y.Scale = plot.LogScale allScatterPlot.Y.Tick.Marker = plot.LogTicks for i, name := range events.OrderedNames() { scatter, ok := scatters[name] if !ok { continue } allScatterPlot.Add(scatter[0]) allScatterPlot.Add(scatter[1]) scatterPlot, _ := plot.New() scatterPlot.Title.Text = name scatterPlot.X.Label.Text = "Time (s)" scatterPlot.Y.Label.Text = "Duration (s)" scatterPlot.Y.Scale = plot.LogScale scatterPlot.Y.Tick.Marker = plot.LogTicks scatterPlot.Add(scatter...) scatterPlot.Add(verticalLines...) scatterPlot.Add(lineOverlays...) scatterPlot.Add(options.OverlayPlots...) scatterPlot.X.Min = minX scatterPlot.X.Max = maxX scatterPlot.Y.Min = 1e-5 scatterPlot.Y.Max = maxY b.AddSubPlotAt(scatterPlot, 0, n-2-i) } allScatterPlot.Add(verticalLines...) allScatterPlot.Add(lineOverlays...) allScatterPlot.Add(options.OverlayPlots...) allScatterPlot.X.Min = minX allScatterPlot.X.Max = maxX allScatterPlot.Y.Min = 1e-5 allScatterPlot.Y.Max = maxY fmt.Println("all", minX, maxX) b.AddSubPlotAt(allScatterPlot, 0, n-1) width := 12.0 if options.WidthStretch > 0 { width = width * options.WidthStretch } b.Save(width, 5*float64(n), filename) }