hep: go-hep.org/x/hep/hplot Index | Examples | Files | Directories

package hplot

import "go-hep.org/x/hep/hplot"

Package hplot is a package to plot histograms, n-tuples and functions

Code:


const npoints = 10000

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

hist1 := hbook.NewH1D(20, -4, +4)
hist2 := hbook.NewH1D(20, -4, +4)

for i := 0; i < npoints; i++ {
    v1 := dist.Rand()
    v2 := dist.Rand() + 0.5
    hist1.Fill(v1, 1)
    hist2.Fill(v2, 1)
}

// Make a plot and set its title.
p1 := hplot.New()
p1.Title.Text = "Histos"
p1.Y.Label.Text = "Y"

// Create a histogram of our values drawn
// from the standard normal.
h1 := hplot.NewH1D(hist1)
h1.LineStyle.Color = color.RGBA{R: 255, A: 255}
h1.FillColor = nil
p1.Add(h1)

h2 := hplot.NewH1D(hist2)
h2.LineStyle.Color = color.RGBA{B: 255, A: 255}
h2.FillColor = nil
p1.Add(h2)

// hide X-axis labels
p1.X.Tick.Marker = hplot.NoTicks{}

p1.Add(hplot.NewGrid())

hist3 := hbook.NewH1D(20, -4, +4)
for i := 0; i < hist3.Len(); i++ {
    v1 := hist1.Value(i)
    v2 := hist2.Value(i)
    x1, _ := hist1.XY(i)
    hist3.Fill(x1, v1-v2)
}

hdiff := hplot.NewH1D(hist3)

p2 := hplot.New()
p2.X.Label.Text = "X"
p2.Y.Label.Text = "Delta-Y"
p2.Add(hdiff)
p2.Add(hplot.NewGrid())

const (
    width  = 15 * vg.Centimeter
    height = width / math.Phi
)

c := vgimg.PngCanvas{Canvas: vgimg.New(width, height)}
dc := draw.New(c)
top := draw.Canvas{
    Canvas: dc,
    Rectangle: vg.Rectangle{
        Min: vg.Point{X: 0, Y: 0.3 * height},
        Max: vg.Point{X: width, Y: height},
    },
}
p1.Draw(top)

bottom := draw.Canvas{
    Canvas: dc,
    Rectangle: vg.Rectangle{
        Min: vg.Point{X: 0, Y: 0},
        Max: vg.Point{X: width, Y: 0.3 * height},
    },
}
p2.Draw(bottom)

f, err := os.Create("testdata/diff_plot.png")
if err != nil {
    log.Fatalf("error: %v\n", err)
}
defer f.Close()
_, err = c.WriteTo(f)
if err != nil {
    log.Fatal(err)
}
err = f.Close()
if err != nil {
    log.Fatal(err)
}

Code:


const npoints = 10000

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

hist := hbook.NewH1D(20, -4, +4)
for i := 0; i < npoints; i++ {
    v := dist.Rand()
    hist.Fill(v, 1)
}

// Make a plot and set its title.
p := hplot.New()
p.Title.Text = `Gaussian distribution: $f(x) = \frac{e^{-(x - \mu)^{2}/(2\sigma^{2}) }} {\sigma\sqrt{2\pi}}$`
p.Y.Label.Text = `$f(x)$`
p.X.Label.Text = `$x$`

// Create a histogram of our values drawn
// from the standard normal.
h := hplot.NewH1D(hist)
h.LineStyle.Color = color.RGBA{R: 255, A: 255}
h.FillColor = nil
h.Infos.Style = hplot.HInfoSummary
p.Add(h)

p.Add(hplot.NewGrid())

const (
    width  = 15 * vg.Centimeter
    height = width / math.Phi
)

c := vgtex.NewDocument(width, height)
p.Draw(draw.New(c))
f, err := os.Create("testdata/latex_plot.tex")
if err != nil {
    log.Fatalf("error: %v\n", err)
}
defer f.Close()
_, err = c.WriteTo(f)
if err != nil {
    log.Fatal(err)
}
err = f.Close()
if err != nil {
    log.Fatal(err)
}

