1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package plotutil
import (
"math"
"sort"
"gonum.org/v1/plot/plotter"
)
// ErrorPoints holds a set of x, y pairs along
// with their X and Y errors.
type ErrorPoints struct {
plotter.XYs
plotter.XErrors
plotter.YErrors
}
// NewErrorPoints returns a new ErrorPoints where each
// point in the ErrorPoints is given by evaluating the
// center function on the Xs and Ys for the corresponding
// set of XY values in the pts parameter. The XError
// and YError are computed likewise, using the err
// function.
//
// This function can be useful for summarizing sets of
// scatter points using a single point and error bars for
// each element of the scatter.
func NewErrorPoints(f func([]float64) (c, l, h float64), pts ...plotter.XYer) (*ErrorPoints, error) {
c := &ErrorPoints{
XYs: make(plotter.XYs, len(pts)),
XErrors: make(plotter.XErrors, len(pts)),
YErrors: make(plotter.YErrors, len(pts)),
}
for i, xy := range pts {
xs := make([]float64, xy.Len())
ys := make([]float64, xy.Len())
for j := 0; j < xy.Len(); j++ {
xs[j], ys[j] = xy.XY(j)
if err := plotter.CheckFloats(xs[j], ys[j]); err != nil {
return nil, err
}
}
c.XYs[i].X, c.XErrors[i].Low, c.XErrors[i].High = f(xs)
if err := plotter.CheckFloats(c.XYs[i].X, c.XErrors[i].Low, c.XErrors[i].High); err != nil {
return nil, err
}
c.XYs[i].Y, c.YErrors[i].Low, c.YErrors[i].High = f(ys)
if err := plotter.CheckFloats(c.XYs[i].Y, c.YErrors[i].Low, c.YErrors[i].High); err != nil {
return nil, err
}
}
return c, nil
}
// MeanAndConf95 returns the mean
// and the magnitude of the 95% confidence
// interval on the mean as low and high
// error values.
//
// MeanAndConf95 may be used as
// the f argument to NewErrorPoints.
func MeanAndConf95(vls []float64) (mean, lowerr, higherr float64) {
n := float64(len(vls))
sum := 0.0
for _, v := range vls {
sum += v
}
mean = sum / n
sum = 0.0
for _, v := range vls {
diff := v - mean
sum += diff * diff
}
stdev := math.Sqrt(sum / n)
conf := 1.96 * stdev / math.Sqrt(n)
return mean, conf, conf
}
// MedianAndMinMax returns the median
// value and error on the median given
// by the minimum and maximum data
// values.
//
// MedianAndMinMax may be used as
// the f argument to NewErrorPoints.
func MedianAndMinMax(vls []float64) (med, lowerr, higherr float64) {
n := len(vls)
if n == 0 {
panic("plotutil: MedianAndMinMax: No values")
}
if n == 1 {
return vls[0], 0, 0
}
sort.Float64s(vls)
if n%2 == 0 {
med = (vls[n/2+1]-vls[n/2])/2 + vls[n/2]
} else {
med = vls[n/2]
}
min := vls[0]
max := vls[0]
for _, v := range vls {
min = math.Min(min, v)
max = math.Max(max, v)
}
return med, med - min, max - med
}
|