From 8dedd91fcb1dca313bca6177080531f4eb19509a Mon Sep 17 00:00:00 2001
From: "Andrew E. Torda" <torda@zbh.uni-hamburg.de>
Date: Sat, 5 Feb 2022 17:28:53 +0100
Subject: [PATCH] Changed the plot functions. We now have a basic plot from
 which the two real plots start and then append their specific information.

---
 Makefile              |   3 +
 mc_work/ToDo          |   5 +-
 mc_work/dorun.go      |   4 +-
 mc_work/plot.go       | 137 +++++++++++++++++++-----------------------
 mc_work/set_suffix.go |   2 +
 ui/scrnplt.go         |   9 ++-
 6 files changed, 78 insertions(+), 82 deletions(-)

diff --git a/Makefile b/Makefile
index 008059b..923682c 100644
--- a/Makefile
+++ b/Makefile
@@ -8,3 +8,6 @@ clean:
 	go clean
 	rm -rf */*_delme.*
 	rm -rf */test_tmp*
+	rm -rf /tmp/go-build[0-9]*
+	rm -rf /tmp/go.*.mod
+	rm -rf /tmp/go.*.sum
diff --git a/mc_work/ToDo b/mc_work/ToDo
index 7d7a839..c5fe2bc 100644
--- a/mc_work/ToDo
+++ b/mc_work/ToDo
@@ -6,4 +6,7 @@ In dorun.go
 
 * Change the tests so all files are written to a temporary directory
 
-Note.. Benchmarking suggests that most of the time is spent in Ackley function, and, to be exact, in the cosine and exp() function.
\ No newline at end of file
+Note.. Benchmarking suggests that most of the time is spent in Ackley function, and, to be exact, in the cosine and exp() function.
+
+In the plottin functions,
+Put a secondary axis on the X trajectory or check out multiplots so that the two plots line up with each other.
diff --git a/mc_work/dorun.go b/mc_work/dorun.go
index 6c5a1cd..fa9b100 100644
--- a/mc_work/dorun.go
+++ b/mc_work/dorun.go
@@ -268,7 +268,7 @@ func doRun(mcPrm *mcPrm) error {
 		saveStep(&cprm, mcPrm.nStep, tmprtr, x, fOld)
 	}
 	defer fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1)
-	breaker()
+
 	if err := plotfWrt(&cprm); err != nil {
 		return err
 	}
@@ -285,7 +285,7 @@ func doRun(mcPrm *mcPrm) error {
 			fmt.Println ("xBuf for plotting is this big", len(xBuf.Bytes()))
 			xdata = xBuf.Bytes()
 		}
-		breaker(fdata, xdata)
+		nothing (fdata, xdata)
 //		ui.Scrnplt(fdata, xdata)
 	}
 
diff --git a/mc_work/plot.go b/mc_work/plot.go
index ee33a9a..7e8b1a9 100644
--- a/mc_work/plot.go
+++ b/mc_work/plot.go
@@ -22,6 +22,11 @@ import (
 	"gitlab.rrz.uni-hamburg.de/Bae5157/axticks"
 )
 