An example of a plot + sub-plot

Code:

const npoints = 10000

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

// Draw some random values from the standard
// normal distribution.
hist := hbook.NewH1D(20, -4, +4)
for i := 0; i < npoints; i++ {
    v := dist.Rand()
    hist.Fill(v, 1)
}

// normalize histo
area := 0.0
for _, bin := range hist.Binning.Bins {
    area += bin.SumW() * bin.XWidth()
}
hist.Scale(1 / area)

// Make a plot and set its title.
p1 := hplot.New()
p1.Title.Text = "Histogram"
p1.X.Label.Text = "X"
p1.Y.Label.Text = "Y"

// Create a histogram of our values drawn
// from the standard normal.
h := hplot.NewH1D(hist)
p1.Add(h)

// The normal distribution function
norm := hplot.NewFunction(dist.Prob)
norm.Color = color.RGBA{R: 255, A: 255}
norm.Width = vg.Points(2)
p1.Add(norm)

// draw a grid
p1.Add(hplot.NewGrid())

// make a second plot which will be diplayed in the upper-right
// of the previous one
p2 := hplot.New()
p2.Title.Text = "Sub plot"
p2.Add(h)
p2.Add(hplot.NewGrid())

const (
    width  = 15 * vg.Centimeter
    height = width / math.Phi
)

c := vgimg.PngCanvas{Canvas: vgimg.New(width, height)}
dc := draw.New(c)
p1.Draw(dc)
sub := draw.Canvas{
    Canvas: dc,
    Rectangle: vg.Rectangle{
        Min: vg.Point{X: 0.70 * width, Y: 0.50 * height},
        Max: vg.Point{X: 1.00 * width, Y: 1.00 * height},
    },
}
p2.Draw(sub)

f, err := os.Create("testdata/sub_plot.png")
if err != nil {
    log.Fatalf("error: %v\n", err)
}
defer f.Close()
_, err = c.WriteTo(f)
if err != nil {
    log.Fatal(err)
}
err = f.Close()
if err != nil {
    log.Fatal(err)
}

Index

Examples

Package Files

doc.go fwd.go h1d.go h2d.go hplot.go s2d.go style.go ticks.go tiledplot.go

func NewFunction Uses

func NewFunction(f func(float64) float64) *plotter.Function

NewFunction returns a Function that plots F using the default line style with 50 samples. NewFunction returns a Function that plots F using the default line style with 50 samples.

func NewGrid Uses

func NewGrid() *plotter.Grid

NewGrid returns a new grid with both vertical and horizontal lines using the default grid line style.

func NewLine Uses

func NewLine(xys plotter.XYer) (*plotter.Line, error)

NewLine returns a Line that uses the default line style and does not draw glyphs.

func NewScatter Uses

func NewScatter(xys plotter.XYer) (*plotter.Scatter, error)

NewScatter returns a Scatter that uses the default glyph style.

func Show Uses

func Show(p *Plot, w, h vg.Length, format string) ([]byte, error)

Show displays the plot according to format, returning the raw bytes and an error, if any.

If format is the empty string, then "png" is selected. The list of accepted format strings is the same one than from the gonum.org/v1/plot/vg/draw.NewFormattedCanvas function.

func ZipXY Uses

func ZipXY(x, y []float64) plotter.XYer

ZipXY zips together 2 slices x and y in such a way to implement the plotter.XYer interface.

ZipXY panics if the slices are not of the same length.

type FreqTicks Uses

type FreqTicks struct {
    N    int // number of ticks
    Freq int // frequency of labeled ticks
}

FreqTicks implements a simple plot.Ticker scheme. FreqTicks will generate N ticks where 1 every Freq tick will be labeled.

func (FreqTicks) Ticks Uses

func (ft FreqTicks) Ticks(min, max float64) []plot.Tick

Ticks returns Ticks in a specified range

type H1D Uses

type H1D struct {
    // Hist is the histogramming data
    Hist *hbook.H1D

    // FillColor is the color used to fill each
    // bar of the histogram.  If the color is nil
    // then the bars are not filled.
    FillColor color.Color

    // LineStyle is the style of the outline of each
    // bar of the histogram.
    draw.LineStyle

    // InfoStyle is the style of infos displayed for
    // the histogram (entries, mean, rms)
    Infos HInfos
}

