plot

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: BSD-3-Clause Imports: 16 Imported by: 0

README

go-plot/plot

go-plot/plot

Docs CI pkg.go.dev coverage go cgo status license

Pure-Go (CGO=0) plotting for go-ndarray: matplotlib-class figures to SVG and PNG, with real TeX in the labels.

🌐 Website · 📚 Documentation

A line plot of two signals with TeX labels, drawn by go-plot

The object model and the defaults are matplotlib's — figure size, fonts, colour cycle, margins, tick placement and tick labels — so a figure looks the way a matplotlib user expects, and the parts that can be equal are tested equal to matplotlib: tick locations and labels on 408 real axes, eight colormaps entry for entry, and the layout of 30 figures (Axes positions, view limits, tick labels, and positions after TightLayout). The API is the object-oriented one that most notebooks use (fig, ax = plt.subplots(); ax.plot(...)). What Go adds: one static binary, js/wasm, no Python, and TeX labels set by a real TeX math typesetter (go-tex/math).

Example

package main

import (
	"math"
	"os"

	"github.com/go-plot/plot"
)

func main() {
	x := make([]float64, 200)
	y := make([]float64, 200)
	for i := range x {
		x[i] = float64(i) / 20
		y[i] = math.Sin(x[i])
	}
	fig, axs := plot.Subplots(1, 1)
	ax := axs[0][0]
	ax.Plot(x, y, plot.Label(`$\sin t$`))
	ax.Plot(x, y, plot.Marker("o"), plot.LineStyle("None"), plot.MarkerSize(2))
	ax.SetXLabel(`time $t$ (s)`)
	ax.Legend()
	fig.SavePNG(os.Stdout)
}

Data arguments take []float64, other numeric slices, or a *ndarray.Array of any dtype. A notebook kernel calls fig.Display(), which returns the figure as image/svg+xml and image/png.

What is in v0

figures NewFigure, Subplots(rows, cols), AddAxes, size in inches and dpi, TightLayout
plots Plot (lines, 17 markers, 4 line styles), Scatter (size and colour per point, colormaps), Bar, Barh, Hist, FillBetween, ErrorBar, Imshow (2-D data or RGB(A)), Contour, Contourf, Axhline, Axvline, Text, Annotate
axes titles, labels, Legend (with "best"), Grid, SetXLim/SetYLim, linear and log scales, TwinX, manual ticks, aspect
colour matplotlib's named colours, tab10 cycle, viridis, plasma, inferno, magma, cividis, gray, coolwarm, RdBu (and _r), Colorbar, LogNorm
output SaveSVG, SavePNG, Display

Not yet: symlog/date axes, constrained_layout, boxplot/pie/violin, hatching, windows (go-widgets/window), PDF. The full list, and every place where go-plot differs from matplotlib, is in docs/design.md.

Compared with matplotlib

Rendering: twelve reference figures drawn by both (same data, size, dpi) put every axes frame and every tick mark on the same pixel, and after TightLayout within 2 pixels; the curves overlap to 0.970–1.000 (see docs/design.md, with the negative controls the comparison is required to fail).

Speed, in-process, medians of 9 interleaved fresh-process runs on a loaded 16-core host (docs/perf.md):

figure go-plot matplotlib 3.11.2
1e6-point line → PNG 0.055 s 0.065 s 1.2x
1e6-point line → SVG 0.019 s 0.053 s 2.8x
1000² imshow → PNG 0.025 s 0.042 s 1.7x
1000² imshow → SVG 0.020 s 0.042 s 2.1x

Python's start and import matplotlib.pyplot (about 0.5 s) are not counted.

Built on

go-widgets/painter (compositing), go-gfx/gfx (anti-aliased coverage), go-opentype (DejaVu Sans, glyph outlines, kerning), go-tex/math (TeX), go-ndarray (data).

Development

go test ./...                                   # includes the matplotlib fixtures
uv run --with matplotlib --with numpy python tools/gen_ticks.py   # regenerate a fixture
cd tools/compare && go run . -out DIR && uv run --with matplotlib --with numpy python figures.py DIR \
  && uv run --with matplotlib --with numpy python compare.py DIR line=line ...

