// makeRegPlots makes the second plot including the raw input data and the // trained function. func makeRegPlots(xys1, xys2 plotter.XYs) error { // Create a plot value. p, err := plot.New() if err != nil { return errors.Wrap(err, "Could not create plot object") } // Label the plot. p.Title.Text = "Daily Counts of Go Repos Created" p.X.Label.Text = "Days from Jan. 1, 2013" p.Y.Label.Text = "Count" // Add both sets of points, predicted and actual, to the plot. if err := plotutil.AddLinePoints(p, "Actual", xys1, "Predicted", xys2); err != nil { return errors.Wrap(err, "Could not add lines to plot") } // Save the plot. if err := p.Save(7*vg.Inch, 4*vg.Inch, "regression.png"); err != nil { return errors.Wrap(err, "Could not output plot") } return nil }
// 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 = draw.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 }
// 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 }
// Example_quartPlots draws vertical quartile plots. func Example_quartPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(plotter.Values, n) normal := make(plotter.Values, n) expon := make(plotter.Values, n) for i := 0; i < n; i++ { uniform[i] = rand.Float64() normal[i] = rand.NormFloat64() expon[i] = rand.ExpFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Quartile Plot" p.Y.Label.Text = "plotter.Values" p.Add(must(plotter.NewQuartPlot(0, uniform)).(*plotter.QuartPlot), must(plotter.NewQuartPlot(1, normal)).(*plotter.QuartPlot), must(plotter.NewQuartPlot(2, expon)).(*plotter.QuartPlot)) // Set the X axis of the plot to nominal with // the given names for x=0, x=1 and x=2. p.NominalX("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") return p }
func Example_groupedHorizontalQuartPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(plotter.Values, n) normal := make(plotter.Values, n) expon := make(plotter.Values, n) for i := 0; i < n; i++ { uniform[i] = rand.Float64() normal[i] = rand.NormFloat64() expon[i] = rand.ExpFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Box Plot" p.Y.Label.Text = "plotter.Values" w := vg.Points(10) for x := 0.0; x < 3.0; x++ { b0 := must(plotter.MakeHorizQuartPlot(x, uniform)).(plotter.HorizQuartPlot) b0.Offset = -w b1 := must(plotter.MakeHorizQuartPlot(x, normal)).(plotter.HorizQuartPlot) b2 := must(plotter.MakeHorizQuartPlot(x, expon)).(plotter.HorizQuartPlot) b2.Offset = w p.Add(b0, b1, b2) } p.Add(plotter.NewGlyphBoxes()) p.NominalY("Group 0", "Group 1", "Group 2") return p }
// 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 }
// Example_groupedBoxPlots draws vertical boxplots. func Example_groupedBoxPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(plotter.Values, n) normal := make(plotter.Values, n) expon := make(plotter.Values, n) for i := 0; i < n; i++ { uniform[i] = rand.Float64() normal[i] = rand.NormFloat64() expon[i] = rand.ExpFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Box Plot" p.Y.Label.Text = "plotter.Values" w := vg.Points(20) for x := 0.0; x < 3.0; x++ { b0 := must(plotter.NewBoxPlot(w, x, uniform)).(*plotter.BoxPlot) b0.Offset = -w - vg.Points(3) b1 := must(plotter.NewBoxPlot(w, x, normal)).(*plotter.BoxPlot) b2 := must(plotter.NewBoxPlot(w, x, expon)).(*plotter.BoxPlot) b2.Offset = w + vg.Points(3) p.Add(b0, b1, b2) } // Set the X axis of the plot to nominal with // the given names for x=0, x=1 and x=2. p.NominalX("Group 0", "Group 1", "Group 2") return p }
// CreateImage creates graph of nyanpass func (n *Nyanpass) CreateImage(fileName string) error { if n.Counts == nil { return errors.New("Count is not defined.") } p, err := plot.New() if err != nil { return err } bar, err := plotter.NewBarChart(n.Counts, vg.Points(30)) if err != nil { return err } bar.LineStyle.Width = vg.Length(0) bar.Color = plotutil.Color(2) p.Add(bar) p.Title.Text = "Nyanpass Graph" p.X.Label.Text = "Days" p.Y.Label.Text = "Nyanpass count" p.NominalX(n.labels...) p.Y.Tick.Marker = RelabelTicks{} if err := p.Save(6*vg.Inch, 6*vg.Inch, fileName); err != nil { return err } n.imagePath = fileName return nil }
// 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 }
func plotSingle(df *DataFrame, name string) { p, err := plot.New() if err != nil { log.Fatal(err) } p.X.Label.Text = "X" p.Y.Label.Text = "Y" err = plotutil.AddLinePoints(p, name, df.PlotPoints()) if err != nil { log.Fatal(err) } c := vgsvg.New(16*vg.Inch, 9*vg.Inch) can := draw.New(c) p.Draw(can) p.Save(16*vg.Inch/2, 9*vg.Inch/2, fmt.Sprintf("graphs/%s.png", name)) f, err := os.Create(fmt.Sprintf("graphs/%s.svg", name)) if err != nil { log.Fatal(err) } c.WriteTo(f) }
func ExampleHeatMap() { m := unitGrid{mat64.NewDense(3, 4, []float64{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, })} h := NewHeatMap(m, palette.Heat(12, 1)) p, err := plot.New() if err != nil { log.Panic(err) } p.Title.Text = "Heat map" p.Add(h) p.X.Padding = 0 p.Y.Padding = 0 p.X.Max = 3.5 p.Y.Max = 2.5 err = p.Save(100, 100, "testdata/heatMap.png") if err != nil { log.Panic(err) } }
func PlotLine(pts, pts2 plotter.XYs, w []float64, b float64, path string) { p, err := plot.New() if err != nil { panic(err) } p.X.Label.Text = "x" p.Y.Label.Text = "y" x := []float64{} y := []float64{} for i := range make([]float64, 150) { bx := float64(i)*0.1 - 6.0 x = append(x, bx) y = append(y, -b/w[1]-w[0]/w[1]*bx) } pts_res := makeLine(x, y) err = plotutil.AddScatters(p, "Class 0", pts, "Class 1", pts2, ) if err != nil { panic(err) } err = plotutil.AddLines(p, "Line", pts_res, ) if err != nil { panic(err) } if err := p.Save(10*vg.Inch, 10*vg.Inch, path); err != nil { panic(err) } }
func plotDensity(results []densityResult) { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Density" p.X.Label.Text = "Seconds" p.Y.Label.Text = "Number of Pods" err = plotutil.AddLinePoints(p, "Created", getCreatedPoints(results), "Running", getRunningPoints(results), "Pending", getPendingPoints(results), "Waiting", getWaitingPoints(results)) if err != nil { panic(err) } // Save the plot to a SVG file. if err := p.Save(10*vg.Inch, 10*vg.Inch, "density-all.svg"); err != nil { panic(err) } fmt.Println("successfully plotted density graph to density-all.svg") }
func plotDensity(rs1, rs2 []result, ftype string) { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Scheduler Benchmark" p.X.Label.Text = "Seconds" var filename string switch ftype { case "total": p.Y.Label.Text = "Number of Pods" err = plotutil.AddLinePoints(p, "Total-new", getTotal(rs1), "Total-old", getTotal(rs2)) filename = "schedule-total.png" case "rate": p.Y.Label.Text = "Rate of Scheduling" err = plotutil.AddLinePoints(p, "Rate-new", getRate(rs1), "Rate-old", getRate(rs2)) filename = "schedule-rate.png" } if err != nil { panic(err) } if err := p.Save(10*vg.Inch, 10*vg.Inch, filename); err != nil { panic(err) } fmt.Println("successfully plotted density graph to", filename) }
// Plot plots only 2-dimensional cluster and points func (em EM) Plot(fileid int, directory string) { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "EM-Algorithm Plot" p.X.Label.Text = "X" p.Y.Label.Text = "Y" bs, err := plotter.NewBubbles(em.clusterTriples(), vg.Points(30), vg.Points(80)) if err != nil { panic(err) } bs.Color = color.RGBA{R: 255, B: 255, A: 255} p.Add(bs) ss, err := plotter.NewScatter(em.dataTriples()) if err != nil { panic(err) } ss.Color = color.Black p.Add(ss) filename := directory + fmt.Sprintf("%03d", fileid) + ".png" if err := p.Save(10*vg.Inch, 10*vg.Inch, filename); err != nil { panic(err) } }
// 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) }
// makePlots creates and saves the first of our plots showing the raw input data. func makePlots(xys plotter.XYs) error { // Create a new plot. p, err := plot.New() if err != nil { return errors.Wrap(err, "Could not create plot object") } // Label the new plot. p.Title.Text = "Daily Counts of Go Repos Created" p.X.Label.Text = "Days from Jan. 1, 2013" p.Y.Label.Text = "Count" // Add the prepared points to the plot. if err = plotutil.AddLinePoints(p, "Counts", xys); err != nil { return errors.Wrap(err, "Could not add lines to plot") } // Save the plot to a PNG file. if err := p.Save(7*vg.Inch, 4*vg.Inch, "countseries.png"); err != nil { return errors.Wrap(err, "Could not output plot") } return nil }
func PlotGraph(title string, timestamps []int64, w io.Writer) error { p, err := plot.New() if err != nil { return err } p.Title.Text = title p.X.Label.Text = "Time" p.Y.Label.Text = "Number of stars" p.Y.Min = 0 points := make(plotter.XYs, len(timestamps)) for i, timestamp := range timestamps { points[i].X = float64(timestamp) points[i].Y = float64(i + 1) } plotutil.AddLinePoints(p, "Stars", points) c := vgimg.New(4*vg.Inch, 4*vg.Inch) cpng := vgimg.PngCanvas{c} p.Draw(draw.New(cpng)) if _, err := cpng.WriteTo(w); err != nil { return err } return nil }
func GeneratePlot(x, y []float64, title, xLabel, yLabel, legendLabel, fileName string) { outPlotPoints := make(plotter.XYs, len(x)) for i, _ := range x { outPlotPoints[i].X = x[i] outPlotPoints[i].Y = y[i] } outPlot, err := plot.New() if err != nil { panic(err) } outPlot.Title.Text = title outPlot.X.Label.Text = xLabel outPlot.Y.Label.Text = yLabel err = plotutil.AddLines(outPlot, legendLabel, outPlotPoints) if err != nil { panic(err) } if err := outPlot.Save(6*vg.Inch, 6*vg.Inch, fileName); err != nil { panic(err) } }
func GeneratePlots(x, y [][]float64, title, xLabel, yLabel, fileName string, legendLabel []string) { outPlotPoints := make([]plotter.XYs, len(x)) outPlots := make([]*plot.Plot, len(x)) for i, _ := range outPlotPoints { outPlot, err := plot.New() outPlots[i] = outPlot outPlots[i].Title.Text = title outPlots[i].X.Label.Text = xLabel outPlots[i].Y.Label.Text = yLabel outPlotPoints[i] = make(plotter.XYs, len(x[0])) for j, _ := range x[0] { outPlotPoints[i][j].X = x[i][j] outPlotPoints[i][j].Y = y[i][j] } err = plotutil.AddLines(outPlots[i], legendLabel[i], outPlotPoints[i]) if err != nil { panic(err) } if err = outPlot.Save(6*vg.Inch, 6*vg.Inch, (fileName+strconv.FormatInt(int64(i), 16))+".png"); err != nil { panic(err) } } }
// 784 Bits func Paint(image []float64, imageId int) { outPlotPoints := make(plotter.XYs, len(image)) outPlot, err := plot.New() if err != nil { panic(err) } x := 0 y := 0 for i, bit := range image { outPlotPoints[i].X = float64(x) if bit > 0.4 { outPlotPoints[i].Y = float64(y) } else { outPlotPoints[i].Y = 0 } if i%int(math.Sqrt(float64(len(image)))) == 0 { x = 0 y++ } else { x++ } } outPlot.Add(plotter.NewGrid()) s, _ := plotter.NewScatter(outPlotPoints) outPlot.Add(s) if err = outPlot.Save(6*vg.Inch, 6*vg.Inch, "plots/centroid-drawing-"+strconv.FormatInt(int64(imageId), 16)+".png"); err != nil { panic(err) } }
func TestHeatMapWithContour(t *testing.T) { if !*visualDebug { return } m := unitGrid{mat64.NewDense(3, 4, []float64{ 2, 1, 4, 3, 6, 7, 2, 5, 9, 10, 11, 12, })} h := NewHeatMap(m, palette.Heat(12, 1)) levels := []float64{1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5} c := NewContour(m, levels, palette.Rainbow(10, palette.Blue, palette.Red, 1, 1, 1)) c.LineStyles[0].Width *= 5 plt, _ := plot.New() plt.Add(h) plt.Add(c) plt.Add(NewGlyphBoxes()) plt.X.Padding = 0 plt.Y.Padding = 0 plt.X.Max = 3.5 plt.Y.Max = 2.5 plt.Save(7, 7, "heat.svg") }
func TestComplexContours(t *testing.T) { if !*visualDebug { return } for _, n := range []float64{0, 1, 2, 4, 8, 16, 32} { data := make([]float64, 6400) for i := range data { r := float64(i/80) - 40 c := float64(i%80) - 40 data[i] = rand.NormFloat64()*n + math.Hypot(r, c) } m := unitGrid{mat64.NewDense(80, 80, data)} levels := []float64{-1, 3, 7, 9, 13, 15, 19, 23, 27, 31} c := NewContour(m, levels, palette.Rainbow(10, palette.Blue, palette.Red, 1, 1, 1)) plt, _ := plot.New() plt.Add(c) plt.X.Padding = 0 plt.Y.Padding = 0 plt.X.Max = 79.5 plt.Y.Max = 79.5 plt.Save(7, 7, fmt.Sprintf("complex_contour-%v.svg", n)) } }
// Save benched results. func save(filename string, names []string, ns [][]int64, X []int64) { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "ns/sort" p.X.Label.Text = "N" p.Y.Label.Text = "ns" p.X.Scale = plot.LogScale{} p.Y.Scale = plot.LogScale{} data := make([]interface{}, len(names)*2) for i, name := range names { data[i*2] = name data[i*2+1] = points(X, ns[i]) } if err := plotutil.AddLinePoints(p, data...); err != nil { panic(err) } if err := p.Save(10*vg.Inch, 8*vg.Inch, filename); err != nil { panic(err) } }
func (s *Plots) DrawTps() { p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Response Time" p.X.Label.Text = "Time (seconds)" p.Y.Label.Text = "Response time (ms)" p.Add(plotter.NewGrid()) // Make a line plotter and set its style. l, err := plotter.NewLine(s.intervalsTps) if err != nil { panic(err) } l.LineStyle.Color = color.RGBA{B: 255, A: 255} p.Add(l) p.Legend.Add("line", l) // Save the plot to a PNG file. if err := p.Save(128*vg.Inch, 32*vg.Inch, "tps.svg"); err != nil { panic(err) } }
func drawEmbeddedFeaturesFilteringResults(results []testEmbeddedFeaturesFilteringResult, refF1 float64, fileName string) { fmt.Println("plotting ...") p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Adaboost: Embedded features filtering test" p.X.Label.Text = "Selected features count" p.Y.Label.Text = "F1" var resultPoints plotter.XYs for _, nextResult := range results { resultPoints = append(resultPoints, struct{ X, Y float64 }{float64(nextResult.FeaturesCount), nextResult.F1}) } refPoints := make(plotter.XYs, 2) refPoints[0] = struct{ X, Y float64 }{float64(results[0].FeaturesCount), refF1} refPoints[1] = struct{ X, Y float64 }{float64(results[len(results)-1].FeaturesCount), refF1} err = plotutil.AddLinePoints(p, "F1 with selected features", resultPoints, "reference F1 with all features", refPoints) if err != nil { panic(err) } if err := p.Save(8*vg.Inch, 8*vg.Inch, fileName); err != nil { panic(err) } }
func TestIssue179(t *testing.T) { scatter, err := plotter.NewScatter(plotter.XYs{{1, 1}, {0, 1}, {0, 0}}) if err != nil { log.Fatal(err) } p, err := plot.New() if err != nil { log.Fatal(err) } p.Add(scatter) p.HideAxes() c := vgimg.JpegCanvas{Canvas: vgimg.New(5.08*vg.Centimeter, 5.08*vg.Centimeter)} p.Draw(draw.New(c)) b := bytes.NewBuffer([]byte{}) if _, err = c.WriteTo(b); err != nil { t.Error(err) } f, err := os.Open(filepath.Join("testdata", "issue179.jpg")) if err != nil { t.Error(err) } defer f.Close() want, err := ioutil.ReadAll(f) if err != nil { t.Error(err) } if !bytes.Equal(b.Bytes(), want) { t.Error("Image mismatch") } }
func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: plotWav <file.wav>\n") os.Exit(1) } // open file testInfo, err := os.Stat(os.Args[1]) checkErr(err) testWav, err := os.Open(os.Args[1]) checkErr(err) wavReader, err := wav.NewReader(testWav, testInfo.Size()) checkErr(err) // File informations fmt.Println(wavReader) // limit sample count sampleCnt := wavReader.GetSampleCount() if sampleCnt > 10000 { sampleCnt = 10000 } // setup plotter p, err := plot.New() checkErr(err) p.Title.Text = "Waveplot" p.X.Label.Text = "t" p.Y.Label.Text = "Ampl" pts := make(plotter.XYs, sampleCnt) // read samples and construct points for plot for i := range pts { n, err := wavReader.ReadSample() if err == io.EOF { break } checkErr(err) pts[i].X = float64(i) pts[i].Y = float64(n) } err = plotutil.AddLinePoints(p, "", pts) checkErr(err) // construct output filename inputFname := path.Base(os.Args[1]) plotFname := strings.Split(inputFname, ".")[0] + ".pdf" if err := p.Save(10*vg.Inch, 4*vg.Inch, plotFname); err != nil { panic(err) } }
func main() { // Connecting log.Println("Trying to connect to localhost:1972 ...") conn, err := gobci.Connect("localhost:1972") if err != nil { log.Fatal(err) } defer conn.Close() // Getting header information log.Println("Requesting header data ...") header, err := conn.GetHeader() if err != nil { log.Fatal(err) } for { // Getting samples log.Println("Requesting sample data ...") var amountOfSamples uint32 = 100 if header.NSamples < amountOfSamples { log.Fatal("Not enough samples avialable") } samples, err := conn.GetData(0, 0) if err != nil { log.Fatal(err) } // Visualizing the channels channels := make([]channelXYer, header.NChannels) for _, sample := range samples { for i := uint32(0); i < header.NChannels; i++ { channels[i].Values = append(channels[i].Values, sample[i]) } } for chIndex := range channels { channels[chIndex].freq = header.SamplingFrequency } log.Println("Plotting samples ...") plt, err := plot.New() plotutil.AddLinePoints(plt, "CH0", plotter.XYer(channels[0])) //"CH1", plotter.XYer(channels[1]), //"CH2", plotter.XYer(channels[2])) log.Println("Saving plot to output.jpg ...") plt.Save(10*vg.Inch, 5*vg.Inch, "output.jpg") } log.Println("Done") }
func newplttr(nproc int) *plttr { p, err := plot.New() if err != nil { panic(err) } plt := &plttr{Plot: p, nproc: nproc} plt.X.Min, plt.X.Max = 0, 1 plt.Y.Min, plt.Y.Max = -1.5, 1.5 return plt }