// NewFormattedCanvas creates a new vg.CanvasWriterTo with the specified // image format. // // Supported formats are: // // eps, jpg|jpeg, pdf, png, svg, and tif|tiff. func NewFormattedCanvas(w, h vg.Length, format string) (vg.CanvasWriterTo, error) { var c vg.CanvasWriterTo switch format { case "eps": c = vgeps.New(w, h) case "jpg", "jpeg": c = vgimg.JpegCanvas{Canvas: vgimg.New(w, h)} case "pdf": c = vgpdf.New(w, h) case "png": c = vgimg.PngCanvas{Canvas: vgimg.New(w, h)} case "svg": c = vgsvg.New(w, h) case "tif", "tiff": c = vgimg.TiffCanvas{Canvas: vgimg.New(w, h)} default: return nil, fmt.Errorf("unsupported format: %q", format) } return c, nil }
func plotSingle(df *DataFrame, name string) { p, err := plot.New() if err != nil { log.Fatal(err) } p.X.Label.Text = "X" p.Y.Label.Text = "Y" err = plotutil.AddLinePoints(p, name, df.PlotPoints()) if err != nil { log.Fatal(err) } c := vgsvg.New(16*vg.Inch, 9*vg.Inch) can := draw.New(c) p.Draw(can) p.Save(16*vg.Inch/2, 9*vg.Inch/2, fmt.Sprintf("graphs/%s.png", name)) f, err := os.Create(fmt.Sprintf("graphs/%s.svg", name)) if err != nil { log.Fatal(err) } c.WriteTo(f) }
// WriterTo returns an io.WriterTo that will write the plot as // the specified image format. // // Supported formats are: // // eps, jpg|jpeg, pdf, png, svg, and tif|tiff. func (p *Plot) WriterTo(w, h vg.Length, format string) (io.WriterTo, error) { var c interface { vg.CanvasSizer io.WriterTo } switch format { case "eps": c = vgeps.New(w, h) case "jpg", "jpeg": c = vgimg.JpegCanvas{Canvas: vgimg.New(w, h)} case "pdf": c = vgpdf.New(w, h) case "png": c = vgimg.PngCanvas{Canvas: vgimg.New(w, h)} case "svg": c = vgsvg.New(w, h) case "tif", "tiff": c = vgimg.TiffCanvas{Canvas: vgimg.New(w, h)} default: return nil, fmt.Errorf("unsupported format: %q", format) } p.Draw(draw.New(c)) return c, nil }
func plotMulti(name string, names []string, frames []*DataFrame) { if len(names) != len(frames) { log.Fatal("wrong length for plots") } p, err := plot.New() if err != nil { log.Fatal(err) } p.X.Label.Text = "X" p.Y.Label.Text = "Y" lines := make([]interface{}, len(names)*2) x := 0 for i := 0; i < len(lines); i += 2 { lines[i] = names[x] lines[i+1] = frames[x].PlotPoints() x += 1 } err = plotutil.AddLinePoints(p, lines...) if err != nil { log.Fatal(err) } c := vgsvg.New(16*vg.Inch, 9*vg.Inch) can := draw.New(c) p.Draw(can) p.Save(16*vg.Inch/2, 9*vg.Inch/2, fmt.Sprintf("graphs/%s.png", name)) f, err := os.Create(fmt.Sprintf("graphs/%s.svg", name)) if err != nil { log.Fatal(err) } c.WriteTo(f) }
func (c *client) run() { var err error dir, err := ioutil.TempDir("", "snfusion-web-") if err != nil { log.Printf("error creating temporary directory: %v\n", err) return } defer func() { c.srv.unregister <- c c.ws.Close() c.srv = nil os.RemoveAll(dir) }() type params struct { ID int `json:"id"` NumIters int `json:"num_iters"` NumCarbons float64 `json:"num_carbons"` Seed int64 `json:"seed"` } type genReply struct { ID int `json:"id"` Stage string `json:"stage"` Err error `json:"err"` Msg string `json:"msg"` Engine sim.Engine `json:"engine"` } type plotReply struct { ID int `json:"id"` Stage string `json:"stage"` Err error `json:"err"` SVG string `json:"svg"` } type zipReply struct { ID int `json:"id"` Stage string `json:"stage"` Err error `json:"err"` Href string `json:"href"` } for { param := params{ NumIters: 100000, NumCarbons: 60, Seed: 1234, } log.Printf("waiting for simulation parameters...\n") err = websocket.JSON.Receive(c.ws, ¶m) if err != nil { log.Printf("error rcv: %v\n", err) return } id := param.ID msgbuf := new(bytes.Buffer) msg := log.New(msgbuf, "snfusion-sim: ", 0) engine := sim.Engine{ NumIters: param.NumIters, NumCarbons: param.NumCarbons, Seed: param.Seed, } engine.SetLogger(msg) log.Printf("processing... %#v\n", engine) csvbuf := new(bytes.Buffer) errc := make(chan error) ticker := time.NewTicker(1 * time.Second) go func() { errc <- engine.Run(csvbuf) ticker.Stop() }() err = <-errc if err != nil { log.Printf("error: %v\n", err) _ = websocket.JSON.Send(c.ws, genReply{ ID: id, Err: err, Engine: engine, Stage: "gen-done", Msg: msgbuf.String(), }) return } err = websocket.JSON.Send(c.ws, genReply{ ID: id, Err: err, Engine: engine, Stage: "gen-done", Msg: msgbuf.String(), }) if err != nil { log.Printf("error sending data: %v\n", err) return } csvdata := make([]byte, len(csvbuf.Bytes())) copy(csvdata, csvbuf.Bytes()) log.Printf("running post-processing...\n") r := csv.NewReader(csvbuf) r.Comma = ';' r.Comment = '#' table := make([]plotter.XYs, len(engine.Population)) for i := range table { table[i] = make(plotter.XYs, engine.NumIters+1) } for ix := 0; ix < engine.NumIters+1; ix++ { var text []string text, err = r.Read() if err != nil { break } for i := range engine.Population { table[i][ix].X = float64(ix) table[i][ix].Y = float64(atoi(text[i])) } } if err == io.EOF { err = nil } if err != nil { log.Printf("error reading data: %v\n", err) return } p, err := plot.New() if err != nil { panic(err) } p.Title.Text = fmt.Sprintf( "Time evolution of nuclei C%v-O%v (seed=%d)", engine.NumCarbons, 100-engine.NumCarbons, engine.Seed, ) p.X.Label.Text = "Iteration number" p.Y.Label.Text = "Atomic mass of nuclei" for i, n := range engine.Population { line, err := plotter.NewLine(table[i]) if err != nil { log.Fatalf( "error adding data points for nucleus %v: %v\n", n, err, ) } line.LineStyle.Color = col(n) line.LineStyle.Width = vg.Points(1) p.Add(line) p.Legend.Add(label(n), line) } p.Add(plotter.NewGrid()) p.Legend.Top = true p.Legend.XOffs = -1 * vg.Centimeter figX := 25 * vg.Centimeter figY := figX / vg.Length(math.Phi) // Create a Canvas for writing SVG images. canvas := vgsvg.New(figX, figY) // Draw to the Canvas. p.Draw(draw.New(canvas)) outsvg := new(bytes.Buffer) _, err = canvas.WriteTo(outsvg) if err != nil { log.Printf("error svg: %v\n", err) return } err = websocket.JSON.Send(c.ws, plotReply{ ID: id, Err: err, SVG: outsvg.String(), Stage: "plot-done", }) if err != nil { log.Printf("error sending data: %v\n", err) return } pngcanvas := vgimg.PngCanvas{Canvas: vgimg.New(figX, figY)} p.Draw(draw.New(pngcanvas)) outpng := new(bytes.Buffer) _, err = pngcanvas.WriteTo(outpng) if err != nil { log.Printf("error png: %v\n", err) return } href := filepath.Join(dir, fmt.Sprintf("output-%d.zip", id)) zipf, err := os.Create(href) if err != nil { log.Printf("error creating zip file: %v\n", err) } defer zipf.Close() zipw := zip.NewWriter(zipf) defer zipw.Close() for _, file := range []struct { Name string Body []byte }{ {"output.csv", csvdata}, {"output.png", outpng.Bytes()}, } { ff, err := zipw.Create(file.Name) if err != nil { log.Printf("error creating zip content %v: %v\n", file.Name, err) return } _, err = ff.Write(file.Body) if err != nil { log.Printf("error writing zip content %v: %v\n", file.Name, err) return } } err = zipw.Close() if err != nil { log.Printf("error closing zip-writer: %v\n", err) return } err = zipf.Close() if err != nil { log.Printf("error closing zip-file: %v\n", err) return } err = websocket.JSON.Send(c.ws, zipReply{ ID: id, Err: err, Href: href, Stage: "zip-done", }) if err != nil { log.Printf("error sending zip: %v\n", err) return } log.Printf("saved report under %v\n", href) } }