### Generate Bubble Plots in Go Source: https://github.com/gonum/plot/wiki/Example-plots Creates a bubble plot using random data points with X, Y, and Z values. This example requires importing plot, plotter, vg, and color packages. The Z value is used to determine the size of the bubbles, though this specific example does not explicitly scale bubble size based on Z. ```go package main import ( "image/color" "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) func main() { rand.Seed(int64(0)) n := 10 bubbleData := randomTriples(n) p := plot.New() p.Title.Text = "Bubbles" p.X.Label.Text = "X" p.Y.Label.Text = "Y" bs, err := plotter.NewScatter(bubbleData) if err != nil { panic(err) } bs.Color = color.RGBA{R: 196, B: 128, A: 255} p.Add(bs) if err := p.Save(4*vg.Inch, 4*vg.Inch, "bubble.png"); err != nil { panic(err) } } // randomTriples returns some random x, y, z triples // with some interesting kind of trend. func randomTriples(n int) plotter.XYZs { data := make(plotter.XYZs, n) for i := range data { if i == 0 { data[i].X = rand.Float64() } else { data[i].X = data[i-1].X + 2*rand.Float64() } data[i].Y = data[i].X + 10*rand.Float64() data[i].Z = data[i].X } return data } ``` -------------------------------- ### Creating a Histogram with Normal Distribution Overlay in Go Source: https://github.com/gonum/plot/wiki/Example-plots This example generates a histogram from random normal distribution data and overlays the probability density function of the standard normal distribution. It demonstrates normalizing the histogram to sum to one and customizing the overlay function's appearance. ```go package main import ( "image/color" "math" "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" "github.com/gonum/stat/distuv" ) func main() { // Draw some random values from the standard // normal distribution. rand.Seed(int64(0)) v := make(plotter.Values, 10000) for i := range v { v[i] = rand.NormFloat64() } // Make a plot and set its title. p := plot.New() p.Title.Text = "Histogram" // Create a histogram of our values drawn // from the standard normal. h, err := plotter.NewHist(v, 16) if err != nil { panic(err) } // Normalize the area under the histogram to // sum to one. h.Normalize(1) p.Add(h) // The normal distribution function norm := plotter.NewFunction(distuv.UnitNormal.Prob) 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, "hist.png"); err != nil { panic(err) } } ``` -------------------------------- ### Creating Box Plots with plotutil in Go Source: https://github.com/gonum/plot/wiki/Example-plots This example demonstrates a more concise way to create box plots for multiple distributions using the plotutil.AddBoxPlots helper function. It simplifies the process by handling the creation and addition of box plots with specified labels and data. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" ) func main() { // Get some data to display in our plot. rand.Seed(int64(0)) n := 10 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() } // Create the plot and set its title and axis label. p := plot.New() p.Title.Text = "Box plots" p.Y.Label.Text = "Values" // Make boxes for our data and add them to the plot. err := plotutil.AddBoxPlots(p, vg.Points(20), "Uniform\nDistribution", uniform, "Normal\nDistribution", normal, "Exponential\nDistribution", expon) if err != nil { panic(err) } if err := p.Save(3*vg.Inch, 4*vg.Inch, "boxplot.png"); err != nil { panic(err) } } ``` -------------------------------- ### Plotting Multiple Functions in Go Source: https://github.com/gonum/plot/wiki/Example-plots This example demonstrates how to plot multiple mathematical functions (quadratic, exponential, and sine) on the same plot. It shows how to customize line styles, colors, and add a legend. Note that functions require manual setting of axis ranges as they do not have finite bounds. ```go package main import ( "image/color" "math" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) func main() { p := plot.New() 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 = 0.5 * vg.Inch // 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) } } ``` -------------------------------- ### Creating Box Plots with plotter in Go Source: https://github.com/gonum/plot/wiki/Example-plots This example shows how to create box plots for different distributions (uniform, normal, exponential) using the plotter package. It involves creating plotter.Values for each dataset, instantiating plotter.NewBoxPlot for each, customizing their appearance, and adding them to the plot with nominal X-axis labels. ```go package main import ( "image/color" "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) func main() { // Get some data to display in our plot. rand.Seed(uint64(0)) n := 10 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() } // Create the plot and set its title and axis label. p := plot.New() p.Title.Text = "Box plots" p.Y.Label.Text = "Values" // Make boxes for our data and add them to the plot. w := vg.Points(20) b0, err := plotter.NewBoxPlot(w, 0, uniform) b0.FillColor = color.RGBA{127, 188, 165, 1} if err != nil { panic(err) } b1, err := plotter.NewBoxPlot(w, 1, normal) b1.FillColor = color.RGBA{127, 188, 165, 1} if err != nil { panic(err) } b2, err := plotter.NewBoxPlot(w, 2, expon) b2.FillColor = color.RGBA{127, 188, 165, 1} if err != nil { panic(err) } 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("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") if err := p.Save(3*vg.Inch, 4*vg.Inch, "boxplot.png"); err != nil { panic(err) } } ``` -------------------------------- ### Grouped Bar Chart Source: https://github.com/gonum/plot/wiki/Example-plots This example demonstrates the creation of a grouped bar chart. It involves defining multiple sets of values (groups), creating `BarChart` plotters for each group, and then adding them to the plot with appropriate offsets and colors. The `NominalX` function is used to label the categories on the X-axis. ```go package main import ( "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" ) func main() { groupA := plotter.Values{20, 35, 30, 35, 27} groupB := plotter.Values{25, 32, 34, 20, 25} groupC := plotter.Values{12, 28, 15, 21, 8} p := plot.New() p.Title.Text = "Bar chart" p.Y.Label.Text = "Heights" w := vg.Points(20) barsA, err := plotter.NewBarChart(groupA, w) if err != nil { panic(err) } barsA.LineStyle.Width = vg.Length(0) barsA.Color = plotutil.Color(0) barsA.Offset = -w barsB, err := plotter.NewBarChart(groupB, w) if err != nil { panic(err) } barsB.LineStyle.Width = vg.Length(0) barsB.Color = plotutil.Color(1) barsC, err := plotter.NewBarChart(groupC, w) if err != nil { panic(err) } barsC.LineStyle.Width = vg.Length(0) barsC.Color = plotutil.Color(2) barsC.Offset = w p.Add(barsA, barsB, barsC) p.Legend.Add("Group A", barsA) p.Legend.Add("Group B", barsB) p.Legend.Add("Group C", barsC) p.Legend.Top = true p.NominalX("One", "Two", "Three", "Four", "Five") if err := p.Save(5*vg.Inch, 3*vg.Inch, "barchart.png"); err != nil { panic(err) } } ``` -------------------------------- ### Points with Error Bars Source: https://github.com/gonum/plot/wiki/Example-plots This example shows how to create plots with error bars. It utilizes `plotutil.NewErrorPoints` to generate points with associated error information, which can represent confidence intervals or min/max ranges. The `plotutil.AddErrorBars` function is then used to draw these error bars on the plot. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" ) func main() { // Get some data. n, m := 5, 10 pts := make([]plotter.XYer, n) for i := range pts { xys := make(plotter.XYs, m) pts[i] = xys center := float64(i) for j := range xys { xys[j].X = center + (rand.Float64() - 0.5) xys[j].Y = center + (rand.Float64() - 0.5) } } plt, err := plot.New() if err != nil { panic(err) } // Create two lines connecting points and error bars. For // the first, each point is the mean x and y value and the // error bars give the 95% confidence intervals. For the // second, each point is the median x and y value with the // error bars showing the minimum and maximum values. mean95, err := plotutil.NewErrorPoints(plotutil.MeanAndConf95, pts...) if err != nil { panic(err) } medMinMax, err := plotutil.NewErrorPoints(plotutil.MedianAndMinMax, pts...) if err != nil { panic(err) } plotutil.AddLinePoints(plt, "mean and 95% confidence", mean95, "median and minimum and maximum", medMinMax) plotutil.AddErrorBars(plt, mean95, medMinMax) // Add the points that are summarized by the error points. plotutil.AddScatters(plt, pts[0], pts[1], pts[2], pts[3], pts[4]) plt.Save(4*vg.Inch, 4*vg.Inch, "errpoints.png") } ``` -------------------------------- ### Stream Plot Output to an io.Writer Source: https://context7.com/gonum/plot/llms.txt Generates a plot and returns an io.WriterTo interface for streaming the rendered plot to any writer, such as an HTTP response or a buffer. This example demonstrates writing SVG bytes into a bytes.Buffer. ```go import ( "bytes" "gonum.org/v1/plot" "gonum.org/v1/plot/vg" ) p := plot.New() p.Title.Text = "Streamed Plot" // Write SVG bytes into a buffer wt, err := p.WriterTo(20*vg.Centimeter, 15*vg.Centimeter, "svg") if err != nil { panic(err) } var buf bytes.Buffer if _, err := wt.WriteTo(&buf); err != nil { panic(err) } // buf.Bytes() now contains the complete SVG document ``` -------------------------------- ### Custom Tick Marks with Commas Source: https://github.com/gonum/plot/wiki/Example-plots This example demonstrates how to override the default tick marker to add commas as thousands separators to axis labels. This improves the readability of large numbers on plots. It requires defining a custom type that implements the plot.Tick.Marker interface and a helper function to format the string. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" ) func main() { rand.Seed(int64(0)) p := plot.New() p.Title.Text = "Relabeling tick marks example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" // Use a custom tick marker interface implementation with the Ticks function, // that computes the default tick marks and re-labels the major ticks with commas. p.Y.Tick.Marker = commaTicks{} err := plotutil.AddLinePoints(p, "First", randomPoints(15), "Second", randomPoints(15), "Third", randomPoints(15)) if err != nil { panic(err) } // Save the plot to a PNG file. if err := p.Save(4*vg.Inch, 4*vg.Inch, "points_commas.png"); err != nil { panic(err) } } // RandomPoints returns some random x, y points. func randomPoints(n int) plotter.XYs { pts := make(plotter.XYs, n) for i := range pts { if i == 0 { pts[i].X = rand.Float64() } else { pts[i].X = pts[i-1].X + rand.Float64() } pts[i].Y = (pts[i].X + 10*rand.Float64()) * 1000 } return pts } type commaTicks struct{} // Ticks computes the default tick marks, but inserts commas // into the labels for the major tick marks. func (commaTicks) Ticks(min, max float64) []plot.Tick { tks := plot.DefaultTicks{}.Ticks(min, max) for i, t := range tks { if t.Label == "" { // Skip minor ticks, they are fine. continue } tks[i].Label = addCommas(t.Label) } return tks } // AddCommas adds commas after every 3 characters from right to left. // NOTE: This function is a quick hack, it doesn't work with decimal // points, and may have a bunch of other problems. func addCommas(s string) string { rev := "" n := 0 for i := len(s) - 1; i >= 0; i-- { rev += string(s[i]) n++ if n%3 == 0 { rev += "," } } s = "" for i := len(rev) - 1; i >= 0; i-- { s += string(rev[i]) } return s } ``` -------------------------------- ### Get Coordinate Transforms Source: https://github.com/gonum/plot/wiki/Creating-Custom-Plotters:-A-tutorial-on-creating-custom-Plotters Obtain functions to transform data coordinates to drawing coordinates using the plot's transforms. This is essential for positioning elements on the canvas. ```Go trX, trY := plt.Transforms(&c) ``` -------------------------------- ### Simple Line and Point Plot with plotutil Source: https://github.com/gonum/plot/wiki/Example-plots Use plotutil.AddLinePoints for quick creation of line and point plots with default styling. This is suitable when the default color, dash, and glyph settings are acceptable. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/plotutil" "gonum.org/v1/plot/vg" ) func main() { rand.Seed(int64(0)) p := plot.New() p.Title.Text = "Plotutil example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" err := plotutil.AddLinePoints(p, "First", randomPoints(15), "Second", randomPoints(15), "Third", randomPoints(15)) if err != nil { panic(err) } // Save the plot to a PNG file. if err := p.Save(4*vg.Inch, 4*vg.Inch, "points.png"); err != nil { panic(err) } } // randomPoints returns some random x, y points. func randomPoints(n int) plotter.XYs { pts := make(plotter.XYs, n) for i := range pts { if i == 0 { p ts[i].X = rand.Float64() } else { p ts[i].X = pts[i-1].X + rand.Float64() } p ts[i].Y = pts[i].X + 10*rand.Float64() } return pts } ``` -------------------------------- ### Create a Histogram Source: https://context7.com/gonum/plot/llms.txt Bins data into a specified number of equal-width bins and can normalize to unit area for probability density. Optionally overlay theoretical distributions. ```Go import ( "image/color" "math" "math/rand/v2" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) rnd := rand.New(rand.NewPCG(1, 1)) vals := make(plotter.Values, 10000) for i := range vals { vals[i] = rnd.NormFloat64() } h, err := plotter.NewHist(vals, 20) if err != nil { panic(err) } h.Normalize(1) // normalize to unit area h.FillColor = color.RGBA{R: 100, G: 150, B: 255, A: 200} // Overlay the theoretical PDF pdf := plotter.NewFunction(func(x float64) float64 { return math.Exp(-x*x/2) / math.Sqrt(2*math.Pi) }) pdf.Color = color.RGBA{R: 255, A: 255} pdf.Width = vg.Points(2) p := plot.New() p.Title.Text = "Normal Distribution" p.Add(h, pdf) p.Save(15*vg.Centimeter, 10*vg.Centimeter, "histogram.png") ``` -------------------------------- ### Test Custom Bubbles Plotter Source: https://github.com/gonum/plot/wiki/Creating-Custom-Plotters:-A-tutorial-on-creating-custom-Plotters Sets up a new plot, generates random bubble data, creates a Bubbles plotter instance, adds it to the plot, sets axis ranges, and saves the plot to a PNG file. Requires `plot.New`, `plot.Plotter`, and `vg.Inch`. ```Go func TestBubbles(t *testing.T) { rand.Seed(int64(0)) n := 10 bubbleData := randomTriples(n) p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Bubbles" p.X.Label.Text = "X" p.Y.Label.Text = "Y" bs := NewBubbles(bubbleData, vg.Points(1), vg.Points(20)) bs.Color = color.RGBA{R:196, B:128, A: 255} p.Add(bs) // Axis ranges that seem to include all bubbles. p.X.Min = 0 p.X.Max = 15 p.Y.Min = 0 p.Y.Max = 25 if err := p.Save(4*vg.Inch, 4*vg.Inch, "bubble.png"); err != nil { panic(err) } } ``` -------------------------------- ### Configure Plot Axes with Scales and Ticks Source: https://context7.com/gonum/plot/llms.txt Illustrates axis configuration including logarithmic and inverted scales, custom constant ticks, and nominal (categorical) axes for bar charts. Use plot.LogScale for log axes and plot.ConstantTicks for custom ticks. ```go import ( "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) p := plot.New() // Log scale on Y axis p.Y.Scale = plot.LogScale{} p.Y.Tick.Marker = plot.LogTicks{Prec: -1} // Custom constant ticks on X p.X.Tick.Marker = plot.ConstantTicks([]plot.Tick{ {Value: 0, Label: "Jan"}, {Value: 1, Label: "Feb"}, {Value: 2, Label: "Mar"}, {Value: 3, Label: "Apr"}, }) // Invert an axis p.X.Scale = plot.InvertedScale{Normalizer: plot.LinearScale{}} // Nominal (categorical) axis — hides numeric ticks p2 := plot.New() vals := plotter.Values{12, 25, 8, 19} bars, _ := plotter.NewBarChart(vals, vg.Points(20)) p2.Add(bars) p2.NominalX("Q1", "Q2", "Q3", "Q4") // integer positions 0,1,2,3 → labels p2.Save(15*vg.Centimeter, 10*vg.Centimeter, "nominal.png") ``` -------------------------------- ### Create New Bubble Plotter Instance Source: https://github.com/gonum/plot/wiki/Creating-Custom-Plotters:-A-tutorial-on-creating-custom-Plotters The NewBubbles function creates a new bubble plot plotter. It copies the provided XYZer data, computes the minimum and maximum Z values, and initializes the plotter with specified minimum and maximum radii. ```go // NewBubbles creates as new bubble plot plotter for // the given data, with a minimum and maximum // bubble radius. func NewBubbles(xyz XYZer, min, max vg.Length) *Bubbles { cpy := CopyXYZs(xyz) minz := cpy[0].Z maxz := cpy[0].Z for _, d := range cpy { minz = math.Min(minz, d.Z) maxz = math.Max(maxz, d.Z) } return &Bubbles{ XYZs: cpy, MinRadius: min, MaxRadius: max, MinZ: minz, MaxZ: maxz, } } ``` -------------------------------- ### Custom Plotter: Implement `Plotter` Interface Source: https://context7.com/gonum/plot/llms.txt Extend Gonum Plot by implementing the `Plotter` interface, which requires a `Plot(draw.Canvas, *plot.Plot)` method. Implementing `DataRanger` enables auto-scaling, and `GlyphBoxer` prevents glyph clipping. ```go import ( "image/color" "gonum.org/v1/plot" "gonum.org/v1/plot/vg" "gonum.org/v1/plot/vg/draw" ) // HorizLine draws a single horizontal rule across the full data range. type HorizLine struct { Y float64 Style draw.LineStyle } func (h HorizLine) Plot(c draw.Canvas, plt *plot.Plot) { _, trY := plt.Transforms(&c) y := trY(h.Y) if !c.ContainsY(y) { return } c.StrokeLine2(h.Style, c.Min.X, y, c.Max.X, y) } func (h HorizLine) DataRange() (xmin, xmax, ymin, ymax float64) { return 0, 1, h.Y, h.Y } p := plot.New() rule := HorizLine{ Y: 50, Style: draw.LineStyle{Color: color.RGBA{R: 200, A: 255}, Width: vg.Points(1)}, } p.Add(rule) p.Save(15*vg.Centimeter, 10*vg.Centimeter, "custom.png") ``` -------------------------------- ### Create a Line Plot with Custom Styling Source: https://context7.com/gonum/plot/llms.txt Generates a line plot using NewLinePoints, which also returns a scatter plotter for the same data. Allows customization of line color, width, step style (NoStep, PreStep, MidStep, PostStep), and fill color beneath the line. ```go import ( "image/color" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) pts := plotter.XYs{ {X: 0, Y: 0}, {X: 1, Y: 2}, {X: 2, Y: 1.5}, {X: 3, Y: 3}, {X: 4, Y: 2.5}, } line, scatter, err := plotter.NewLinePoints(pts) if err != nil { panic(err) } line.Color = color.RGBA{R: 255, A: 255} line.Width = vg.Points(2) // Step-style connections: NoStep (default), PreStep, MidStep, PostStep line.StepStyle = plotter.MidStep // Area fill beneath the line line.FillColor = color.RGBA{R: 255, A: 40} p := plot.New() p.Add(line, scatter) p.Save(15*vg.Centimeter, 10*vg.Centimeter, "line.png") ``` -------------------------------- ### Define XYZer Interface and Implementations Source: https://github.com/gonum/plot/wiki/Creating-Custom-Plotters:-A-tutorial-on-creating-custom-Plotters Defines the XYZer interface for data with X, Y, and Z coordinates and provides an implementation using a slice. This is useful for plotters requiring three-dimensional data. ```go // XYZer wraps the Len and XYZ methods. type XYZer interface { // Len returns the number of x, y, z triples. Len() int // XYZ returns an x, y, z triple. XYZ(int) (float64, float64, float64) } // XYZs implements the XYZer interface using a slice. type XYZs []struct{ X, Y, Z float64 } // Len implements the Len method of the XYZer interface. func (xyz XYZs) Len() int { return len(xyz) } // XYZ implements the XYZ method of the XYZer interface. func (xyz XYZs) XYZ(i int) (float64, float64, float64) { return xyz[i].X, xyz[i].Y, xyz[i].Z } ``` ```go // CopyXYZs copies an XYZer. func CopyXYZs(data XYZer) XYZs { cpy := make(XYZs, data.Len()) for i := range cpy { cpy[i].X, cpy[i].Y, cpy[i].Z = data.XYZ(i) } return cpy } ``` -------------------------------- ### Generate Quartile Plots in Go Source: https://github.com/gonum/plot/wiki/Example-plots Generates quartile plots for uniform, normal, and exponential distributions. This requires importing plot and plotter packages. The X-axis is set to nominal with distribution names. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" ) func main() { // Get some data to display in our plot. rand.Seed(int64(0)) n := 10 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() } // Create the plot and set its title and axis label. p := plot.New() p.Title.Text = "Quartile plots" p.Y.Label.Text = "Values" // Make boxes for our data and add them to the plot. q0, err := plotter.NewQuartPlot(0, uniform) if err != nil { panic(err) } q1, err := plotter.NewQuartPlot(1, normal) if err != nil { panic(err) } q2, err := plotter.NewQuartPlot(2, expon) if err != nil { panic(err) } p.Add(q0, q1, q2) // 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") if err := p.Save(3*vg.Inch, 4*vg.Inch, "quartile.png"); err != nil { panic(err) } } ``` -------------------------------- ### Create Grouped Bar Charts Source: https://context7.com/gonum/plot/llms.txt Generates grouped or stacked bar charts. Use `Offset` to group bars side-by-side or `StackOn` to stack them. Ensure bar width is specified. ```Go import ( "image/color" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) groupA := plotter.Values{20, 35, 30, 35, 27} groupB := plotter.Values{25, 32, 34, 20, 25} w := vg.Points(10) barsA, err := plotter.NewBarChart(groupA, w) if err != nil { panic(err) } barsA.Color = color.RGBA{R: 255, A: 255} barsA.Offset = -w / 2 // shift left to group barsB, err := plotter.NewBarChart(groupB, w) if err != nil { panic(err) } barsB.Color = color.RGBA{B: 255, A: 255} barsB.Offset = w / 2 // shift right to group // To stack instead: barsB.StackOn(barsA) p := plot.New() p.Title.Text = "Grouped Bar Chart" p.Y.Label.Text = "Value" p.Add(barsA, barsB) p.Legend.Add("Group A", barsA) p.Legend.Add("Group B", barsB) p.Legend.Top = true p.NominalX("Mon", "Tue", "Wed", "Thu", "Fri") p.Save(15*vg.Centimeter, 10*vg.Centimeter, "barchart.png") ``` -------------------------------- ### Detailed Style Settings for Points and Lines Source: https://github.com/gonum/plot/wiki/Example-plots Manually configure plot elements like color, line style, and glyph shape for Scatter, Line, and LinePoints plotters. This provides fine-grained control over the plot's appearance and legend entries. ```go package main import ( "image/color" "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" "gonum.org/v1/plot/vg/draw" ) func main() { // Get some random points rand.Seed(int64(0)) n := 15 scatterData := randomPoints(n) lineData := randomPoints(n) linePointsData := randomPoints(n) // Create a new plot, set its title and // axis labels. p := plot.New() 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 = draw.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) // Save the plot to a PNG file. if err := p.Save(4*vg.Inch, 4*vg.Inch, "points.png"); err != nil { panic(err) } } // randomPoints returns some random x, y points. func randomPoints(n int) plotter.XYs { pts := make(plotter.XYs, n) for i := range pts { if i == 0 { p ts[i].X = rand.Float64() } else { p ts[i].X = pts[i-1].X + rand.Float64() } p ts[i].Y = pts[i].X + 10*rand.Float64() } return pts } ``` -------------------------------- ### Create a Box Plot Source: https://context7.com/gonum/plot/llms.txt Computes Tukey's five-number summary and marks outliers. Supports vertical and horizontal orientations. Optionally label outlier points. ```Go import ( "image/color" "math/rand/v2" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) rnd := rand.New(rand.NewPCG(42, 42)) data := make(plotter.Values, 200) for i := range data { data[i] = rnd.NormFloat64()*2 + 5 } box, err := plotter.NewBoxPlot(vg.Points(30), 0, data) if err != nil { panic(err) } box.FillColor = color.RGBA{R: 127, G: 188, B: 165, A: 200} // Optionally label outlier points labels, err := box.OutsideLabels(plotter.ValueLabels(nil)) // pass a Labeller _ = labels p := plot.New() p.Title.Text = "Box Plot" p.NominalX("Normal(5,2)") p.Add(box) p.Save(8*vg.Centimeter, 12*vg.Centimeter, "boxplot.png") ``` -------------------------------- ### plot.New Source: https://context7.com/gonum/plot/llms.txt Creates a new plot with default settings. You can then configure titles, labels, and axis ranges before adding plotters. ```APIDOC ## plot.New — create a new plot `plot.New()` returns a `*Plot` with sensible defaults: white background, Liberation Serif font, linear axes, and automatic range detection. Axis labels, titles, and tick styles are configured directly on the returned struct. ### Method ```go p := plot.New() p.Title.Text = "My Plot" p.X.Label.Text = "X Axis" p.Y.Label.Text = "Y Axis" // Manual axis range (optional — auto-set when plotters are added) p.X.Min, p.X.Max = 0, 10 p.Y.Min, p.Y.Max = 0, 100 // Save to PNG (format inferred from extension) if err := p.Save(15*vg.Centimeter, 10*vg.Centimeter, "output.png"); err != nil { panic(err) } // Supported formats: .eps .jpg .pdf .png .svg .tex .tif ``` ``` -------------------------------- ### Create and Save a New Plot Source: https://context7.com/gonum/plot/llms.txt Creates a new plot with a title and axis labels, optionally sets manual axis ranges, and saves it to a PNG file. The format is inferred from the file extension. Supported formats include .eps, .jpg, .pdf, .png, .svg, .tex, .tif. ```go import ( "gonum.org/v1/plot" "gonum.org/v1/plot/vg" ) p := plot.New() p.Title.Text = "My Plot" p.X.Label.Text = "X Axis" p.Y.Label.Text = "Y Axis" // Manual axis range (optional — auto-set when plotters are added) p.X.Min, p.X.Max = 0, 10 p.Y.Min, p.Y.Max = 0, 100 // Save to PNG (format inferred from extension) if err := p.Save(15*vg.Centimeter, 10*vg.Centimeter, "output.png"); err != nil { panic(err) } // Supported formats: .eps .jpg .pdf .png .svg .tex .tif ``` -------------------------------- ### Create Heat Map from Grid Data Source: https://context7.com/gonum/plot/llms.txt Generates a heat map using plotter.NewHeatMap from a GridXYZ data source and a color palette. Supports vector and rasterized rendering. ```go import ( "os" "gonum.org/v1/gonum/mat" "gonum.org/v1/plot" "gonum.org/v1/plot/palette" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" "gonum.org/v1/plot/vg/draw" "gonum.org/v1/plot/vg/vgimg" ) // Implement GridXYZ with a gonum dense matrix. type grid struct{ *mat.Dense } func (g grid) Dims() (c, r int) { r, c = g.Dense.Dims(); return c, r } func (g grid) Z(c, r int) float64 { return g.Dense.At(r, c) } func (g grid) X(c int) float64 { return float64(c) } func (g grid) Y(r int) float64 { return float64(r) } data := mat.NewDense(4, 5, []float64{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, }) h := plotter.NewHeatMap(grid{data}, palette.Heat(16, 1)) p := plot.New() p.Title.Text = "Heat Map" p.Add(h) img := vgimg.New(20*vg.Centimeter, 15*vg.Centimeter) p.Draw(draw.New(img)) f, _ := os.Create("heatmap.png") defer f.Close() vgimg.PngCanvas{Canvas: img}.WriteTo(f) ``` -------------------------------- ### Generate Horizontal Box Plots in Go Source: https://github.com/gonum/plot/wiki/Example-plots Creates horizontal box plots for uniform, normal, and exponential distributions. Requires importing plot, plotter, and vg packages. The Y-axis is set to nominal with distribution names. ```go package main import ( "math/rand" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) func main() { // Get some data to display in our plot. rand.Seed(int64(0)) n := 10 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() } // Create the plot and set its title and axis label. p := plot.New() p.Title.Text = "Horizontal box plots" p.X.Label.Text = "Values" // Make horizontal boxes for our data and add // them to the plot. w := vg.Points(20) b0, err := plotter.MakeHorizBoxPlot(w, 0, uniform) if err != nil { panic(err) } b1, err := plotter.MakeHorizBoxPlot(w, 1, normal) if err != nil { panic(err) } b2, err := plotter.MakeHorizBoxPlot(w, 2, expon) if err != nil { panic(err) } p.Add(b0, b1, b2) // Set the Y axis of the plot to nominal with // the given names for y=0, y=1 and y=2. p.NominalY("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") if err := p.Save(4*vg.Inch, 3*vg.Inch, "boxplot-horiz.png"); err != nil { panic(err) } } ``` -------------------------------- ### Implement Bubbles Plotter Source: https://github.com/gonum/plot/wiki/Creating-Custom-Plotters:-A-tutorial-on-creating-custom-Plotters The Plot method for the Bubbles plotter. It transforms data points, calculates bubble radii, and draws filled circles on the canvas. Requires `vg.Path` and `draw.Canvas`. ```Go // Plot implements the plot.Plotter interface. func (bs *Bubbles) Plot(c draw.Canvas, plt *plot.Plot) { trX, trY := plt.Transforms(&c) c.SetColor(bs.Color) for _, d := range bs.XYZs { // Transform the data x, y coordinate of this bubble // to the corresponding drawing coordinate. x := trX(d.X) y := trY(d.Y) // Get the radius of this bubble. The radius // is specified in drawing units (i.e., its size // is given as the final size at which it will // be drawn) so it does not need to be transformed. rad := bs.radius(d.Z) // Fill a circle centered at x,y on the draw area. var p vg.Path p.Move(x + rad, y) p.Arc(x, y, rad, 0, 2*math.Pi) p.Close() c.Fill(p) } } ```