Skip to content
Snippets Groups Projects
Select Git revision
  • f3190b0f55a8a8743ca04141e811550f60880f62
  • master default protected
  • devel
  • adaptive_step_size
4 results

plot.go

Blame
  • user avatar
    Andrew E. Torda authored
    temperature and x-values.
    f3190b0f
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    plot.go 3.00 KiB
    // 31 Dec 2021
    // This is for doing some plotting. For the moment, this is in the ackwork package,
    // but maybe it should be in its own. It definitely goes in its own file, since
    // it is tied to one of the chart packages I have tried out.
    
    package ackwork
    
    import (
    	"fmt"
    	"io"
    	"math"
    	"path/filepath"
    
    	"github.com/wcharczuk/go-chart/v2"
    	"github.com/wcharczuk/go-chart/v2/drawing"
    	"gitlab.rrz.uni-hamburg.de/Bae5157/axticks"
    )
    
    // makepngName takes a name. If it does not end in png, append .png to the name.
    // If it ends in something else, replace the ending with png.
    // We have stalinistically decided that we will only write png output.
    // svg is nicer, but the files can become silly big.
    func makepngName(fname string) string {
    	const dotpng = ".png"
    	ext := filepath.Ext(fname)
    	switch ext {
    	case "":
    		return fname + dotpng
    	case ".png":
    		fallthrough
    	case ".PNG":
    		return fname
    	default:
    		return fname[0:len(fname)-len(ext)] + dotpng
    	}
    	return "hello"
    }
    
    // maketicks gives reasonable default tick locations
    func maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
    	xmin, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Delta, axisDscrpt.Prcsn
    	rnge := axisDscrpt.Xmax - axisDscrpt.Xmin
    	ntick := int(math.Round((rnge / delta) + 1))
    	t := make([]chart.Tick, ntick)
    	const fstr = "%.*f"
    	t[0].Value, t[0].Label = xmin, fmt.Sprintf(fstr, prcsn, xmin)
    	for i := 1; i < ntick; i++ {
    		t[i].Value = t[i-1].Value + delta
    		t[i].Label = fmt.Sprintf("%.*f", prcsn, t[i].Value)
    	}
    	return t
    }
    
    // plotWrt writes out a plot to the given io.writercloser and
    // closes the file when finished.
    func plotWrite(xdata, ydata []float64, plotOut io.WriteCloser, plotme bool) error {
    	if !plotme {
    		return nil
    	}
    	var xAxisDscrpt, yAxisDscrpt axticks.AxisDscrpt
    	var err error
    	if yAxisDscrpt, err = axticks.Tickpos(ydata); err != nil {
    		return fmt.Errorf("plot making y axis: %w", err)
    	}
    	if xAxisDscrpt, err = axticks.Tickpos(xdata); err != nil {
    		return fmt.Errorf("plot making x axis: %w", err)
    	}
    
    	xaxis := chart.XAxis{
    		Name:  "step",
    		Range: &chart.ContinuousRange{
    			Min: xAxisDscrpt.Xmin,
    			Max: xAxisDscrpt.Xmax,
    		},
    		Ticks: maketicks(xAxisDscrpt, yAxisDscrpt.Prcsn),
    	}
    	yaxis := chart.YAxis{
    		Name: "cost (arb units)",
    		NameStyle: chart.Style{
    			TextRotationDegrees: 360}, // Zero does not work
    		TickStyle: chart.Style{
    			TextRotationDegrees: 0,
    		},
    		AxisType: chart.YAxisSecondary,
    		Range: &chart.ContinuousRange{
    			Min: yAxisDscrpt.Xmin,
    			Max: yAxisDscrpt.Xmax,
    		},
    		Ticks: maketicks(yAxisDscrpt, yAxisDscrpt.Prcsn),
    	}
    
    	graph := chart.Chart{
    		Width: 800,
    		Series: []chart.Series{
    			chart.ContinuousSeries{
    				XValues: xdata,
    				YValues: ydata,
    				Style: chart.Style{
    					StrokeWidth: 5,
    					DotWidth:    0,
    				},
    			},
    		},
    		YAxis: yaxis,
    		XAxis: xaxis,
    
    		Background: chart.Style{
    			Padding: chart.Box{
    				Left:  75,
    				Right: 25,
    			},
    			FillColor: drawing.ColorTransparent,
    		},
    	}
    	if err := graph.Render(chart.PNG, plotOut); err != nil {
    		return fmt.Errorf("While plotting %w", err)
    	}
    
    	return nil
    }