File: gob_test.go

package info (click to toggle)
golang-gonum-v1-plot 0.7.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 13,980 kB
  • sloc: sh: 81; makefile: 13
file content (161 lines) | stat: -rw-r--r-- 3,891 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gob_test

import (
	"bytes"
	"encoding/gob"
	"image/color"
	"os"
	"testing"

	"golang.org/x/exp/rand"

	"gonum.org/v1/plot"
	_ "gonum.org/v1/plot/gob"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"
	"gonum.org/v1/plot/vg/draw"
)

func init() {
	gob.Register(commaTicks{})
}

func TestPersistency(t *testing.T) {
	rnd := rand.New(rand.NewSource(1))

	// Get some random points
	n := 15
	scatterData := randomPoints(n, rnd)
	lineData := randomPoints(n, rnd)
	linePointsData := randomPoints(n, rnd)

	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")
	// }

}

// randomPoints returns some random x, y points.
func randomPoints(n int, rnd *rand.Rand) plotter.XYs {
	pts := make(plotter.XYs, n)
	for i := range pts {
		if i == 0 {
			pts[i].X = rnd.Float64()
		} else {
			pts[i].X = pts[i-1].X + rnd.Float64()
		}
		pts[i].Y = pts[i].X + rnd.Float64()*1e4
	}
	return pts
}

// CommaTicks computes the default tick marks, but inserts commas
// into the labels for the major tick marks.
type commaTicks struct{}

func (commaTicks) Ticks(min, max float64) []plot.Tick {
	tks := plot.DefaultTicks{}.Ticks(min, max)
	for i, t := range tks {
		if t.Label == "" { // Skip minor ticks, they are fine.
			continue
		}
		tks[i].Label = addCommas(t.Label)
	}
	return tks
}

// AddCommas adds commas after every 3 characters from right to left.
// NOTE: This function is a quick hack, it doesn't work with decimal
// points, and may have a bunch of other problems.
func addCommas(s string) string {
	rev := ""
	n := 0
	for i := len(s) - 1; i >= 0; i-- {
		rev += string(s[i])
		n++
		if n%3 == 0 {
			rev += ","
		}
	}
	s = ""
	for i := len(rev) - 1; i >= 0; i-- {
		s += string(rev[i])
	}
	return s
}