H1D implements the plotter.Plotter interface, drawing a histogram of the data.

An example of making a 1D-histogram.

Code:

const npoints = 10000

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

// Draw some random values from the standard
// normal distribution.
hist := hbook.NewH1D(20, -4, +4)
for i := 0; i < npoints; i++ {
    v := dist.Rand()
    hist.Fill(v, 1)
}

// normalize histogram
area := 0.0
for _, bin := range hist.Binning.Bins {
    area += bin.SumW() * bin.XWidth()
}
hist.Scale(1 / area)

// Make a plot and set its title.
p := hplot.New()
p.Title.Text = "Histogram"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

// Create a histogram of our values drawn
// from the standard normal.
h := hplot.NewH1D(hist)
h.Infos.Style = hplot.HInfoSummary
p.Add(h)

// The normal distribution function
norm := hplot.NewFunction(dist.Prob)
norm.Color = color.RGBA{R: 255, A: 255}
norm.Width = vg.Points(2)
p.Add(norm)

// draw a grid
p.Add(hplot.NewGrid())

// Save the plot to a PNG file.
if err := p.Save(6*vg.Inch, -1, "testdata/h1d_plot.png"); err != nil {
    log.Fatalf("error saving plot: %v\n", err)
}

An example of making a 1D-histogram and saving to a PDF

Code:

const npoints = 10000

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

// Draw some random values from the standard
// normal distribution.
hist := hbook.NewH1D(20, -4, +4)
for i := 0; i < npoints; i++ {
    v := dist.Rand()
    hist.Fill(v, 1)
}

// normalize histogram
area := 0.0
for _, bin := range hist.Binning.Bins {
    area += bin.SumW() * bin.XWidth()
}
hist.Scale(1 / area)

// Make a plot and set its title.
p := hplot.New()
p.Title.Text = "Histogram"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

// Create a histogram of our values drawn
// from the standard normal.
h := hplot.NewH1D(hist)
h.Infos.Style = hplot.HInfoSummary
p.Add(h)

// The normal distribution function
norm := hplot.NewFunction(dist.Prob)
norm.Color = color.RGBA{R: 255, A: 255}
norm.Width = vg.Points(2)
p.Add(norm)

// draw a grid
p.Add(hplot.NewGrid())

// Save the plot to a PNG file.
if err := p.Save(6*vg.Inch, -1, "testdata/h1d_plot.pdf"); err != nil {
    log.Fatalf("error saving plot: %v\n", err)
}

func NewH1D Uses

func NewH1D(h *hbook.H1D) *H1D

NewH1D returns a new histogram, as in NewH1DFromXYer, except that it accepts a hbook.H1D instead of a plotter.XYer

func NewH1FromValuer Uses

func NewH1FromValuer(vs plotter.Valuer, n int) *H1D

NewH1FromValuer returns a new histogram, as in NewH1FromXYer, except that it accepts a plotter.Valuer instead of an XYer.

func NewH1FromXYer Uses

func NewH1FromXYer(xy plotter.XYer, n int) *H1D

NewH1FromXYer returns a new histogram that represents the distribution of values using the given number of bins.

Each y value is assumed to be the frequency count for the corresponding x.

It panics if the number of bins is non-positive.

func (*H1D) DataRange Uses

func (h *H1D) DataRange() (xmin, xmax, ymin, ymax float64)

DataRange returns the minimum and maximum X and Y values

func (*H1D) GlyphBoxes Uses

func (h *H1D) GlyphBoxes(p *plot.Plot) []plot.GlyphBox

GlyphBoxes returns a slice of GlyphBoxes, one for each of the bins, implementing the plot.GlyphBoxer interface.

func (*H1D) Plot Uses

func (h *H1D) Plot(c draw.Canvas, p *plot.Plot)

Plot implements the Plotter interface, drawing a line that connects each point in the Line.

func (*H1D) Thumbnail Uses

