gonum / plot

A repository for plotting and visualizing data
BSD 3-Clause "New" or "Revised" License
2.74k stars 203 forks source link

Unable to generate different style for projected forecasted-data vs the original-data #726

Closed mozhi-bateman closed 3 years ago

mozhi-bateman commented 3 years ago

I am trying to generate a graph with the data that has two characteristics.

  1. Data that is available and real ( stored in the backend based on user's past historical actions )
  2. And projected data into future ( which is forecasted ) based on past history ( predicted data )

My intent was to generate plot something like below, where orange color depicts original data and dotted blue line depicts forecasted data. I tried plotting with custom styles but couldn't get to solve it.

image

sbinet commented 3 years ago

I suspect this can be easily achieved with, say, 2 plotter.Lines :

package main

import (
    "image/color"
    "log"

    "golang.org/x/exp/rand"
    "gonum.org/v1/plot"
    "gonum.org/v1/plot/plotter"
    "gonum.org/v1/plot/vg"
)

func main() {
    rnd := rand.New(rand.NewSource(1))

    // randomPoints returns some random x, y points
    // with some interesting kind of trend.
    randomPoints := func(n int, x float64) plotter.XYs {
        pts := make(plotter.XYs, n)
        for i := range pts {
            pts[i].X = float64(i) + x
            pts[i].Y = 2*(float64(i)+x) + 3 + 10*rnd.Float64()
        }
        return pts
    }

    n := 100

    p := plot.New()
    p.Title.Text = "Data + Prediction"
    p.X.Label.Text = "X"
    p.Y.Label.Text = "Y"
    p.X.Min = 0
    p.X.Max = 100

    pts := randomPoints(n, 0)
    data, err := plotter.NewLine(pts[:80+1])
    if err != nil {
        log.Panic(err)
    }
    data.LineStyle.Color = color.RGBA{R: 255, A: 255}

    pred, err := plotter.NewLine(pts[80:])
    if err != nil {
        log.Panic(err)
    }
    pred.LineStyle.Color = color.RGBA{B: 255, A: 255}
    pred.LineStyle.Dashes = []vg.Length{1, 2, 1}

    p.Add(data, pred)
    p.Add(plotter.NewGrid())
    p.Legend.Add("data", data)
    p.Legend.Add("prediction", pred)

    err = p.Save(15*vg.Centimeter, 10*vg.Centimeter, "ooo.png")
    if err != nil {
        log.Fatal(err)
    }
}

ooo

sbinet commented 3 years ago

I guess the "thumb up" means this issue can be closed :) (feel free to reopen otherwise)