+const (
+	chrtWdth = 800
+	chrtHt   = 400
+)
+
 // maketicks gives reasonable default tick locations
 func maketicks(axisDscrpt axticks.AxisDscrpt) []chart.Tick {
 	xmin, xmax, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Xmax, axisDscrpt.Delta, axisDscrpt.Prcsn
@@ -41,22 +46,6 @@ func maketicks(axisDscrpt axticks.AxisDscrpt) []chart.Tick {
 	return t
 }
 
-// maketicks this version works, but usually leaves you wanting one tick more.
-/*func alt_maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
-	xmin, xmax, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Xmax, axisDscrpt.Delta, axisDscrpt.Prcsn
-	var t []chart.Tick
-	const fstr = "%.*f"
-	xv, xl := xmin, fmt.Sprintf(fstr, prcsn, xmin)
-	if xmin > 3.56 && xmin < 3.58 {
-		fmt.Println (axisDscrpt)
-	}
-	for ; xv <= xmax; xv, xl = xv+delta, fmt.Sprintf("%.*f", prcsn, xv) {
-		t = append(t, chart.Tick {Value: xv, Label: xl})
-	}
-
-	return t
-}*/
-
 // range2 just lets us append methods to a range/continuousrange structure
 type range2 struct {
 	chart.ContinuousRange
@@ -77,27 +66,14 @@ func (rng *range2) GetTicks(r chart.Renderer, cs chart.Style, vf chart.ValueForm
 	}
 }
 
-// plotfWrt writes out a plot of function values to the given
-// io.Writer. It used to ask for a string.
-func plotfWrt(cprm *cprm) error {
-	if cprm.fplotWrt == nil {
-		return nil
-	}
-	xdata := cprm.plotnstp // We just unpack for readability
-	ydata := cprm.plotf
-	tmprtrData := cprm.plotTmprtr
-
+// plotbase returns a chart that serves as the basis for both the function
+// values and the X trajectories. This lets us set up the x-axis once and
+// put the temperature on both plots so they come out the same size.
+func plotbase(cprm *cprm) *chart.Chart {
 	xaxis := chart.XAxis{
 		Name:  "step",
 		Range: &range2{},
 	}
-
-	fvalAxis := chart.YAxis{
-		Name:      "cost (arb units)",
-		NameStyle: chart.Style{TextRotationDegrees: 360}, // Zero does not work
-		AxisType:  chart.YAxisSecondary,
-		Range:     &range2{},
-	}
 	var tmprtrAxis chart.YAxis
 	if cprm.coolme { // If we are not cooling, we do not plot
 		tmprtrAxis = chart.YAxis{ // the temperature axis.
@@ -109,39 +85,54 @@ func plotfWrt(cprm *cprm) error {
 		tmprtrAxis = chart.YAxis{}        // to mess up the scaling on the
 		tmprtrAxis.Style = chart.Hidden() //  other axis
 	}
-
+	xdata := cprm.plotnstp
+	leftAxis := chart.YAxis{
+		NameStyle: chart.Style{TextRotationDegrees: 360}, // Zero does not work
+		AxisType:  chart.YAxisSecondary,
+		Range:     &range2{},
+	}
 	graph := chart.Chart{
-		Width: 800,
-		Title: "cost function",
+		Width: chrtWdth, Height: chrtHt,
 		Series: []chart.Series{
+			chart.ContinuousSeries{
+				Name:    "temperature",
+				XValues: xdata,
+				YValues: cprm.plotTmprtr,
+			},
 			chart.ContinuousSeries{ // The function values
-				Name:    "cost",
+				Name:    "specify me",
 				YAxis:   chart.YAxisSecondary,
 				XValues: xdata,
-				YValues: ydata,
 				Style: chart.Style{
-					StrokeWidth: 5,
+					StrokeWidth: 4,
 					DotWidth:    0,
 				},
 			},
-			chart.ContinuousSeries{
-				Name:    "temperature",
-				XValues: xdata,
-				YValues: tmprtrData,
-			},
 		},
 		YAxis:          tmprtrAxis,
-		YAxisSecondary: fvalAxis,
+		YAxisSecondary: leftAxis,
 		XAxis:          xaxis,
 
 		Background: chart.Style{
-			Padding: chart.Box{
-				Left:  50,
-				Right: 75,
-			},
+			Padding:   chart.Box{Left: 75, Right: 75},
 			FillColor: drawing.ColorTransparent,
 		},
 	}
+	return &graph
+}
+
+// plotfWrt plots the function values and temperature to an io.Writer that
+// it finds in the cprm structure. It might be writing to a file or a buffer.
+func plotfWrt(cprm *cprm) error {
+	graph := plotbase(cprm)
+	graph.YAxisSecondary.Name = "cost (arb units)"
+	if funcSeries, ok := graph.Series[1].(chart.ContinuousSeries); ok {
+		funcSeries.Name = "cost"
+		funcSeries.YValues = cprm.plotf
+		graph.Series[1] = funcSeries
+	} else {
+		panic("prog bug type assertion function plot")
+	}
 
 	if err := graph.Render(chart.PNG, cprm.fplotWrt); err != nil {
 		return fmt.Errorf("Render: %w", err)
@@ -151,16 +142,21 @@ func plotfWrt(cprm *cprm) error {
 }
 
 // plotxWrt
-// For each dimension, allocate space. Copy elements over from the long array.
-// Then call the plotter on each series in turn. I think I have to make a
-// slice of continuous series and then add them into the chart structure.
+// For each dimension, allocate space. The X's are stored in a single
+// array, so here we allocate an array of arrays for each dimension and
+// copy the elements. We then take the graph object and toss out the first
+// continuousSeries. Then, we make a series of ContinousSeries, appending
+// each in turn to the []graph.Series.
 func plotxWrt(cprm *cprm, ndim int) error {
-	if cprm.xplotWrt == nil { return nil }
+	if cprm.xplotWrt == nil {
+		return nil
+	}
+	graph := plotbase(cprm)
 	type f64 []float64
 	len_used := len(cprm.plotnstp)
 	xdata := make([]f64, ndim)
 	for i := 0; i < ndim; i++ {
-		xdata[i] = make([]float64, len_used)
+		xdata[i] = make([]float64, len_used, len_used)
 	}
 	var n int
 	for i := 0; i < len_used; i++ {
@@ -169,29 +165,18 @@ func plotxWrt(cprm *cprm, ndim int) error {
 			n++
 		}
 	}
-	series := make([]chart.Series, ndim)
-	for i := 0; i < ndim; i++ {
-		series[i] = chart.ContinuousSeries{
-			Name:    fmt.Sprintf("dimension %d", i),
-			XValues: cprm.plotnstp,
-			YValues: xdata[i],
+	graph.Title = fmt.Sprintf("X trajectories %d dimension", ndim)
+	graph.YAxisSecondary.Name = "X coord"
+	if baseSeries, ok := graph.Series[1].(chart.ContinuousSeries); ok {
+		graph.Series = graph.Series[:1]
+		for i := 0; i < ndim; i++ {
+			tmp := baseSeries
+			tmp.Name = fmt.Sprintf("dim %d", i)
+			tmp.YValues = xdata[i]
+			graph.Series = append(graph.Series, tmp)
 		}
-	}
-	graph := chart.Chart{
-		Title: fmt.Sprintf("X trajectories %d dimension", ndim),
-		XAxis: chart.XAxis{Name: "step", Range: &range2{}},
-		YAxis: chart.YAxis{
-			Name:      "x coord",
-			Range:     &range2{},
-			AxisType:  chart.YAxisSecondary,
-			NameStyle: chart.Style{TextRotationDegrees: 360},
-		},
-		Series: series,
-		Background: chart.Style{
-			Padding: chart.Box{
-				Left: 75,
-			},
-		},
+	} else {
+		panic("program bug, type assertion on y axis xtrajectories")
 	}
 	if err := graph.Render(chart.PNG, cprm.xplotWrt); err != nil {
 		return fmt.Errorf("plotting X trajectories: %w", err)
diff --git a/mc_work/set_suffix.go b/mc_work/set_suffix.go
index 81fc9be..c0bf8d0 100644
--- a/mc_work/set_suffix.go
+++ b/mc_work/set_suffix.go
@@ -48,3 +48,5 @@ func removeQuotes(s string) string {
 	}
 	return s
 }
+
+func nothing (...interface{}){}
diff --git a/ui/scrnplt.go b/ui/scrnplt.go
index ed51887..72a8bcf 100644
--- a/ui/scrnplt.go
+++ b/ui/scrnplt.go
@@ -17,7 +17,10 @@ import (
 
 func breaker(...interface{}) {}
 func Scrnplt(fdata []byte, xdata []byte) {
-	fmt.Println("scrnplt says fbuf size", len(fdata), "first few bytes:", string(fdata[:10]))
+	if len(fdata) == 0 && len (xdata) == 0 { return }
+
+fmt.Println("scrnplt says fbuf size", len(fdata), "first few bytes:", string(fdata[:10]))
+
 	fmt.Println("scrnplt says xbuf size", len(xdata), "first few bytes:", string(xdata[:10]))
 	a := app.New()
 	w := a.NewWindow("container")
@@ -31,8 +34,8 @@ func Scrnplt(fdata []byte, xdata []byte) {
 	text2 := canvas.NewText("There", green)
 //top, bottom, left, right
 //	content = container.NewMax(image, text1)
-	content := container.NewHSplit(fImage, xImage)
-	content.SetOffset(0.95)
+	content := container.NewVSplit(fImage, xImage)
+	content.SetOffset(0.50)
 	breaker(text1, content, text2)
 	w.Resize(fyne.NewSize(500, 320))
 	w.SetContent(content)
-- 
GitLab