func (h *H1D) Thumbnail(c *draw.Canvas)

Thumbnail draws a rectangle in the given style of the histogram.

type H2D Uses

type H2D struct {
    // H is the histogramming data
    H   *hbook.H2D

    // InfoStyle is the style of infos displayed for
    // the histogram (entries, mean, rms)
    Infos HInfos

    // HeatMap implements the Plotter interface, drawing
    // a heat map of the values in the 2-d histogram.
    HeatMap *plotter.HeatMap
}

H2D implements the plotter.Plotter interface, drawing a 2-dim histogram of the data.

Code:

h := hbook.NewH2D(100, -10, 10, 100, -10, 10)

const npoints = 10000

dist, ok := distmv.NewNormal(
    []float64{0, 1},
    mat.NewSymDense(2, []float64{4, 0, 0, 2}),
    rand.New(rand.NewSource(1234)),
)
if !ok {
    log.Fatalf("error creating distmv.Normal")
}

v := make([]float64, 2)
// Draw some random values from the standard
// normal distribution.
for i := 0; i < npoints; i++ {
    v = dist.Rand(v)
    h.Fill(v[0], v[1], 1)
}

p := hplot.New()
p.Title.Text = "Hist-2D"
p.X.Label.Text = "x"
p.Y.Label.Text = "y"

p.Add(hplot.NewH2D(h, nil))
p.Add(plotter.NewGrid())
err := p.Save(10*vg.Centimeter, 10*vg.Centimeter, "testdata/h2d_plot.png")
if err != nil {
    log.Fatal(err)
}

func NewH2D Uses

func NewH2D(h *hbook.H2D, p palette.Palette) *H2D

NewH2D returns a new 2-dim histogram from a hbook.H2D.

func (*H2D) DataRange Uses

func (h *H2D) DataRange() (xmin, xmax, ymin, ymax float64)

DataRange implements the DataRange method of the plot.DataRanger interface.

func (*H2D) GlyphBoxes Uses

func (h *H2D) GlyphBoxes(p *plot.Plot) []plot.GlyphBox

GlyphBoxes returns a slice of GlyphBoxes, one for each of the bins, implementing the plot.GlyphBoxer interface.

func (*H2D) Plot Uses

func (h *H2D) Plot(c draw.Canvas, p *plot.Plot)

Plot implements the Plotter interface, drawing a line that connects each point in the Line.

type HInfoStyle Uses

type HInfoStyle uint32
const (
    HInfoNone    HInfoStyle = 0
    HInfoEntries HInfoStyle = 1 << iota
    HInfoMean
    HInfoRMS
    HInfoStdDev
    HInfoSummary HInfoStyle = HInfoEntries | HInfoMean | HInfoStdDev
)

type HInfos Uses

type HInfos struct {
    Style HInfoStyle
}

type NoTicks Uses

type NoTicks struct{}

NoTicks implements plot.Ticker but does not display any tick.

func (NoTicks) Ticks Uses

func (NoTicks) Ticks(min, max float64) []plot.Tick

Ticks returns Ticks in a specified range

type Options Uses

type Options int32

Options encodes various options to pass to a plot.

const (
    OptNone      Options = 1 << iota // default
    WithXErrBars                     // enable display of X-error bars (if available)
    WithYErrBars                     // enable display of Y-error bars (if available)
)

type Plot Uses

type Plot struct {
    *plot.Plot
    Style Style
}

Plot is the basic type representing a plot.

func New Uses

func New() *Plot

New returns a new plot with some reasonable default settings.

func (*Plot) Add Uses

func (p *Plot) Add(ps ...plot.Plotter)

Add adds a Plotters to the plot.

If the plotters implements DataRanger then the minimum and maximum values of the X and Y axes are changed if necessary to fit the range of the data.

When drawing the plot, Plotters are drawn in the order in which they were added to the plot.

func (*Plot) Save Uses

func (p *Plot) Save(w, h vg.Length, file string) (err error)

Save saves the plot to an image file. The file format is determined by the extension.

Supported extensions are:

.eps, .jpg, .jpeg, .pdf, .png, .svg, .tif and .tiff.

