
Sensible integer scale for Gonum Plot
January 20, 2021
Over the years, I found myself multiple times using Gonum Plot. I do find it as a very good and easy to use plotting tool for Go.
The problem I found myself, over and over, dealing with is the tickers scale. If you know before-hand the values that can be expected to be created by the application, it is very straightforward, but the majority of times, this is not the case. I often find myself creating a plotting application on data that track events that have not yet happened and cannot predict their range.
To solve the issue, I create a package that has a struct that implements the Ticker interface and provides tickers that are usually sensible.
Since this struct only works for integer scales, I called it sit
, which stands for “Sensible Int Ticks”.
You can find the sit
package here, and an example of its usage is:
package main
import (
"github.com/fale/sit"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
)
func main() {
p, err := plot.New()
if err != nil {
return
}
line := plotter.XYs{
plotter.XY{X: float64(1), Y: float64(1)},
plotter.XY{X: float64(2), Y: float64(11)},
plotter.XY{X: float64(3), Y: float64(5)},
plotter.XY{X: float64(4), Y: float64(2)},
plotter.XY{X: float64(5), Y: float64(7)},
}
p.Add(plotter.NewGrid())
err = plotutil.AddLinePoints(p,
"First", line,
)
if err != nil {
return
}
p.Y.Tick.Marker = sit.Ticker{}
p.Y.Min = sit.Min(p.Y.Min, p.Y.Max)
p.Y.Max = sit.Max(p.Y.Min, p.Y.Max)
if err := p.Save(10*vg.Inch, 5*vg.Inch, "points.png"); err != nil {
return
}
return
}
The important part is the block between line 33 and 35, that - to be clear - is the following:
p.Y.Tick.Marker = sit.Ticker{}
p.Y.Min = sit.Min(p.Y.Min, p.Y.Max)
p.Y.Max = sit.Max(p.Y.Min, p.Y.Max)
The first line of the block ensures that the object that implements the Ticker
interface from GoNum Plot is used for the Y axes, while the other two make sure that the provided functions from the sit
package adequately set the min and max Y values.
You can also use it for X ax in a similar way by exchanging Y
with X
in the three highlighted lines.
I hope this helps other people as much as it helped me!