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 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
// 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.
// Copyright ©2013 The bíogo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Palette type comments ©2002 Cynthia Brewer.
// Package brewer provides Brewer Palettes for informative graphics.
//
// The colors defined here are from http://www.ColorBrewer.org/ by Cynthia A. Brewer,
// Geography, Pennsylvania State University.
//
// For more information see:
// http://www.personal.psu.edu/cab38/ColorBrewer/ColorBrewer_learnMore.html
//
package brewer // import "gonum.org/v1/plot/palette/brewer"
import (
"errors"
"fmt"
"image/color"
"gonum.org/v1/plot/palette"
)
// Color represents a Brewer Palette color.
type Color struct {
Letter byte
color.Color
}
// Usability describes the usability of a palette for particular use cases.
type Usability byte
const (
NotAvalailable Usability = iota
Bad
Unsure
Good
)
// Palette represents a color scheme.
type Palette struct {
ID string
Name string
Laptop Usability
CRT Usability
ColorBlind Usability
Copy Usability
Projector Usability
Color []color.Color
}
// DivergingPalette represents a diverging color scheme.
type DivergingPalette Palette
// Colors returns the palette's color collection.
func (d DivergingPalette) Colors() []color.Color { return d.Color }
// CriticalIndex returns the indices of the lightest (median) color or colors in the DivergingPalette.
// The low and high index values will be equal when there is a single median color.
func (d DivergingPalette) CriticalIndex() (low, high int) {
l := len(d.Color)
return (l - 1) / 2, l / 2
}
// NonDivergingPalette represents sequential or qualitative color schemes.
type NonDivergingPalette Palette
// Colors returns the palette's color collection.
func (d NonDivergingPalette) Colors() []color.Color { return d.Color }
// Diverging schemes put equal emphasis on mid-range critical values and extremes
// at both ends of the data range. The critical class or break in the middle of the
// legend is emphasized with light colors and low and high extremes are emphasized
// with dark colors that have contrasting hues.
type Diverging map[int]DivergingPalette
// Qualitative schemes do not imply magnitude differences between legend classes,
// and hues are used to create the primary visual differences between classes.
// Qualitative schemes are best suited to representing nominal or categorical data.
type Qualitative map[int]NonDivergingPalette
// Sequential schemes are suited to ordered data that progress from low to high.
// Lightness steps dominate the look of these schemes, with light colors for low
// data values to dark colors for high data values.
type Sequential map[int]NonDivergingPalette
var (
// DivergingPalettes is a string-based map look-up table of diverging palettes.
DivergingPalettes map[string]Diverging = diverging
// QualitativePalettes is a string-based map look-up table of qualitative palettes.
QualitativePalettes map[string]Qualitative = qualitative
// SequentialPalettes is a string-based map look-up table of sequential palettes.
SequentialPalettes map[string]Sequential = sequential
)
// PaletteType indicates palette type for a GetPalette request.
type PaletteType int
const (
TypeAny PaletteType = iota
TypeDiverging
TypeQualitative
TypeSequential
)
// GetPalette returns a Palette based on palette type and name, and the number of colors
// required. An error is returned if the palette name or type is not known or the requested
// palette does not support the required number of colors.
func GetPalette(typ PaletteType, name string, colors int) (palette.Palette, error) {
if colors < 3 {
return nil, errors.New("brewer: number of colors must be 3 or greater")
}
var (
p palette.Palette
nameOk, colorsOk bool
)
switch typ {
case TypeAny:
var pt interface{}
pt, nameOk = all[name]
if !nameOk {
break
}
switch pt := pt.(type) {
case Diverging:
p, colorsOk = pt[colors]
case Qualitative:
p, colorsOk = pt[colors]
case Sequential:
p, colorsOk = pt[colors]
default:
panic("brewer: unexpected type")
}
case TypeDiverging:
var pt Diverging
pt, nameOk = diverging[name]
if !nameOk {
break
}
p, colorsOk = pt[colors]
case TypeQualitative:
var pt Qualitative
pt, nameOk = qualitative[name]
if !nameOk {
break
}
p, colorsOk = pt[colors]
case TypeSequential:
var pt Sequential
pt, nameOk = sequential[name]
if !nameOk {
break
}
p, colorsOk = pt[colors]
default:
return nil, fmt.Errorf("brewer: palette type not known: %v", typ)
}
if !nameOk {
return nil, fmt.Errorf("brewer: palette %q not known", name)
}
if !colorsOk {
return nil, fmt.Errorf("brewer: palette %q does not support %d colors", name, colors)
}
return p, nil
}
|