If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. If w and h are <= 0, the values are chosen such that they follow the Golden Ratio (the width is defaulted to vgimg.DefaultWidth).

func (*Plot) Show Uses

func (p *Plot) Show(w, h vg.Length, scr screen.Screen) (*vgshiny.Canvas, error)

Show displays the plot to the screen, with the given dimensions.

If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. If w and h are <= 0, the values are chosen such that they follow the Golden Ratio (the width is defaulted to vgimg.DefaultWidth).

type S2D Uses

type S2D struct {
    Data plotter.XYer

    // GlyphStyle is the style of the glyphs drawn
    // at each point.
    draw.GlyphStyle
    // contains filtered or unexported fields
}

S2D plots a set of 2-dim points with error bars.

ExampleS2D draws some scatter points.

Code:

const npoints = 1000

dist, ok := distmv.NewNormal(
    []float64{0, 1},
    mat.NewSymDense(2, []float64{4, 0, 0, 2}),
    rand.New(rand.NewSource(1234)),
)
if !ok {
    log.Fatalf("error creating distmv.Normal")
}

s2d := hbook.NewS2D()

v := make([]float64, 2)
// Draw some random values from the standard
// normal distribution.
for i := 0; i < npoints; i++ {
    v = dist.Rand(v)
    s2d.Fill(hbook.Point2D{X: v[0], Y: v[1]})
}

p := hplot.New()
p.Title.Text = "Scatter-2D"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"
p.Add(plotter.NewGrid())

s := hplot.NewS2D(s2d)
s.GlyphStyle.Color = color.RGBA{R: 255, A: 255}
s.GlyphStyle.Radius = vg.Points(2)

p.Add(s)

err := p.Save(10*vg.Centimeter, 10*vg.Centimeter, "testdata/s2d.png")
if err != nil {
    log.Fatal(err)
}

ExampleS2D_withErrorBars draws some scatter points with their error bars.

Code:

pts := []hbook.Point2D{
    {X: 1, Y: 1, ErrX: hbook.Range{Min: 0.5, Max: 0.5}, ErrY: hbook.Range{Min: 2, Max: 3}},
    {X: 2, Y: 2, ErrX: hbook.Range{Min: 0.5, Max: 1.5}, ErrY: hbook.Range{Min: 5, Max: 2}},
}
s2d := hbook.NewS2D(pts...)

p := hplot.New()
p.Title.Text = "Scatter-2D (with error bars)"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"
p.Add(plotter.NewGrid())

s := hplot.NewS2D(s2d, hplot.WithXErrBars|hplot.WithYErrBars)
s.GlyphStyle.Color = color.RGBA{R: 255, A: 255}
s.GlyphStyle.Radius = vg.Points(4)

p.Add(s)

err := p.Save(10*vg.Centimeter, 10*vg.Centimeter, "testdata/s2d_errbars.png")
if err != nil {
    log.Fatal(err)
}

func NewS2D Uses

func NewS2D(data plotter.XYer, opts ...Options) *S2D

NewS2D creates a 2-dim scatter plot from a XYer.

func (*S2D) DataRange Uses

func (pts *S2D) DataRange() (xmin, xmax, ymin, ymax float64)

DataRange returns the minimum and maximum x and y values, implementing the plot.DataRanger interface.

func (*S2D) GlyphBoxes Uses

func (pts *S2D) GlyphBoxes(plt *plot.Plot) []plot.GlyphBox

GlyphBoxes returns a slice of plot.GlyphBoxes, implementing the plot.GlyphBoxer interface.

func (*S2D) Plot Uses

func (pts *S2D) Plot(c draw.Canvas, plt *plot.Plot)

Plot draws the Scatter, implementing the plot.Plotter interface.

func (*S2D) Thumbnail Uses

func (pts *S2D) Thumbnail(c *draw.Canvas)

Thumbnail the thumbnail for the Scatter, implementing the plot.Thumbnailer interface.

type Style Uses

