func (l *Labels) GlyphBoxes(p *plot.Plot) []plot.GlyphBox {
	bs := make([]plot.GlyphBox, len(l.Labels))
	for i, label := range l.Labels {
		bs[i].X = p.X.Norm(l.XYs[i].X)
		bs[i].Y = p.Y.Norm(l.XYs[i].Y)
		sty := l.TextStyle[i]
		bs[i].Rectangle = sty.Rectangle(label)
	}
	return bs
}
GlyphBoxes returns a slice of GlyphBoxes,
one for each of the labels, implementing the
plot.GlyphBoxer interface.
package plotter
import (
	"errors"
	"gonum.org/v1/plot"
	"gonum.org/v1/plot/vg"
	"gonum.org/v1/plot/vg/draw"
)
var (
	DefaultFont = plot.DefaultFont
	DefaultFontSize = vg.Points(10)
)
type Labels struct {
	XYs
	Labels []string
	TextStyle []draw.TextStyle
	XOffset, YOffset vg.Length
}
func NewLabels(d XYLabeller) (*Labels, error) {
	xys, err := CopyXYs(d)
	if err != nil {
		return nil, err
	}
	if d.Len() != len(xys) {
		return nil, errors.New("Number of points does not match the number of labels")
	}
	strs := make([]string, d.Len())
	for i := range strs {
		strs[i] = d.Label(i)
	}
	fnt, err := vg.MakeFont(DefaultFont, DefaultFontSize)
	if err != nil {
		return nil, err
	}
	styles := make([]draw.TextStyle, d.Len())
	for i := range styles {
		styles[i] = draw.TextStyle{Font: fnt}
	}
	return &Labels{
		XYs:       xys,
		Labels:    strs,
		TextStyle: styles,
	}, nil
}
func (l *Labels) Plot(c draw.Canvas, p *plot.Plot) {
	trX, trY := p.Transforms(&c)
	for i, label := range l.Labels {
		pt := vg.Point{X: trX(l.XYs[i].X), Y: trY(l.XYs[i].Y)}
		if !c.Contains(pt) {
			continue
		}
		pt.X += l.XOffset
		pt.Y += l.YOffset
		c.FillText(l.TextStyle[i], pt, label)
	}
}
func (l *Labels) DataRange() (xmin, xmax, ymin, ymax float64) {
	return XYRange(l)
}