Write rendered images to a directory outside the repository.

License

BSD 3-Clause. See LICENSE.

Documentation

Overview

Package plot draws publication-quality figures — line plots, scatter plots, bars, histograms, images, contours — to SVG and PNG, in pure Go.

The object model is matplotlib's: a Figure holds Axes, an Axes holds what is plotted on it, and the defaults (sizes, fonts, colours, margins, tick placement and labels) are matplotlib's own, so a figure looks the way a matplotlib user expects:

fig, axs := plot.Subplots(1, 1)
ax := axs[0][0]
ax.Plot(x, y, plot.Label("data"))
ax.SetXLabel("time $t$ (s)")
ax.Legend()
fig.SavePNG(w)

Labels may contain TeX math between dollar signs, typeset by go-tex/math.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Values

func Values(v any) []float64

Values converts plot data to []float64. It accepts []float64, []float32, []int, []int64, []int32, a single float64 or int, any *ndarray.Array (of any dtype, flattened in row-major order; complex values keep their real part, as NumPy's astype does) and nil (which gives nil). Anything else panics: passing a type a plot cannot draw is a programming error, like an index out of range.

Types

type Axes

type Axes struct {
	Facecolor colors.RGBA
	// contains filtered or unexported fields
}

Axes is one plotting area: two axes, the things plotted on them, a title and a legend. Create it with Figure.Subplots, Subplots or Figure.AddAxes.

func (*Axes) Annotate

func (a *Axes) Annotate(s string, x, y, tx, ty float64, opts ...Option)

Annotate writes s at (tx, ty) and, with the Arrow option, draws an arrow from it to the point (x, y), as matplotlib's ax.annotate(s, xy=(x, y), xytext=(tx, ty), arrowprops=dict(arrowstyle="->")). Both points are in data coordinates.

Options: Arrow, and those of Text.

func (*Axes) Axhline

func (a *Axes) Axhline(y float64, opts ...Option)

Axhline draws a horizontal line across the Axes at y, as matplotlib's ax.axhline: it spans the full width whatever the x limits, and only y takes part in autoscaling. Its colour is C0 unless given; it does not advance the cycle.

Options: as Plot.

func (*Axes) Axvline

func (a *Axes) Axvline(x float64, opts ...Option)

Axvline draws a vertical line across the Axes at x, as matplotlib's ax.axvline.

Options: as Plot.

func (*Axes) Bar

func (a *Axes) Bar(x, height any, opts ...Option)

Bar draws vertical bars of the given heights at x, as matplotlib's ax.bar: 0.8 wide, centred on x, from 0, in the next colour of the fill cycle, with no edge.

Options: Width, Bottom, Align ("center" or "edge"), Color, Colors (one per bar), FaceColor, EdgeColor, LineWidth (edge), Alpha, Label, ZOrder.

func (*Axes) Barh

func (a *Axes) Barh(y, width any, opts ...Option)

Barh draws horizontal bars of the given widths at y, as matplotlib's ax.barh. Width sets the bar thickness (matplotlib's height=) and Bottom the left end.

Options: as Bar.

func (*Axes) Contour

func (a *Axes) Contour(x, y, z any, opts ...Option) *Mappable

Contour draws iso-lines of z, as matplotlib's ax.contour: about 7 levels chosen like axis ticks, each coloured from the colormap over the levels' range. x and y give the column and row coordinates and may be nil.

Options: Levels, NLevels, Cmap, Vmin, Vmax, Color (all lines), LineWidth, Alpha, ZOrder.

func (*Axes) Contourf

func (a *Axes) Contourf(x, y, z any, opts ...Option) *Mappable

Contourf fills the bands between levels of z, as matplotlib's ax.contourf; each band takes the colour of its middle value.

Options: as Contour.

func (*Axes) ErrorBar

func (a *Axes) ErrorBar(x, y any, opts ...Option)