type Style struct {
    Fonts struct {
        Name   string  // font name of this style
        Title  vg.Font // font used for the plot title
        Label  vg.Font // font used for the plot labels
        Legend vg.Font // font used for the plot legend
        Tick   vg.Font // font used for the plot's axes' ticks
    }
}

Style stores a given plot style.

var (
    // DefaultStyle is the default style used for hplot plots.
    DefaultStyle Style
)

func NewStyle Uses

func NewStyle(name string, ft *truetype.Font) (Style, error)

NewStyle creates a new style with the given truetype font.

func (*Style) Apply Uses

func (s *Style) Apply(p *Plot)

Apply setups the plot p with the current style.

type TiledPlot Uses

type TiledPlot struct {
    Plots []*Plot
    Tiles draw.Tiles
}

TiledPlot is a regularly spaced set of plots, aranged as tiles.

An example of making a tile-plot

Code:

tp := hplot.NewTiledPlot(draw.Tiles{Cols: 3, Rows: 2})

// Create a normal distribution.
dist := distuv.Normal{
    Mu:    0,
    Sigma: 1,
    Src:   rand.New(rand.NewSource(0)),
}

newHist := func(p *hplot.Plot) {
    const npoints = 10000
    hist := hbook.NewH1D(20, -4, +4)
    for i := 0; i < npoints; i++ {
        v := dist.Rand()
        hist.Fill(v, 1)
    }

    h := hplot.NewH1D(hist)
    p.Add(h)
}

for i := 0; i < tp.Tiles.Rows; i++ {
    for j := 0; j < tp.Tiles.Cols; j++ {
        p := tp.Plot(i, j)
        p.X.Min = -5
        p.X.Max = +5
        newHist(p)
        p.Title.Text = fmt.Sprintf("hist - (%02d, %02d)", i, j)
    }
}

// remove plot at (0,1)
tp.Plots[1] = nil

err := tp.Save(15*vg.Centimeter, -1, "testdata/tiled_plot_histogram.png")
if err != nil {
    t.Fatalf("error: %v\n", err)
}

func NewTiledPlot Uses

func NewTiledPlot(tiles draw.Tiles) *TiledPlot

NewTiledPlot creates a new set of plots aranged as tiles. By default, NewTiledPlot will put a 1 vg.Length space between each plot.

func (*TiledPlot) Draw Uses

func (tp *TiledPlot) Draw(c draw.Canvas)

Draw draws the tiled plot to a draw.Canvas.

Each non-nil plot.Plot in the aranged set of tiled plots is drawn inside its dedicated sub-canvas, using hplot.Plot.Draw.

func (*TiledPlot) Plot Uses

func (tp *TiledPlot) Plot(i, j int) *Plot

Plot returns the plot at the i-th column and j-th row in the set of tiles. (0,0) is at the top-left of the set of tiles.

func (*TiledPlot) Save Uses

func (tp *TiledPlot) Save(w, h vg.Length, file string) (err error)

Save saves the plots to an image file. The file format is determined by the extension.

Supported extensions are the same ones than hplot.Plot.Save.

If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. If w and h are <= 0, the values are chosen such that they follow the Golden Ratio (the width is defaulted to vgimg.DefaultWidth).

func (*TiledPlot) Show Uses

func (tp *TiledPlot) Show(w, h vg.Length, scr screen.Screen) (*vgshiny.Canvas, error)

Show displays the plots to the screen, with the given dimensions.

If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. If w and h are <= 0, the values are chosen such that they follow the Golden Ratio (the width is defaulted to vgimg.DefaultWidth).

func (*TiledPlot) WriterTo Uses

func (tp *TiledPlot) WriterTo(w, h vg.Length, format string) (io.WriterTo, error)

WriterTo returns an io.WriterTo that will write the plots as the specified image format.

Supported formats are the same ones than hplot.Plot.WriterTo

If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. If w and h are <= 0, the values are chosen such that they follow the Golden Ratio (the width is defaulted to vgimg.DefaultWidth).

Directories

PathSynopsis
cmd/hplothplot is a simple gnuplot-like command to create plots
cmd/iplot

Package hplot imports 23 packages (graph) and is imported by 22 packages. Updated 2019-03-12. Refresh now. Tools for package owners.