func AddLinePointsWithColor(plt *plot.Plot, i int, vs ...interface{}) error { var ps []plot.Plotter names := make(map[[2]plot.Thumbnailer]string) name := "" for _, v := range vs { switch t := v.(type) { case string: name = t case plotter.XYer: l, s, err := plotter.NewLinePoints(t) if err != nil { return err } l.Color = plotutil.Color(i) l.Dashes = plotutil.Dashes(i) s.Color = plotutil.Color(i) s.Shape = plotutil.Shape(i) ps = append(ps, l, s) if name != "" { names[[2]plot.Thumbnailer{l, s}] = name name = "" } default: panic(fmt.Sprintf("AddLinePointsWithColor handles strings and plotter.XYers, got %T", t)) } } plt.Add(ps...) for ps, n := range names { plt.Legend.Add(n, ps[0], ps[1]) } return nil }
// Example_points draws some scatter points, a line, // and a line with points. func Example_points() *plot.Plot { rand.Seed(int64(0)) n := 15 scatterData := randomPoints(n) lineData := randomPoints(n) linePointsData := randomPoints(n) p, err := plot.New() if err != nil { panic(err) } p.Title.Text = "Points Example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" p.Add(plotter.NewGrid()) s := must(plotter.NewScatter(scatterData)).(*plotter.Scatter) s.GlyphStyle.Color = color.RGBA{R: 255, B: 128, A: 255} s.GlyphStyle.Radius = vg.Points(3) l := must(plotter.NewLine(lineData)).(*plotter.Line) l.LineStyle.Width = vg.Points(1) l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)} l.LineStyle.Color = color.RGBA{B: 255, A: 255} lpLine, lpPoints, err := plotter.NewLinePoints(linePointsData) if err != nil { panic(err) } lpLine.Color = color.RGBA{G: 255, A: 255} lpPoints.Shape = draw.CircleGlyph{} lpPoints.Color = color.RGBA{R: 255, A: 255} p.Add(s, l, lpLine, lpPoints) p.Legend.Add("scatter", s) p.Legend.Add("line", l) p.Legend.Add("line points", lpLine, lpPoints) return p }
func (g *Graph) Save(filename string, w, h int) error { g.Plot.Add(plotter.NewGrid()) for _, c := range g.Curves { lpLine, lpPoints, err := plotter.NewLinePoints(c.Points) if err != nil { return err } if len(c.RGB) != 3 { return errors.New("bad RGB") } color := color.RGBA{R: c.RGB[0], G: c.RGB[1], B: c.RGB[2], A: 255} lpLine.LineStyle.Color = color lpPoints.Color = color g.Plot.Add(lpLine, lpPoints) if c.Name != "" { g.Plot.Legend.Add(c.Name, lpLine, lpPoints) } } return g.Plot.Save(vg.Length(w), vg.Length(h), filename) }
func (p *chartPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if service.IsMe(message) { return } if bruxism.MatchesCommand(service, "chart", message) { query, parts := bruxism.ParseCommand(service, message) if len(parts) == 0 { service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart eg: %s", p.randomChart(service))) return } start, end := 0.5, 0.5 switch parts[0] { case "up": start, end = 0, 1 case "down": start, end = 1, 0 case "flat": case "straight": default: service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart direction. eg: %s", p.randomChart(service))) return } axes := strings.Split(query[len(parts[0]):], ",") if len(axes) != 2 { service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart axis labels eg: %s", p.randomChart(service))) return } pl, err := plot.New() if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Error making chart, sorry! eg: %s", p.randomChart(service))) return } service.Typing(message.Channel()) pl.Y.Label.Text = axes[0] pl.X.Label.Text = axes[1] num := 5 + rand.Intn(15) start *= float64(num) end *= float64(num) pts := make(plotter.XYs, num) for i := range pts { pts[i].X = float64(i) + rand.Float64()*0.5 - 0.2 pts[i].Y = start + float64(end-start)/float64(num-1)*float64(i) + rand.Float64()*0.5 - 0.25 } pl.X.Tick.Label.Color = color.Transparent pl.Y.Tick.Label.Color = color.Transparent pl.X.Min = -0.5 pl.X.Max = float64(num) + 0.5 pl.Y.Min = -0.5 pl.Y.Max = float64(num) + 0.5 lpLine, lpPoints, err := plotter.NewLinePoints(pts) if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your chart.", message.UserName())) } lpLine.Color = plotutil.Color(rand.Int()) lpLine.Width = vg.Points(1 + 0.5*rand.Float64()) lpLine.Dashes = plotutil.Dashes(rand.Int()) lpPoints.Shape = plotutil.Shape(rand.Int()) lpPoints.Color = lpLine.Color pl.Add(lpLine, lpPoints) w, err := pl.WriterTo(320, 240, "png") if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your chart.", message.UserName())) return } b := &bytes.Buffer{} w.WriteTo(b) go func() { if service.Name() == bruxism.DiscordServiceName { discord := service.(*bruxism.Discord) p, err := discord.UserChannelPermissions(message.UserID(), message.Channel()) if err == nil && p&discordgo.PermissionAttachFiles != 0 { service.SendFile(message.Channel(), "chart.png", b) return } } url, err := bot.UploadToImgur(b, "chart.png") if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem uploading the chart to imgur.", message.UserName())) log.Println("Error uploading chart: ", err) return } if service.Name() == bruxism.DiscordServiceName { service.SendMessage(message.Channel(), fmt.Sprintf("Here's your chart <@%s>: %s", message.UserID(), url)) } else { service.SendMessage(message.Channel(), fmt.Sprintf("Here's your chart %s: %s", message.UserName(), url)) } }() } }
func TestPersistency(t *testing.T) { // Get some random points rand.Seed(0) // The default random seed is 1. n := 15 scatterData := randomPoints(n) lineData := randomPoints(n) linePointsData := randomPoints(n) p, err := plot.New() if err != nil { t.Fatalf("error creating plot: %v\n", err) } p.Title.Text = "Plot Example" p.X.Label.Text = "X" p.Y.Label.Text = "Y" // Use a custom tick marker function that computes the default // tick marks and re-labels the major ticks with commas. p.Y.Tick.Marker = commaTicks{} // Draw a grid behind the data p.Add(plotter.NewGrid()) // Make a scatter plotter and set its style. s, err := plotter.NewScatter(scatterData) if err != nil { panic(err) } s.GlyphStyle.Color = color.RGBA{R: 255, B: 128, A: 255} // Make a line plotter and set its style. l, err := plotter.NewLine(lineData) if err != nil { panic(err) } l.LineStyle.Width = vg.Points(1) l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)} l.LineStyle.Color = color.RGBA{B: 255, A: 255} // Make a line plotter with points and set its style. lpLine, lpPoints, err := plotter.NewLinePoints(linePointsData) if err != nil { panic(err) } lpLine.Color = color.RGBA{G: 255, A: 255} lpPoints.Shape = draw.PyramidGlyph{} lpPoints.Color = color.RGBA{R: 255, A: 255} // Add the plotters to the plot, with a legend // entry for each p.Add(s, l, lpLine, lpPoints) p.Legend.Add("scatter", s) p.Legend.Add("line", l) p.Legend.Add("line points", lpLine, lpPoints) // Save the plot to a PNG file. err = p.Save(4, 4, "test-persistency.png") if err != nil { t.Fatalf("error saving to PNG: %v\n", err) } defer os.Remove("test-persistency.png") buf := new(bytes.Buffer) enc := gob.NewEncoder(buf) err = enc.Encode(p) if err != nil { t.Fatalf("error gob-encoding plot: %v\n", err) } // TODO(sbinet): impl. BinaryMarshal for plot.Plot and vg.Font // { // dec := gob.NewDecoder(buf) // var p plot.Plot // err = dec.Decode(&p) // if err != nil { // t.Fatalf("error gob-decoding plot: %v\n", err) // } // // Save the plot to a PNG file. // err = p.Save(4, 4, "test-persistency-readback.png") // if err != nil { // t.Fatalf("error saving to PNG: %v\n", err) // } // defer os.Remove("test-persistency-readback.png") // } }