ErrorBar draws y against x with error bars, as matplotlib's ax.errorbar: a line in the next cycle colour, and symmetric bars of YErr and/or XErr (one value for all points, or one per point) in the same colour, with caps CapSize points long on each side if CapSize is given.

Options: XErr, YErr, CapSize, ErrorColor, and those of Plot.

func (*Axes) Figure

func (a *Axes) Figure() *Figure

Figure returns the figure the Axes is on.

func (*Axes) FillBetween

func (a *Axes) FillBetween(x, y1, y2 any, opts ...Option)

FillBetween fills the region between y1 and y2 over x, as matplotlib's ax.fill_between. y2 may be nil (zero) or data. Without a colour it takes the next colour of the fill cycle.

Options: Where, Color, FaceColor, EdgeColor, LineWidth, Alpha, Label, ZOrder.

func (*Axes) Grid

func (a *Axes) Grid(on bool)

Grid turns the major grid lines of both axes on or off.

func (*Axes) Hist

func (a *Axes) Hist(x any, opts ...Option)

Hist draws a histogram of x, as matplotlib's ax.hist with histtype "bar": 10 equal bins over the data range by default, touching bars in the next colour of the line cycle (as in matplotlib).

Options: Bins, BinEdges, Density, Color, Alpha, EdgeColor, LineWidth, Label, ZOrder.

func (*Axes) Imshow

func (a *Axes) Imshow(data any, opts ...Option) *Mappable

Imshow shows 2-D data as an image, as matplotlib's ax.imshow: each value coloured through the colormap (viridis by default, scaled to the data range), pixel centres at integer coordinates, row 0 at the top, square pixels. A 3-D *ndarray.Array of shape (rows, cols, 3 or 4) is shown as RGB(A): floats in [0, 1], or uint8.

Options: Cmap, Vmin, Vmax, LogNorm, Extent, Origin, Aspect, Alpha, ZOrder.

func (*Axes) Legend

func (a *Axes) Legend(opts ...Option)

Legend adds a legend of every labelled artist, as matplotlib's ax.legend(): 10-point labels in a rounded, translucent frame.

Options: Loc, FontSize.

func (*Axes) Plot

func (a *Axes) Plot(x, y any, opts ...Option)

Plot draws y against x as lines and/or markers, as matplotlib's ax.plot does. x may be nil, meaning 0, 1, 2, ... . Without a colour option the line takes the next colour of the cycle.

Options: Color, RGBA, Alpha, LineWidth, LineStyle, Marker, MarkerSize, MarkerEdgeWidth, FaceColor (marker fill), EdgeColor (marker edge), Label, ZOrder, Clip.

func (*Axes) Scatter

func (a *Axes) Scatter(x, y any, opts ...Option) *Mappable

Scatter draws a marker at each (x, y), as matplotlib's ax.scatter: circles of 36 points² in the next colour of the fill cycle, edged in their own colour. With CValues the colours come from a colormap, and the returned Mappable can be given to Colorbar; otherwise it is nil.

Options: Sizes, CValues, Cmap, Vmin, Vmax, LogNorm, Color, Colors, Marker, EdgeColor, LineWidth (edge), Alpha, Label, ZOrder.

func (*Axes) SetAspect

func (a *Axes) SetAspect(r float64)

SetAspect sets the ratio of y units to x units on screen: 1 for "equal", 0 for "auto". The Axes box shrinks to honour it, as with matplotlib's adjustable="box".

func (*Axes) SetTitle

func (a *Axes) SetTitle(s string)

SetTitle sets the title above the Axes.

func (*Axes) SetXLabel

func (a *Axes) SetXLabel(s string)

SetXLabel sets the label of the x axis.

func (*Axes) SetXLim

func (a *Axes) SetXLim(lo, hi float64)

SetXLim fixes the x view limits and turns x autoscaling off. Equal limits are widened, as matplotlib widens them.

func (*Axes) SetXScale

func (a *Axes) SetXScale(s string)

SetXScale sets the x scale: "linear" or "log".

