forked from gonum/plot
/
colorbar.go
98 lines (88 loc) · 2.52 KB
/
colorbar.go
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
// Copyright ©2017 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 plotter
import (
"image"
"github.com/elamre/plot"
"github.com/elamre/plot/palette"
"github.com/elamre/plot/vg/draw"
)
// ColorBar is a plot.Plotter that draws a color bar legend for a ColorMap.
type ColorBar struct {
ColorMap palette.ColorMap
// Vertical determines wether the legend will be
// plotted vertically or horizontally.
// The default is false (horizontal).
Vertical bool
// Colors specifies the number of colors to be
// shown in the legend. If Colors is not specified,
// a default will be used.
Colors int
}
// colors returns the number of colors to be shown
// in the legend, substituting invalid values
// with the default of one color per point.
func (l *ColorBar) colors(c draw.Canvas) int {
if l.Colors > 0 {
return l.Colors
}
if l.Vertical {
return int(c.Max.Y - c.Min.Y)
}
return int(c.Max.X - c.Min.X)
}
// check determines whether the ColorBar is
// valid in its current configuration.
func (l *ColorBar) check() {
if l.ColorMap == nil {
panic("plotter: nil ColorMap in ColorBar")
}
if l.ColorMap.Max() == l.ColorMap.Min() {
panic("plotter: ColorMap Max==Min")
}
}
// Plot implements the Plot method of the plot.Plotter interface.
func (l *ColorBar) Plot(c draw.Canvas, p *plot.Plot) {
l.check()
colors := l.colors(c)
var pImg *Image
delta := (l.ColorMap.Max() - l.ColorMap.Min()) / float64(colors)
if l.Vertical {
img := image.NewNRGBA64(image.Rectangle{
Min: image.Point{X: 0, Y: 0},
Max: image.Point{X: 1, Y: colors},
})
for i := 0; i < colors; i++ {
color, err := l.ColorMap.At(l.ColorMap.Min() + delta*float64(i))
if err != nil {
panic(err)
}
img.Set(0, colors-1-i, color)
}
pImg = NewImage(img, 0, l.ColorMap.Min(), 1, l.ColorMap.Max())
} else {
img := image.NewNRGBA64(image.Rectangle{
Min: image.Point{X: 0, Y: 0},
Max: image.Point{X: colors, Y: 1},
})
for i := 0; i < colors; i++ {
color, err := l.ColorMap.At(l.ColorMap.Min() + delta*float64(i))
if err != nil {
panic(err)
}
img.Set(i, 0, color)
}
pImg = NewImage(img, l.ColorMap.Min(), 0, l.ColorMap.Max(), 1)
}
pImg.Plot(c, p)
}
// DataRange implements the DataRange method
// of the plot.DataRanger interface.
func (l *ColorBar) DataRange() (xmin, xmax, ymin, ymax float64) {
l.check()
if l.Vertical {
return 0, 1, l.ColorMap.Min(), l.ColorMap.Max()
}
return l.ColorMap.Min(), l.ColorMap.Max(), 0, 1
}