// Example_groupedBoxPlots draws vertical boxplots. func Example_groupedBoxPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(plotter.Values, n) normal := make(plotter.Values, n) expon := make(plotter.Values, n) for i := 0; i < n; i++ { uniform[i] = rand.Float64() normal[i] = rand.NormFloat64() expon[i] = rand.ExpFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Box Plot" p.Y.Label.Text = "plotter.Values" w := vg.Points(20) for x := 0.0; x < 3.0; x++ { b0 := must(plotter.NewBoxPlot(w, x, uniform)).(*plotter.BoxPlot) b0.Offset = -w - vg.Points(3) b1 := must(plotter.NewBoxPlot(w, x, normal)).(*plotter.BoxPlot) b2 := must(plotter.NewBoxPlot(w, x, expon)).(*plotter.BoxPlot) b2.Offset = w + vg.Points(3) p.Add(b0, b1, b2) } // Set the X axis of the plot to nominal with // the given names for x=0, x=1 and x=2. p.NominalX("Group 0", "Group 1", "Group 2") return p }
// Example_boxPlots draws vertical boxplots. func Example_boxPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(plotter.Values, n) normal := make(plotter.Values, n) expon := make(plotter.Values, n) for i := 0; i < n; i++ { uniform[i] = rand.Float64() normal[i] = rand.NormFloat64() expon[i] = rand.ExpFloat64() } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Box Plot" p.Y.Label.Text = "plotter.Values" // Make boxes for our data and add them to the plot. p.Add(must(plotter.NewBoxPlot(vg.Points(20), 0, uniform)).(*plotter.BoxPlot), must(plotter.NewBoxPlot(vg.Points(20), 1, normal)).(*plotter.BoxPlot), must(plotter.NewBoxPlot(vg.Points(20), 2, expon)).(*plotter.BoxPlot)) // Set the X axis of the plot to nominal with // the given names for x=0, x=1 and x=2. p.NominalX("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") return p }
// Example_horizontalBoxPlots draws horizontal boxplots // with some labels on their points. func Example_horizontalBoxPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(valueLabels, n) normal := make(valueLabels, n) expon := make(valueLabels, n) for i := 0; i < n; i++ { uniform[i].Value = rand.Float64() uniform[i].Label = fmt.Sprintf("%4.4f", uniform[i].Value) normal[i].Value = rand.NormFloat64() normal[i].Label = fmt.Sprintf("%4.4f", normal[i].Value) expon[i].Value = rand.ExpFloat64() expon[i].Label = fmt.Sprintf("%4.4f", expon[i].Value) } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Horizontal Box Plot" p.X.Label.Text = "plotter.Values" // Make boxes for our data and add them to the plot. uniBox := plotter.HorizBoxPlot{plotter.NewBoxPlot(vg.Points(20), 0, uniform)} uniLabels, err := uniBox.OutsideLabels(uniform) if err != nil { panic(err) } normBox := plotter.HorizBoxPlot{plotter.NewBoxPlot(vg.Points(20), 1, normal)} normLabels, err := normBox.OutsideLabels(normal) if err != nil { panic(err) } expBox := plotter.HorizBoxPlot{plotter.NewBoxPlot(vg.Points(20), 2, expon)} expLabels, err := expBox.OutsideLabels(expon) if err != nil { panic(err) } p.Add(uniBox, uniLabels, normBox, normLabels, expBox, expLabels) // Add a GlyphBox plotter for debugging. p.Add(plotter.NewGlyphBoxes()) // Set the Y axis of the plot to nominal with // the given names for y=0, y=1 and y=2. p.NominalY("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") return p }
// Example_verticalBoxPlots draws vertical boxplots // with some labels on their points. func Example_verticalBoxPlots() *plot.Plot { rand.Seed(int64(0)) n := 100 uniform := make(valueLabels, n) normal := make(valueLabels, n) expon := make(valueLabels, n) for i := 0; i < n; i++ { uniform[i].Value = rand.Float64() uniform[i].Label = fmt.Sprintf("%4.4f", uniform[i].Value) normal[i].Value = rand.NormFloat64() normal[i].Label = fmt.Sprintf("%4.4f", normal[i].Value) expon[i].Value = rand.ExpFloat64() expon[i].Label = fmt.Sprintf("%4.4f", expon[i].Value) } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Box Plot" p.Y.Label.Text = "plotter.Values" // Make boxes for our data and add them to the plot. uniBox := must(plotter.NewBoxPlot(vg.Points(20), 0, uniform)).(*plotter.BoxPlot) uniLabels, err := uniBox.OutsideLabels(uniform) if err != nil { panic(err) } normBox := must(plotter.NewBoxPlot(vg.Points(20), 1, normal)).(*plotter.BoxPlot) normLabels, err := normBox.OutsideLabels(normal) if err != nil { panic(err) } expBox := must(plotter.NewBoxPlot(vg.Points(20), 2, expon)).(*plotter.BoxPlot) expLabels, err := expBox.OutsideLabels(expon) if err != nil { panic(err) } p.Add(uniBox, uniLabels, normBox, normLabels, expBox, expLabels) // Set the X axis of the plot to nominal with // the given names for x=0, x=1 and x=2. p.NominalX("Uniform\nDistribution", "Normal\nDistribution", "Exponential\nDistribution") return p }
// AddBoxPlots adds box plot plotters to a plot and // sets the X axis of the plot to be nominal. // The variadic arguments must be either strings // or plotter.Valuers. Each valuer adds a box plot // to the plot at the X location corresponding to // the number of box plots added before it. If a // plotter.Valuer is immediately preceeded by a // string then the string value is used to label the // tick mark for the box plot's X location. // // If an error occurs then none of the plotters are added // to the plot, and the error is returned. func AddBoxPlots(plt *plot.Plot, width vg.Length, vs ...interface{}) error { var ps []plot.Plotter var names []string name := "" for _, v := range vs { switch t := v.(type) { case string: name = t case plotter.Valuer: b, err := plotter.NewBoxPlot(width, float64(len(names)), t) if err != nil { return err } ps = append(ps, b) names = append(names, name) name = "" default: panic(fmt.Sprintf("AddScatters handles strings and plotter.XYers, got %T", t)) } } plt.Add(ps...) plt.NominalX(names...) return nil }
func boxplot(path string, sets []set) error { var ( fiveEnds = make([]plotter.Values, len(sets)) threeEnds = make([]plotter.Values, len(sets)) err error ln int ) for i := range sets { fiveEnds[i], err = plotter.CopyValues(&normalised{vals: sets[i].fiveEnd}) if err != nil { return err } threeEnds[i], err = plotter.CopyValues(&normalised{vals: sets[i].threeEnd}) if err != nil { return err } if i == 0 { ln = fiveEnds[i].Len() } if fiveEnds[i].Len() != threeEnds[i].Len() || fiveEnds[i].Len() != ln { return errors.New("missing values") } } font, err := vg.MakeFont("Helvetica", 10) if err != nil { return err } titleFont, err := vg.MakeFont("Helvetica", 12) if err != nil { return err } style := plot.TextStyle{Color: color.Gray{0}, Font: font} p, err := plot.New() if err != nil { return err } p.Title.Text = titles[filter] p.Title.TextStyle = plot.TextStyle{Color: color.Gray{0}, Font: titleFont} p.X.Label.Text = "Length Offset" p.Y.Label.Text = "Relative Frequency" p.X.Label.TextStyle = style p.Y.Label.TextStyle = style p.X.Tick.Label = style p.Y.Tick.Label = style p.Legend.TextStyle = style type boxPair struct{ five, three *plotter.BoxPlot } var boxes []boxPair for i := 0; i < ln; i++ { fiveEnd := make(plotter.Values, len(sets)) threeEnd := make(plotter.Values, len(sets)) for j := range sets { fiveEnd[j] = fiveEnds[j][i] threeEnd[j] = threeEnds[j][i] } boxFivePrime, err := plotter.NewBoxPlot(1, float64(i), fiveEnd) // A non-zero width is required to prevent the creation failing. if err != nil { return err } boxFivePrime.MedianStyle.Width = 0.5 boxFivePrime.BoxStyle.Width = 0.75 boxFivePrime.BoxStyle.Color = plotutil.Color(0) boxThreePrime, err := plotter.NewBoxPlot(1, float64(i), threeEnd) // A non-zero width is required to prevent the creation failing. if err != nil { return err } boxThreePrime.MedianStyle.Width = 0.5 boxThreePrime.BoxStyle.Width = 0.75 boxThreePrime.BoxStyle.Color = plotutil.Color(1) boxes = append(boxes, boxPair{boxFivePrime, boxThreePrime}) p.Add(boxFivePrime, boxThreePrime) } p.Legend.Add("5'-end", &plotter.BarChart{Color: plotutil.Color(0)}) p.Legend.Add("3'-end", &plotter.BarChart{Color: plotutil.Color(1)}) p.Legend.Top = true p.NominalX(func() []string { n := make([]string, ln) for i := 0; i < ln; i++ { if v := i - maxLength; v%5 == 0 { n[i] = fmt.Sprint(v) } } return n }()...) p.X.Width = 0.5 p.X.Tick.Width = 0.5 p.X.Tick.Length = 8 p.Add(&plotter.Grid{Vertical: plotter.DefaultGridLineStyle}) c := vgsvg.New(vg.Centimeters(19), vg.Centimeters(10)) da := plot.MakeDrawArea(c) trX, _ := p.Transforms(&da) w := ((trX(float64(2*maxLength)) - trX(float64(0))) / vg.Length(2*maxLength)) / 3 for _, b := range boxes { b.five.Width = w b.five.Offset = -w / 2 b.three.Width = w b.three.Offset = w / 2 } p.Draw(da) f, err := os.Create(decorate(path, "boxplot.svg", filter)) if err != nil { return err } defer f.Close() _, err = c.WriteTo(f) return err }