Qualitative color palettes are well-suited to representing categorical data because most of their variation is in the hue component. The default color palette in seaborn is a qualitative palette with ten distinct hues
These colors have the same ordering as the default matplotlib color palette, “tab10”, but they are a bit less intense. Compare
Seaborn has six variations of matplotlib’s palette, called deep, muted, pastel, bright, dark, and colorblind. This span a range of average luminance and saturation values
Many people find the moderated hues of the default “deep” palette to be aesthetically pleasing, but they are also less distinct. As a result, they may be more difficult to discriminate in some contexts, which is something to keep in mind when making publication graphics. This comparison can help estimate how the seaborn color palettes perform when simulating different forms of colorblindness.
Using circular color systems
When you have an arbitrary number of categories, the easiest approach to finding unique hues is to draw evenly-spaced colors in a circular color space (one where the hue changes while keeping the brightness and saturation constant). This is what most seaborn functions default to when they need to use more colors than are currently set in the default color cycle.
The most common way to do this uses the HLS color space, which is a simple transformation of RGB values. We saw this color palette before as a counterexample for how to plot a histogram:
Because of the way the human visual system works, colors that have the same luminance and saturation in terms of their RGB values won’t necessarily look equally intense To remedy this, seaborn provides an interface to the HUSL system since renamed to HSLuv, which achieves less intensity variation as you rotate around the color wheel
Using categorical Colorbrewer palettes
Another source of visually pleasing categorical palettes comes from the Color Brewer tool which also has sequential and diverging palettes, as we’ll see below.
Sequential color palettes
The second major class of color palettes is called “sequential”. This kind of mapping is appropriate when data range from relatively low or uninteresting values to relatively high or interesting values or vice versa. As we saw above, the primary dimension of variation in a sequential palette is luminance. Some seaborn functions will default to a sequential palette when you are mapping numeric data. For historical reasons, both categorical and numeric mappings are specified with the hue parameter in functions like relplot() or displot(), even though numeric mappings use color palettes with relatively little hue variation.
Perceptually uniform palettes
Because they are intended to represent numeric values, the best sequential palettes will be perceptually uniform, meaning that the relative discriminability of two colors is proportional to the difference between the corresponding data values.
Seaborn includes four perceptually uniform sequential colormaps: “rocket”, “mako”, “flare”, and “crest”. The first two have a very wide luminance range and are well suited for applications such as heatmaps, where colors fill the space they are plotted into
Because the extreme values of these colormaps approach white, they are not well-suited for coloring elements such as lines or points: it will be difficult to discriminate important values against a white or gray background. The “flare” and “crest” colormaps are a better choice for such plots. They have a more restricted range of luminance variations, which they compensate for with a slightly more pronounced variation in hue. The default direction of the luminance ramp is also reversed so that smaller values have lighter colors
It is also possible to use the perceptually uniform colormaps provided by matplotlib, such as “magma” and “viridis”
Discrete vs. continuous mapping
One thing to be aware of is that seaborn can generate discrete values from sequential colormaps and, when doing so, it will not use the most extreme values. Compare the discrete version of “rocket” against the continuous version shown above
Internally, seaborn uses the discrete version for categorical data and the continuous version when in numeric mapping mode. Discrete sequential colormaps can be well-suited for visualizing categorical data with an intrinsic ordering, especially if there is some hue variation.
Sequential “cubehelix” palettes
The perceptually uniform colormaps are difficult to programmatically generate because they are not based on the RGB color space. The cubehelix system offers an RGB-based compromise: it generates sequential palettes with a linear increase or decrease in brightness and some continuous variation in hue. While not perfectly perceptually uniform, the resulting colormaps have many good properties. Importantly, many aspects of the design process are parameterizable.
Matplotlib has the default cubehelix version built into it
cubehelix_palette() function is a bit different from the matplotlib default in that it does not rotate as far around the hue wheel or cover as wide a range of intensities. It also reverses the luminance ramp
Other arguments to cubehelix_palette() control how the palette looks. The two main things you’ll change are the start value between 0 and 3 and rot, or number of rotations, an arbitrary value, but usually between -1 and 1.
You can control both how dark and light the endpoints are and their order
sns.cubehelix_palette(start=2, rot=0, dark=0, light=.95, reverse=True, as_cmap=True)
Custom sequential palettes
For a simpler interface to custom sequential palettes, you can use light_palette() or dark_palette(), which are both seeded with a single color and produce a palette that ramps either from light or dark desaturated values to that color
sns.dark_palette("#69d", reverse=True, as_cmap=True) Reverse the colormap by adding “_r"
sns.color_palette("dark:salmon_r", as_cmap=True) Diverging color palettes
The third class of color palettes is called “diverging”. These are used for data where both large low and high values are interesting and span a midpoint value often 0 that should be emphasized. The rules for choosing good diverging palettes are similar to good sequential palettes, except now there should be two dominant hues in the colormap, one at (or near) each pole. It’s also important that the starting values are of similar brightness and saturation.
Perceptually uniform diverging palettes
Seaborn includes two perceptually uniform diverging palettes
“vlag” and “icefire”. They both use blue and red at their poles, which many intuitively process as “cold” and “hot”
Custom diverging palettes
You can also use the seaborn function diverging_palette() to create a custom colormap for diverging data. This function makes diverging palettes using the HUSL color system. You pass it two hues (in degrees) and, optionally, the lightness and saturation values for the extremes. Using HUSL means that the extreme values, and the resulting ramps to the midpoint, while not perfectly perceptually uniform, will be well-balanced
sns.diverging_palette(220, 20, as_cmap=True)
It’s also possible to make a palette where the midpoint is dark rather than light
Other diverging palettes
There are a few other good diverging palettes built into matplotlib, including Color Brewer palettes
Seaborn tries both to use good defaults and to offer a lot of flexibility.
This discussion is only the beginning, and there are a number of good resources for learning more about techniques for using color in visualizations.