func (*Axes) SetXTicks

func (a *Axes) SetXTicks(locs []float64, labels ...string)

SetXTicks fixes the x tick locations and, when labels are given, their labels.

func (*Axes) SetYLabel

func (a *Axes) SetYLabel(s string)

SetYLabel sets the label of the y axis.

func (*Axes) SetYLim

func (a *Axes) SetYLim(lo, hi float64)

SetYLim fixes the y view limits and turns y autoscaling off.

func (*Axes) SetYScale

func (a *Axes) SetYScale(s string)

SetYScale sets the y scale: "linear" or "log".

func (*Axes) SetYTicks

func (a *Axes) SetYTicks(locs []float64, labels ...string)

SetYTicks fixes the y tick locations and, when labels are given, their labels.

func (*Axes) Text

func (a *Axes) Text(x, y float64, s string, opts ...Option)

Text writes s at (x, y) in data coordinates, as matplotlib's ax.text: 10 points, black, left-aligned on its baseline, not clipped. s may contain TeX math between dollar signs.

Options: FontSize, Color, Alpha, HA, VA, Rotation, ZOrder.

func (*Axes) TwinX

func (a *Axes) TwinX() *Axes

TwinX returns a new Axes sharing this one's x axis, with its y axis on the right, as matplotlib's ax.twinx() does. It has its own colour cycle, which starts again at C0, as in matplotlib.

func (*Axes) XLim

func (a *Axes) XLim() (float64, float64)

XLim returns the x view limits as of the last draw (or as set).

func (*Axes) YLim

func (a *Axes) YLim() (float64, float64)

YLim returns the y view limits as of the last draw (or as set).

type FigOption

type FigOption func(*Figure)

A FigOption configures a new Figure.

func DPI

func DPI(d float64) FigOption

DPI sets the resolution in pixels per inch (default 100).

func FigSize

func FigSize(w, h float64) FigOption

