// Draw the plotinum logo. func Example_logo() *plot.Plot { p, err := plot.New() if err != nil { panic(err) } plotter.DefaultLineStyle.Width = vg.Points(1) plotter.DefaultGlyphStyle.Radius = vg.Points(3) p.Y.Tick.Marker = plot.ConstantTicks([]plot.Tick{ {0, "0"}, {0.25, ""}, {0.5, "0.5"}, {0.75, ""}, {1, "1"}, }) p.X.Tick.Marker = plot.ConstantTicks([]plot.Tick{ {0, "0"}, {0.25, ""}, {0.5, "0.5"}, {0.75, ""}, {1, "1"}, }) pts := plotter.XYs{{0, 0}, {0, 1}, {0.5, 1}, {0.5, 0.6}, {0, 0.6}} line := must(plotter.NewLine(pts)).(*plotter.Line) scatter := must(plotter.NewScatter(pts)).(*plotter.Scatter) p.Add(line, scatter) pts = plotter.XYs{{1, 0}, {0.75, 0}, {0.75, 0.75}} line = must(plotter.NewLine(pts)).(*plotter.Line) scatter = must(plotter.NewScatter(pts)).(*plotter.Scatter) p.Add(line, scatter) pts = plotter.XYs{{0.5, 0.5}, {1, 0.5}} line = must(plotter.NewLine(pts)).(*plotter.Line) scatter = must(plotter.NewScatter(pts)).(*plotter.Scatter) p.Add(line, scatter) return p }
// AddScatters adds Scatter plotters to a plot. // The variadic arguments must be either strings // or plotter.XYers. Each plotter.XYer is added to // the plot using the next color, and glyph shape // via the Color and Shape functions. If a // plotter.XYer is immediately preceeded by // a string then a legend entry is added to the plot // using the string as the name. // // If an error occurs then none of the plotters are added // to the plot, and the error is returned. func AddScatters(plt *plot.Plot, vs ...interface{}) error { var ps []plot.Plotter names := make(map[*plotter.Scatter]string) name := "" var i int for _, v := range vs { switch t := v.(type) { case string: name = t case plotter.XYer: s, err := plotter.NewScatter(t) if err != nil { return err } s.Color = Color(i) s.Shape = Shape(i) i++ ps = append(ps, s) if name != "" { names[s] = name name = "" } default: panic(fmt.Sprintf("AddScatters handles strings and plotter.XYers, got %T", t)) } } plt.Add(ps...) for p, n := range names { plt.Legend.Add(n, p) } return nil }
func plotData(name string, us, ys, ts, fs []float64) { p, err := plot.New() if err != nil { fmt.Printf("Cannot create new plot: %s\n", err) return } p.Title.Text = "Least-square fit of convex function" p.X.Min = -0.1 p.X.Max = 2.3 p.Y.Min = -1.1 p.Y.Max = 7.2 p.Add(plotter.NewGrid()) pts := plotter.NewScatter(dataset(us, ys)) pts.GlyphStyle.Color = color.RGBA{R: 255, A: 255} fit := plotter.NewLine(dataset(ts, fs)) fit.LineStyle.Width = vg.Points(1) fit.LineStyle.Color = color.RGBA{B: 255, A: 255} p.Add(pts) p.Add(fit) if err := p.Save(4, 4, name); err != nil { fmt.Printf("Save to '%s' failed: %s\n", name, err) } }
// 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 }
func linesPlot() *plot.Plot { // Get some random points rand.Seed(int64(0)) n := 10 scatterData := randomPoints(n) lineData := randomPoints(n) linePointsData := randomPoints(n) // Create a new plot, set its title and // axis labels. p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Points Example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" // Draw a grid behind the data p.Add(plotter.NewGrid()) // Make a scatter plotter and set its style. s, err := plotter.NewScatter(scatterData) if err != nil { panic(err) } s.GlyphStyle.Color = color.RGBA{R: 255, B: 128, A: 255} // Make a line plotter and set its style. l, err := plotter.NewLine(lineData) if err != nil { panic(err) } l.LineStyle.Width = vg.Points(1) l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)} l.LineStyle.Color = color.RGBA{B: 255, A: 255} // Make a line plotter with points and set its style. lpLine, lpPoints, err := plotter.NewLinePoints(linePointsData) if err != nil { panic(err) } lpLine.Color = color.RGBA{G: 255, A: 255} lpPoints.Shape = plot.PyramidGlyph{} lpPoints.Color = color.RGBA{R: 255, A: 255} // Add the plotters to the plot, with a legend // entry for each p.Add(s, l, lpLine, lpPoints) p.Legend.Add("scatter", s) p.Legend.Add("line", l) p.Legend.Add("line points", lpLine, lpPoints) return p }
// RamaPlotParts produces plots, in png format for the ramachandran data (phi and psi dihedrals) // contained in data. Data points in tag (maximun 4) are highlighted in the plot. // the extension must be included in plotname. Returns an error or nil. In RamaPlotParts // The data is divided in several slices, where each is represented differently in the plot func RamaPlotParts(data [][][]float64, tag [][]int, title, plotname string) error { var err error if data == nil { return Error{ErrNilData, "", "RamaPlot", "", true} } // Create a new plot, set its title and // axis labels. p, err2 := basicRamaPlot(title) if err2 != nil { return Error{err2.Error(), "", "RamaPlotParts", "", true} } var tagged int for key, val := range data { temp := make(plotter.XYs, 1) //len(val)) // fmt.Println(key, len(val)) for k, v := range val { temp[0].X = v[0] temp[0].Y = v[1] // Make a scatter plotter and set its style. s, err := plotter.NewScatter(temp) //(pts) if err != nil { return Error{err.Error(), "", "RamaPlotParts", "", true} } if tag != nil { if len(tag) < len(data) { return Error{ErrInconsistentData, "", "RamaPlotParts", "If a non-nil tag slice is provided it must contain an element (which can be nil) for each element in the dihedral slice", true} } if tag[key] != nil && isInInt(tag[key], k) { s.GlyphStyle.Shape, err = getShape(tagged) tagged++ } } //set the colors r, g, b := colors(key, len(data)) fmt.Println("DATA POINT", key, "color", r, g, b) s.GlyphStyle.Color = color.RGBA{R: r, B: b, G: g, A: 255} //The tagging procedure is a bit complex. p.Add(s) } } filename := fmt.Sprintf("%s.png", plotname) //here I intentionally shadow err. if err := p.Save(5, 5, filename); err != nil { return Error{err2.Error(), "", "RamaPlotParts", "", true} } return err }
// createScatter creates a scatter graph from provided x,y data and title func createScatter(xdat, ydat []float64, title string) { p, err := plot.New() if err != nil { panic(err) } p.Add(plotter.NewGrid()) p.Title.Text = title scatdata := xyer{xdat, ydat} s := plotter.NewScatter(scatdata) s.GlyphStyle.Radius = 2 s.GlyphStyle.Shape = &plot.BoxGlyph{} s.GlyphStyle.Color = color.RGBA{G: 100, A: 255} p.Add(s) if err := p.Save(5, 5, "out/"+title+".png"); err != nil { panic(err) } }
// Example_points draws some scatter points, a line, // and a line with points. func Example_points() *plot.Plot { rand.Seed(int64(0)) n := 15 scatterData := randomPoints(n) lineData := randomPoints(n) linePointsData := randomPoints(n) p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Points Example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" p.Add(plotter.NewGrid()) s := must(plotter.NewScatter(scatterData)).(*plotter.Scatter) s.GlyphStyle.Color = color.RGBA{R: 255, B: 128, A: 255} s.GlyphStyle.Radius = vg.Points(3) l := must(plotter.NewLine(lineData)).(*plotter.Line) l.LineStyle.Width = vg.Points(1) l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)} l.LineStyle.Color = color.RGBA{B: 255, A: 255} lpLine, lpPoints, err := plotter.NewLinePoints(linePointsData) if err != nil { panic(err) } lpLine.Color = color.RGBA{G: 255, A: 255} lpPoints.Shape = plot.CircleGlyph{} lpPoints.Color = color.RGBA{R: 255, A: 255} p.Add(s, l, lpLine, lpPoints) p.Legend.Add("scatter", s) p.Legend.Add("line", l) p.Legend.Add("line points", lpLine, lpPoints) return p }
/* if (key-critical)*norm>255{ r=uint8(norm*(key-critical)) g=90 b=255-r } } fmt.Println(r,g,b, norm, steps) */ return r, g, b } // Produce plots, in png format for the ramachandran data (psi and phi dihedrals) // contained in data. Data points in tag (maximun 4) are highlighted in the plot. // the extension must be included in plotname. Returns an error or nil*/ func RamaPlot(data [][]float64, tag []int, title, plotname string) error { var err error if data == nil { return Error{ErrNilData, "", "RamaPlot", "", true} } // Create a new plot, set its title and // axis labels. p, err := basicRamaPlot(title) if err != nil { return Error{err.Error(), "", "RamaPlot", "", true} } temp := make(plotter.XYs, 1) var tagged int //How many residues have been tagged? for key, val := range data { temp[0].X = val[0] temp[0].Y = val[1] // Make a scatter plotter and set its style. s, err := plotter.NewScatter(temp) //(pts) if err != nil { return Error{err.Error(), "", "RamaPlot", "", true} } r, g, b := colors(key, len(data)) if tag != nil && isInInt(tag, key) { s.GlyphStyle.Shape, err = getShape(tagged) tagged++ } s.GlyphStyle.Color = color.RGBA{R: r, B: b, G: g, A: 255} // fmt.Println(r,b,g, key, norm, len(data)) ////////////////////////// // Add the plotter p.Add(s) } // Save the plot to a PNG file. filename := fmt.Sprintf("%s.png", plotname) //here I intentionally shadow err. if err := p.Save(4, 4, filename); err != nil { return Error{err.Error(), "", "RamaPlot", "", true} } return err }
// AddScatters adds Scatter plotters to a plot. // The variadic arguments must be either strings // or plotter.XYers. Each plotter.XYer is added to // the plot using the next color, and glyph shape // via the Color and Shape functions. If a // plotter.XYer is immediately preceeded by // a string then a legend entry is added to the plot // using the string as the name. func AddScatters(plt *plot.Plot, vs ...interface{}) { name := "" var i int for _, v := range vs { switch t := v.(type) { case string: name = t case plotter.XYer: s := plotter.NewScatter(t) s.Color = Color(i) s.Shape = Shape(i) i++ plt.Add(s) if name != "" { plt.Legend.Add(name, s) name = "" } default: panic(fmt.Sprintf("AddScatters handles strings and plotter.XYers, got %T", t)) } } }
// Function called by rest of code to plot graphs func Plot(fname string, title string, labels []string, xdata []float64, ydata ...[]float64) { if len(fname) == 0 { fname = "output" } fname = fmt.Sprintf("out/%v h=%v m=%v M=%v l=%v γ=%v.png", fname, h, m, M, l, gamma) p, err := plot.New() if err != nil { panic(err) } fmt.Print(">> Plotting \"" + title + "\" to \"" + fname + "\"") // Add grid p.Add(plotter.NewGrid()) p.Title.Text = title p.Title.Padding = 10.0 p.X.Label.Text = labels[0] p.Y.Label.Text = labels[1] p.Legend.Top = true p.Legend.Left = true p.Legend.YOffs = -5.0 p.Legend.YOffs = -15.0 p.Legend.Padding = 10.0 p.Legend.ThumbnailWidth = 30.0 var s *plotter.Scatter // This is to allow for plotting of vertical lines for stability graphs stabtest := false last := len(ydata) if len(labels) == last { stabtest = true last -= 2 } // Loop through data and for i := 0; i < last; i++ { s = plotter.NewScatter(&_points{xdata, ydata[i]}) s.GlyphStyle.Color = cols[i] s.GlyphStyle.Radius = 1 s.GlyphStyle.Shape = plot.CircleGlyph{} p.Add(s) if len(ydata) > 1 { p.Legend.Add(labels[i+2], s) } } if stabtest { s = plotter.NewScatter(&_points{ydata[1], ydata[2]}) s.GlyphStyle.Color = cols[0] s.GlyphStyle.Radius = 1 s.GlyphStyle.Shape = plot.CircleGlyph{} p.Add(s) } // Save the plot to a PNG file. if err := p.Save(7, 7, fname); err != nil { panic(err) } fmt.Print(" ... Done\n") }
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) }