func (xyz XYZs) XY(i int) (float64, float64) {
	return xyz[i].X, xyz[i].Y
}
XY implements the XY method of the XYer interface.
package plotter  
import (
	"errors"
	"image/color"
	"math"
	"gonum.org/v1/plot/vg"
	"gonum.org/v1/plot/vg/draw"
)
var (
	DefaultLineStyle = draw.LineStyle{
		Color:    color.Black,
		Width:    vg.Points(1),
		Dashes:   []vg.Length{},
		DashOffs: 0,
	}
	DefaultGlyphStyle = draw.GlyphStyle{
		Color:  color.Black,
		Radius: vg.Points(2.5),
		Shape:  draw.RingGlyph{},
	}
)
type Valuer interface {
	Len() int
	Value(int) float64
}
func Range(vs Valuer) (min, max float64) {
	min = math.Inf(1)
	max = math.Inf(-1)
	for i := 0; i < vs.Len(); i++ {
		v := vs.Value(i)
		min = math.Min(min, v)
		max = math.Max(max, v)
	}
	return
}
type Values []float64
var (
	ErrInfinity = errors.New("Infinite data point")
	ErrNaN      = errors.New("NaN data point")
	ErrNoData   = errors.New("No data points")
)
func CheckFloats(fs ...float64) error {
	for _, f := range fs {
		switch {
		case math.IsNaN(f):
			return ErrNaN
		case math.IsInf(f, 0):
			return ErrInfinity
		}
	}
	return nil
}
func CopyValues(vs Valuer) (Values, error) {
	if vs.Len() == 0 {
		return nil, ErrNoData
	}
	cpy := make(Values, vs.Len())
	for i := 0; i < vs.Len(); i++ {
		cpy[i] = vs.Value(i)
		if err := CheckFloats(cpy[i]); err != nil {
			return nil, err
		}
	}
	return cpy, nil
}
func (vs Values) Len() int {
	return len(vs)
}
func (vs Values) Value(i int) float64 {
	return vs[i]
}
type XYer interface {
	Len() int
	XY(int) (x, y float64)
}
func XYRange(xys XYer) (xmin, xmax, ymin, ymax float64) {
	xmin, xmax = Range(XValues{xys})
	ymin, ymax = Range(YValues{xys})
	return
}
type XYs []XY
type XY struct{ X, Y float64 }
func CopyXYs(data XYer) (XYs, error) {
	cpy := make(XYs, data.Len())
	for i := range cpy {
		cpy[i].X, cpy[i].Y = data.XY(i)
		if err := CheckFloats(cpy[i].X, cpy[i].Y); err != nil {
			return nil, err
		}
	}
	return cpy, nil
}
func (xys XYs) Len() int {
	return len(xys)
}
func (xys XYs) XY(i int) (float64, float64) {
	return xys[i].X, xys[i].Y
}
type XValues struct {
	XYer
}
func (xs XValues) Value(i int) float64 {
	x, _ := xs.XY(i)
	return x
}
type YValues struct {
	XYer
}
func (ys YValues) Value(i int) float64 {
	_, y := ys.XY(i)
	return y
}
type XYZer interface {
	Len() int
	XYZ(int) (float64, float64, float64)
	XY(int) (float64, float64)
}
type XYZs []XYZ
type XYZ struct{ X, Y, Z float64 }
func (xyz XYZs) Len() int {
	return len(xyz)
}
func (xyz XYZs) XYZ(i int) (float64, float64, float64) {
	return xyz[i].X, xyz[i].Y, xyz[i].Z
}