VISUALISE FROM ggsql:penguins
DRAW point
MAPPING bill_dep AS x, body_mass AS y, species AS fill
SETTING stroke => null
SCALE color TO category10Fill and Stroke
Color values are used in two places in ggsql: When setting stroke color and fill color. Stroke color governs the color of lines, be it the outline of a rectangle (e.g. in a bar layer), or the line of a path (e.g. in a line layer). The fill color determines the color of the inside of a shape. It follows that all layers respond to the stroke aesthetic but only those containing closed shapes respond to the fill aesthetic.
The color meta-aesthetic
In addition to the fill and stroke aesthetics there is also a color meta-aesthetic. Setting this will set the fill and stroke at the same time unless they are set directly. For instance, the following will set the fill and stroke to red
DRAW bar
SETTING color => 'red'whereas this will set the fill to red and stroke to black
DRAW bar
SETTING color => 'red', stroke => 'black'The same logic applies when defining a scale. Defining a color scale creates two scales, one for fill and one for stroke, with the same settings (unless either are defined explicitly). For instance, the following
SCALE color TO viridisdefines two separate scales for fill and stroke that both use the viridis palette.
In general, it is highly advisable to be explicit and directly use the fill and stroke aesthetics. The color meta-aesthetic is a quick shortcut if you need it.
Literal values
Literal color values can be defined in any CSS compatible way 1. The gist of it is that colors can be defined in one of three different ways:
- As a named color, e.g.
'red', or'lemonchiffon' - As a hex color value, e.g.
'#FF0000'or'#FFFACD88' - As a css color function, e.g.
'rgba(100%, 0%, 0%, 50%)'or'oklab(98%, -0.012, 0.057)'
Literal color values are used in three places in ggsql. Either when setting an aesthetic (as opposed to mapping), e.g.
DRAW line
SETTING stroke => '#FF0000'when you define the output range of a fill or stroke scale manually, e.g.
SCALE fill TO ['rgb(100%, 0%, 0%)', 'lemonchiffon']or when using an identity scale for color in which case the data values must be parsable as colors.
Note that all different types of color notation can be mixed in the same place.
Literal color values may be translucent, either by providing a fourth channel the the hex-notation, or by using a css color function that includes an alpha level (e.g. rgba()). You should avoid mixing this with the use of the opacity aesthetic to ensure the opacity is predictable.
Palettes
There are two different types of palettes for fill and stroke — those intended for continuous data and those intended for discrete data. While they both consists of multiple color values, the continuous palettes are meant for interpolation between successive values whereas the discrete palettes are not.
Palettes are used by giving them as names in the TO clause:
Instead of using a named palette you can create one on the fly using an array of color values:
VISUALISE FROM ggsql:penguins
DRAW point
MAPPING bill_dep AS x, body_mass AS y, flipper_len AS fill
SETTING stroke => null
SCALE color TO ['antiquewhite', 'firebrick']Continuous palettes
Sequential
Sequential palettes for numeric data. navia is the default continuous color palette in ggsql.
Diverging
Diverging palettes emphasize a critical midpoint with two contrasting hues on either side. Ideal for data with a meaningful center point (e.g., zero, average).
Multi-Sequential
Multi-sequential palettes have multiple sequential segments, useful for categorical data with ordered subcategories.
| Name | Gradient | Source | Description |
|---|---|---|---|
bukavu |
Crameri | Multi-hue sequential | |
fes |
Crameri | Multi-hue sequential | |
oleron |
Crameri | Topographic (land/sea) |
Cyclic
Cyclic palettes wrap around, making them suitable for periodic data like angles, phases, or time of day.
Discrete palettes
Qualitative
Qualitative palettes for categorical data where no ordering is implied.
References
Crameri Scientific Colour Maps
Crameri, F. (2018). Scientific colour maps. Zenodo. doi:10.5281/zenodo.1243862
Crameri, F., Shephard, G.E., & Heron, P.J. (2020). The misuse of colour in science communication. Nature Communications, 11, 5444.
ColorBrewer
Brewer, C.A. (2002). ColorBrewer: Color Advice for Cartography. colorbrewer2.org
Matplotlib
van der Walt, S. & Smith, N. (2015). A Better Default Colormap for Matplotlib. SciPy 2015.
Tableau
Tableau Software. tableau.com
D3
Bostock, M. D3.js. d3js.org
Kelly’s Colors
Kelly, K.L. (1965). Twenty-two colors of maximum contrast. Color Engineering, 3(6), 26-27.
Choosing a Palette
For general continuous data
navia(default) - Good all-purpose choice, perceptually uniformviridis- Excellent for print, colorblind-safe, perceptually uniformbatlow- Wide perceptual range, good for scientific data
For data with a meaningful midpoint
Use a diverging palette:
vikorberlin- Clear red/blue contrastroma- Warm/cool contrast without red/blue
For data representing categories with magnitude
Consider multi-sequential palettes:
oleron- Good for topographic data
For periodic/cyclic data
Use a cyclic palette:
romao- Smooth transitions that wrap around
For general categorical data
ggsql10(default) - Good all-purpose choice, accessibletableau10- Familiar to many users, well-testedcategory10- Standard web visualization palette
For many categories (> 10)
kelly22- Up to 20 distinguishable colorsset3orpaired- 12 colors each
For subtle/background colors
pastel1orpastel2- Light, unobtrusiveset2- Muted but still distinguishable
For bold/emphasis
set1- Highly saturated, attention-grabbingdark2- Rich, deep colors
Accessibility
- Don’t rely on color alone: Use redundant encoding by combining color with shape, pattern, or direct labels. This ensures information is accessible when color cannot be perceived.
- Choose colorblind-safe palettes: Approximately 8% of men and 0.5% of women have some form of color vision deficiency. Palettes like
viridis,cividis, and the Crameri scientific palettes are designed to be distinguishable by colorblind viewers. - Avoid red-green combinations: Red-green color blindness (deuteranopia/protanopia) is the most common form. Avoid using red and green as the only distinguishing colors between categories.
- Ensure sufficient contrast: Light colors on light backgrounds or dark colors on dark backgrounds can be difficult to perceive. Aim for a contrast ratio of at least 3:1 for graphical elements.
- Test in grayscale: Print or display your visualization in grayscale to verify that information is still distinguishable without color. Palettes like
viridisandcividismaintain luminance variation when desaturated. - Limit the number of colors: Most people can only reliably distinguish 6-8 colors at a glance. For more categories, consider grouping, faceting, or interactive filtering instead of adding more colors.
- Use perceptually uniform palettes: Palettes where equal data differences produce equal perceived color differences prevent visual distortion of your data. The Crameri and matplotlib palettes (
viridis,plasma, etc.) are perceptually uniform. - Consider cultural associations: Colors carry different meanings across cultures (e.g., red can signify danger, luck, or political affiliation). Be mindful of unintended connotations in your audience.
- Provide alternatives: When possible, offer a data table or text description alongside color-encoded visualizations for users who cannot perceive the colors.
Footnotes
For a complete overview see the documentation for the csscolorparser crate which is what we use internally.↩︎