Skip to content

Drawing to an Image or Writer: How to save a plot to an image.Image or an io.Writer, not a file.

Sebastien Binet edited this page Jul 29, 2020 · 5 revisions

Plot.Save() makes it easy to save a plot to a file. However, often one wants to plot directly to an image.Image or an io.Writer. This is possible. The trick is to create your own draw.Canvas. The following examples illustrate.

Drawing to an image.Image

package main

import (
	"image"
	"image/png"
	"os"

	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg/draw"
	"gonum.org/v1/plot/vg/vgimg"
)

const dpi = 96

func main() {
	p, err := plot.New()
	if err != nil {
		panic(err)
	}
	l, err := plotter.NewLine(plotter.XYs{{0, 0}, {1, 1}, {2, 2}})
	if err != nil {
		panic(err)
	}
	p.Add(l)

	// Draw the plot to an in-memory image.
	img := image.NewRGBA(image.Rect(0, 0, 3*dpi, 3*dpi))
	c := vgimg.NewWith(vgimg.UseImage(img))
	p.Draw(draw.New(c))

	// Save the image.
	f, err := os.Create("test.png")
	if err != nil {
		panic(err)
	}
	if err := png.Encode(f, c.Image()); err != nil {
		panic(err)
	}
	if err := f.Close(); err != nil {
		panic(err)
	}
}

Writing a plot to an io.Writer

package main

import (
	"os"

	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"
	"gonum.org/v1/plot/vg/draw"
	"gonum.org/v1/plot/vg/vgsvg"
)

const dpi = 96

func main() {
	p, err := plot.New()
	if err != nil {
		panic(err)
	}
	l, err := plotter.NewLine(plotter.XYs{{0, 0}, {1, 1}, {2, 2}})
	if err != nil {
		panic(err)
	}
	p.Add(l)

	// Create a Canvas for writing SVG images.
	c := vgsvg.New(3*vg.Inch, 3*vg.Inch)

	// Draw to the Canvas.
	p.Draw(draw.New(c))

	// Write the Canvas to a io.Writer (in this case, os.Stdout).
	if _, err := c.WriteTo(os.Stdout); err != nil {
		panic(err)
	}
}