FigSize sets the figure size in inches (matplotlib's figsize; default 6.4 x 4.8).

type Figure

type Figure struct {
	// Width and Height are in inches; DPI is pixels per inch. The pixel size
	// is Width*DPI x Height*DPI, rounded as matplotlib rounds it.
	Width, Height, DPI float64
	// Facecolor is the background; white by default.
	Facecolor colors.RGBA
	// Text lays out every string in the figure. The default sets text in
	// DejaVu Sans and TeX math with go-tex/math; replace it to change fonts.
	Text text.Renderer
	// SubplotParams place the grids made by Subplots; TightLayout sets them.
	SubplotParams SubplotParams
	// contains filtered or unexported fields
}

Figure is the whole drawing: a size, a resolution, a background and the Axes on it.

func NewFigure

func NewFigure(opts ...FigOption) *Figure

NewFigure returns an empty figure with matplotlib's defaults: 6.4 x 4.8 inches at 100 dpi on white.

func Subplots

func Subplots(rows, cols int, opts ...FigOption) (*Figure, [][]*Axes)

Subplots returns a new figure with a rows x cols grid of Axes, as matplotlib's plt.subplots does; axs[i][j] is row i, column j.

func (*Figure) AddAxes

func (f *Figure) AddAxes(left, bottom, width, height float64) *Axes

AddAxes adds an Axes at [left, bottom, width, height] in figure fractions, as matplotlib's fig.add_axes does.

func (*Figure) Axes

func (f *Figure) Axes() []*Axes

Axes returns the figure's Axes in the order they were added.

func (*Figure) Colorbar

func (f *Figure) Colorbar(m *Mappable, ax *Axes) *Axes

Colorbar adds a colour scale for m beside ax, taking its space from ax as matplotlib's fig.colorbar(m, ax=ax) does: 15% of the width, a 5% gap, a bar 20 times as tall as wide, ticks on the right. It returns the colorbar's Axes, whose y label can be set.

func (*Figure) Display

func (f *Figure) Display() map[string][]byte

Display returns the figure in every format a notebook front end may show, keyed by MIME type: "image/svg+xml" and "image/png". It is the display contract of the go-notebook kernels, which show the richest format they support.

func (*Figure) Draw

func (f *Figure) Draw(r render.Renderer)

Draw draws the figure through r.

func (*Figure) Image

func (f *Figure) Image() *render.Raster

Image renders the figure to an RGBA raster.

func (*Figure) PixelSize

func (f *Figure) PixelSize() (w, h int)

PixelSize returns the figure size in pixels.

func (*Figure) SavePNG

func (f *Figure) SavePNG(w io.Writer) error

SavePNG writes the figure as a PNG.

func (*Figure) SaveSVG

func (f *Figure) SaveSVG(w io.Writer) error

SaveSVG writes the figure as an SVG document.

func (*Figure) Subplots

func (f *Figure) Subplots(rows, cols int) [][]*Axes

Subplots adds a rows x cols grid of Axes placed as matplotlib's GridSpec places them.

func (*Figure) TightLayout

func (f *Figure) TightLayout() bool

TightLayout moves the grid made by Subplots so that every Axes' tick labels, axis labels and title fit in the figure and do not overlap their neighbours, as matplotlib's fig.tight_layout() does: a pad of 1.08 times the font size (10 points) at the figure edges and between cells. Axes added with AddAxes are left where they are; an Axes with a colorbar counts as one cell with it.

It reports false, changing nothing, when the decorations cannot fit (or there is no grid), as matplotlib then warns and does nothing.

type Mappable

type Mappable struct {
	Cmap *colors.Colormap
	Norm colors.Norm
	// contains filtered or unexported fields
}

Mappable is what maps data values to colours — the result of Imshow, Scatter with CValues, Contour and Contourf — and what Colorbar draws.

type Option

type Option func(*props)

An Option sets one property of what a plotting method creates, as a matplotlib keyword argument does: ax.Plot(x, y, plot.Color("C1"), plot.LineStyle("--"), plot.Label("data")). Each method documents the options it honours and ignores the rest.

func Align

func Align(a string) Option

Align sets bar alignment on its coordinate: "center" (default) or "edge".

func Alpha

func Alpha(a float64) Option

Alpha sets the opacity in [0, 1].

func Arrow

func Arrow() Option

Arrow draws an arrow from an annotation's text to the point it annotates.

func Aspect

func Aspect(a string) Option

Aspect sets Imshow's aspect: "equal" (default) or "auto".

func BinEdges

func BinEdges(e ...float64) Option

BinEdges sets the histogram bin edges explicitly.

func Bins

func Bins(n int) Option

Bins sets the number of histogram bins.

func Bottom

func Bottom(b float64) Option

Bottom sets the bar baseline (left edge, for Barh).

func CValues

func CValues(v any) Option

CValues gives Scatter one value per point, mapped to colours through the colormap (matplotlib's c= with numbers). Any data Values accepts.

func CapSize

func CapSize(s float64) Option

CapSize sets error bar cap length in points.

func Clip

func Clip(on bool) Option

Clip turns clipping to the axes on or off.

func Cmap

func Cmap(name string) Option

Cmap sets the colormap by name (see colors.Names).

func Color

func Color(c string) Option

Color sets the colour: a name ("red", "C1", "tab:blue"), a hex string or a grey level, as matplotlib accepts. An invalid colour panics.

func Colors

func Colors(cs ...string) Option

Colors sets one colour per point (Scatter) or per bar (Bar).

func Density

func Density() Option

Density normalises a histogram to unit area.

func EdgeColor

func EdgeColor(c string) Option

EdgeColor sets the edge colour of patches and markers.

func ErrorColor

func ErrorColor(c string) Option

ErrorColor sets the colour of error bars (matplotlib's ecolor).

func Extent

func Extent(left, right, bottom, top float64) Option

Extent places an image: left, right, bottom, top in data coordinates.

func FaceColor

func FaceColor(c string) Option

FaceColor sets the fill colour of patches and markers.

func FontSize

func FontSize(s float64) Option

FontSize sets text size in points.

func HA

func HA(a string) Option

HA sets horizontal text alignment: "left", "center" or "right".

func Label

func Label(s string) Option

Label names the artist in the legend.

func Levels

func Levels(l ...float64) Option

Levels sets contour levels explicitly.

func LineStyle

func LineStyle(s string) Option

LineStyle sets the line style: "-", "--", "-.", ":", or "" / "None" for no line.

func LineWidth

func LineWidth(w float64) Option

LineWidth sets the line width in points.

func Loc

func Loc(s string) Option

Loc sets where Legend goes: "best" (the default: the place covering the least data, as matplotlib chooses it) or one of matplotlib's location names ("upper right", "lower center", ...).

func LogNorm

func LogNorm() Option

LogNorm maps data to the colormap on a logarithmic scale.

func Marker

func Marker(m string) Option

Marker sets the marker: "o", ".", ",", "s", "^", "v", "<", ">", "D", "d", "p", "h", "*", "+", "x", "|", "_", or "" for none.

func MarkerEdgeWidth

func MarkerEdgeWidth(w float64) Option

MarkerEdgeWidth sets the marker edge width in points.

func MarkerSize

func MarkerSize(s float64) Option

MarkerSize sets the marker size in points.

func NLevels

func NLevels(n int) Option

NLevels asks for about n contour levels (matplotlib's levels=n).

func Origin

func Origin(o string) Option

Origin sets where Imshow puts row 0: "upper" (default) or "lower".

func RGBA

func RGBA(r, g, b, a float64) Option

RGBA sets the colour from components in [0, 1].

func Rotation

func Rotation(deg float64) Option

Rotation sets text rotation in degrees, counter-clockwise.

func Sizes

func Sizes(v any) Option

Sizes gives Scatter one marker area per point, in points squared (matplotlib's s=). A single value applies to every point.

func VA

func VA(a string) Option

VA sets vertical text alignment: "top", "center", "baseline", "center_baseline" or "bottom".

func Vmax

func Vmax(v float64) Option

Vmax sets the data value mapped to the top of the colormap.

func Vmin

func Vmin(v float64) Option

Vmin sets the data value mapped to the bottom of the colormap.

func Where

func Where(mask []bool) Option

Where restricts FillBetween to the points where the mask is true.

func Width

func Width(w float64) Option

Width sets the bar width (height, for Barh) in data units.

func XErr

func XErr(v any) Option

XErr gives ErrorBar symmetric horizontal errors: one value, or one per point.

func YErr

func YErr(v any) Option

YErr gives ErrorBar symmetric vertical errors: one value, or one per point.

func ZOrder

func ZOrder(z float64) Option

ZOrder sets the drawing order: higher is drawn later.

type SubplotParams

type SubplotParams struct {
	Left, Right, Bottom, Top float64
	WSpace, HSpace           float64
}

SubplotParams are matplotlib's figure.subplot.* parameters: where the grid of Subplots sits in the figure (fractions) and the space between its cells (fractions of the average cell width and height).

Directories

Path Synopsis
Package colors parses colour specifications and maps scalars to colours the way matplotlib does: the same names, the same default property cycle (tab10), and colormaps whose lookup tables are matplotlib's own, generated from it by tools/gen_colormaps.py.
Package colors parses colour specifications and maps scalars to colours the way matplotlib does: the same names, the same default property cycle (tab10), and colormaps whose lookup tables are matplotlib's own, generated from it by tools/gen_colormaps.py.
Package contour traces iso-lines and fills iso-bands of a function sampled on a rectangular grid, by marching squares with linear interpolation along cell edges.
Package contour traces iso-lines and fills iso-bands of a function sampled on a rectangular grid, by marching squares with linear interpolation along cell edges.
Package render is the drawing seam between the figure model and its output formats.
Package render is the drawing seam between the figure model and its output formats.
Package text turns label strings into glyph outlines.
Package text turns label strings into glyph outlines.
Package ticker chooses where the ticks of an axis go and how they are labelled.
Package ticker chooses where the ticks of an axis go and how they are labelled.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL