...

Source file src/gonum.org/v1/plot/palette/brewer/brewer.go

Documentation: gonum.org/v1/plot/palette/brewer

     1  // Copyright ©2015 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Copyright ©2013 The bíogo Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  // Palette type comments ©2002 Cynthia Brewer.
    10  
    11  // Package brewer provides Brewer Palettes for informative graphics.
    12  //
    13  // The colors defined here are from http://www.ColorBrewer.org/ by Cynthia A. Brewer,
    14  // Geography, Pennsylvania State University.
    15  //
    16  // For more information see:
    17  // http://www.personal.psu.edu/cab38/ColorBrewer/ColorBrewer_learnMore.html
    18  package brewer // import "gonum.org/v1/plot/palette/brewer"
    19  
    20  import (
    21  	"errors"
    22  	"fmt"
    23  	"image/color"
    24  
    25  	"gonum.org/v1/plot/palette"
    26  )
    27  
    28  // Color represents a Brewer Palette color.
    29  type Color struct {
    30  	Letter byte
    31  	color.Color
    32  }
    33  
    34  // Usability describes the usability of a palette for particular use cases.
    35  type Usability byte
    36  
    37  const (
    38  	NotAvalailable Usability = iota
    39  	Bad
    40  	Unsure
    41  	Good
    42  )
    43  
    44  // Palette represents a color scheme.
    45  type Palette struct {
    46  	ID   string
    47  	Name string
    48  
    49  	Laptop     Usability
    50  	CRT        Usability
    51  	ColorBlind Usability
    52  	Copy       Usability
    53  	Projector  Usability
    54  
    55  	Color []color.Color
    56  }
    57  
    58  // DivergingPalette represents a diverging color scheme.
    59  type DivergingPalette Palette
    60  
    61  // Colors returns the palette's color collection.
    62  func (d DivergingPalette) Colors() []color.Color { return d.Color }
    63  
    64  // CriticalIndex returns the indices of the lightest (median) color or colors in the DivergingPalette.
    65  // The low and high index values will be equal when there is a single median color.
    66  func (d DivergingPalette) CriticalIndex() (low, high int) {
    67  	l := len(d.Color)
    68  	return (l - 1) / 2, l / 2
    69  }
    70  
    71  // NonDivergingPalette represents sequential or qualitative color schemes.
    72  type NonDivergingPalette Palette
    73  
    74  // Colors returns the palette's color collection.
    75  func (d NonDivergingPalette) Colors() []color.Color { return d.Color }
    76  
    77  // Diverging schemes put equal emphasis on mid-range critical values and extremes
    78  // at both ends of the data range. The critical class or break in the middle of the
    79  // legend is emphasized with light colors and low and high extremes are emphasized
    80  // with dark colors that have contrasting hues.
    81  type Diverging map[int]DivergingPalette
    82  
    83  // Qualitative schemes do not imply magnitude differences between legend classes,
    84  // and hues are used to create the primary visual differences between classes.
    85  // Qualitative schemes are best suited to representing nominal or categorical data.
    86  type Qualitative map[int]NonDivergingPalette
    87  
    88  // Sequential schemes are suited to ordered data that progress from low to high.
    89  // Lightness steps dominate the look of these schemes, with light colors for low
    90  // data values to dark colors for high data values.
    91  type Sequential map[int]NonDivergingPalette
    92  
    93  var (
    94  	// DivergingPalettes is a string-based map look-up table of diverging palettes.
    95  	DivergingPalettes map[string]Diverging = diverging
    96  
    97  	// QualitativePalettes is a string-based map look-up table of qualitative palettes.
    98  	QualitativePalettes map[string]Qualitative = qualitative
    99  
   100  	// SequentialPalettes is a string-based map look-up table of sequential palettes.
   101  	SequentialPalettes map[string]Sequential = sequential
   102  )
   103  
   104  // PaletteType indicates palette type for a GetPalette request.
   105  type PaletteType int
   106  
   107  const (
   108  	TypeAny PaletteType = iota
   109  	TypeDiverging
   110  	TypeQualitative
   111  	TypeSequential
   112  )
   113  
   114  // GetPalette returns a Palette based on palette type and name, and the number of colors
   115  // required. An error is returned if the palette name or type is not known or the requested
   116  // palette does not support the required number of colors.
   117  func GetPalette(typ PaletteType, name string, colors int) (palette.Palette, error) {
   118  	if colors < 3 {
   119  		return nil, errors.New("brewer: number of colors must be 3 or greater")
   120  	}
   121  	var (
   122  		p palette.Palette
   123  
   124  		nameOk, colorsOk bool
   125  	)
   126  	switch typ {
   127  	case TypeAny:
   128  		var pt interface{}
   129  		pt, nameOk = all[name]
   130  		if !nameOk {
   131  			break
   132  		}
   133  		switch pt := pt.(type) {
   134  		case Diverging:
   135  			p, colorsOk = pt[colors]
   136  		case Qualitative:
   137  			p, colorsOk = pt[colors]
   138  		case Sequential:
   139  			p, colorsOk = pt[colors]
   140  		default:
   141  			panic("brewer: unexpected type")
   142  		}
   143  	case TypeDiverging:
   144  		var pt Diverging
   145  		pt, nameOk = diverging[name]
   146  		if !nameOk {
   147  			break
   148  		}
   149  		p, colorsOk = pt[colors]
   150  	case TypeQualitative:
   151  		var pt Qualitative
   152  		pt, nameOk = qualitative[name]
   153  		if !nameOk {
   154  			break
   155  		}
   156  		p, colorsOk = pt[colors]
   157  	case TypeSequential:
   158  		var pt Sequential
   159  		pt, nameOk = sequential[name]
   160  		if !nameOk {
   161  			break
   162  		}
   163  		p, colorsOk = pt[colors]
   164  	default:
   165  		return nil, fmt.Errorf("brewer: palette type not known: %v", typ)
   166  	}
   167  	if !nameOk {
   168  		return nil, fmt.Errorf("brewer: palette %q not known", name)
   169  	}
   170  	if !colorsOk {
   171  		return nil, fmt.Errorf("brewer: palette %q does not support %d colors", name, colors)
   172  	}
   173  	return p, nil
   174  }
   175  

View as plain text