Data Visualization with Python and Seaborn — Part 3: Color Palettes

Random Nerd
7 min readAug 17, 2018

Choosing right color is an utmost important aspect of figure styling because it reveals pattern in the data if used effectively; or hide those patterns if used poorly. Even professionals often assume usage of color to portray data as a solved problem. They just pick a palette from a drop-down menu (probably either a grayscale ramp or a rainbow), set start and end points & finally press apply. But it isn’t that simple and thus many visualizations fail to represent the underlying data as appropriately as they could. Primary objective with choice of color is to illuminate datapoints that are concealed in huge datasets. Quoting Robert Simmon (aka Mr. Blue Marble from NASA):

“Although the basics are straightforward, a number of issue complicate color choices in visualization. Among them: The relationship between the light we see and the colors we perceive is extremely complicated. There are multiple types of data, each suited to a different color scheme. A significant number of people (mostly men), are color blind. Arbitrary color choices can be confusing for viewers unfamiliar with a data set. Light colors on a dark field are perceived differently than dark colors on a bright field, which can complicate some visualization tasks, such as target detection.”

One of the most fundamental and important aspects of color selection is the mapping of numbers to colors. This mapping allows us to pseudocolor an image or object based on varying numerical data. By far, the most common color map used in scientific visualization is the rainbow color map. Research paper on Diverging Color Maps for Scientific Visualization by Kenneth Moreland very well deals with the extended color concepts, if the topic interests you for deep analysis.

With all that been said, let us now focus on what Seaborn has to offer BUT before doing that let me once again remind you that Seaborn runs on top of Matplotlib so any color that is supported by Matplotlib will be supported by Seaborn as well. So at first, let us understand what Matplotlib has to offer:

  • An RGB or RGBA tuple of float values in [0, 1] (e.g., (0.1, 0.2, 0.5) or (0.1, 0.2, 0.5, 0.3))
  • A hex RGB or RGBA string (e.g., ‘#0F0F0F’ or ‘#0F0F0F0F’)
  • A string representation of a float value in [0, 1] inclusive for gray level (e.g., ‘0.5’)
  • One of {‘b’, ‘g’, ‘r’, ‘c’, ‘m’, ‘y’, ‘k’, ‘w’}
  • A X11/CSS4 color name
  • A name from the xkcd color survey prefixed with ‘xkcd:’ (e.g., ‘xkcd:sky blue’)
  • One of {‘C0’, ‘C1’, ‘C2’, ‘C3’, ‘C4’, ‘C5’, ‘C6’, ‘C7’, ‘C8’, ‘C9’}
  • One of {‘tab:blue’, ‘tab:orange’, ‘tab:green’, ‘tab:red’, ‘tab:purple’, ‘tab:brown’, ‘tab:pink’, ‘tab:gray’, ‘tab:olive’, ‘tab:cyan’} which are the Tableau Colors from the ‘T10’ categorical palette (which is the default color cycle).

Note that all string specifications of color, other than “CN”, are NOT case-sensitive. Let us briefly go through a couple of common supported colors here:

  • RGB/RGBA tuples are 4-tuples where the respective tuple components represent Red, Green, Blue, and Alpha (opacity) values for a color. Each value is a floating point number between 0.0 and 1.0. For example, the tuple (1, 0, 0, 1) represents an opaque red, while (0, 1, 0, 0.5) represents a half transparent green.
  • This is actually another way of representing RGBA codes and common Color Conversion Calculators can be used to translate values. Here is a Hex to RGBA and RGB to Hex Color converter for your future assistance.
  • Dictionary of values from {‘C0’, ‘C1’, ‘C2’, ‘C3’, ‘C4’, ‘C5’, ‘C6’, ‘C7’, ‘C8’, ‘C9’} represent Color Quantization. I have attached a link that shall guide you to an online book where on Page-29 you could find specifics.

My sole purpose of keeping you posted of Matplotlib background every now and then is only to ensure that when you get to production-level and try to customize a plot as per your analysis, you should know what is ACTUALLY running in the background. This shall empower you to accordingly tweak parameters here and there. Let us now look into few Seaborn options for colors:

Building Color Palettes:

The most important function for working with discrete color palettes is color_palette(). This function provides an interface to many (though not all) of the possible ways we can generate colors in Seaborn, and it’s used internally by any function that has a paletteargument (and in some cases for a color argument when multiple colors are needed). color_palette() will accept the name of any Seaborn palette or Matplotlib colormap (except jet, which we should ideally never use). It can also take a list of colors specified in any valid Matplotlib format (RGB tuples, hex color codes, or HTML color names). The return value is always a list of RGB tuples. Finally, calling color_palette() with no arguments will return the current default color cycle.

These Qualitative (or categorical) palettes are best when we want to distinguish discrete chunks of data, that do not have an inherent ordering. Ideally, when importing Seaborn, the default color cycle is changed to a set of six colors that evoke the standard Matplotlib color cycle. But when we have more than 6, say 8 categories in our data to distinguish, then the most common way is using hls color space, which is a simple transformation of RGB values.

Then there is also hls_palette() function that lets us control the lightness and saturation of colors. All of it displayed above is just the basic Seaborn aesthetics. Let us now look at xkcd_rgb dictionary that has 954 colors in it. Let us try to pull a few out of it:

Other style is cubehelix color palette that makes sequential palettes with a linear increase or decrease in brightness and some variation in hue. Actually let us plot this color palette in a Density contour plot:

Interactive widget to create a sequential cubehelix palette:

Let us now play with the parameters to have some fun and choose best parameters:

If you’re reading above highlighted message in the Jupyter Notebook or JupyterLab Notebook, it may mean that the widgets JavaScript is still loading. If this message persists, it likely means that the widgets JavaScript library is either not installed or not enabled. See the Jupyter Widgets Documentation for setup instructions. If you’re reading this message in another frontend (for example, a static rendering on GitHub or NBViewer), it may mean that your frontend doesn’t currently support widgets. Note that this app only works in this Jupyter Notebook as of now to help choose best parameters for our plot:

start is always between 0 and 3. rot an abbreviation for rotation is kept between -1 and 1. reverse converses the color ordering and hue refers to plot appearance.

Generic Seaborn Plots:

This does the job for us but let us try to get better results by plotting each day in different color instead of same color. For this, we shall replace color parameter with palette parameter:

Similarly let us plot one more and for a change, this time we shall plot a Box plot:

There are multiple such palettes available for us to play around with like magma, warm grey, gunmetal, dusky blue, cool blue, deep teal, viridian, twilight blue and many more. For customized color brewing, we may also use color brewer that also offers interesting color palettes for working with Qualitative data. The cool thing about it is that we can use an interactive Ipython widget function to make the selection of the palette. For this, we only need to use choose_colorbrewer_palette(). We may also choose to use the Color Brewer website that provides some guidance on which palettes are color blind safe.

I also found a nice representation of Color Schemes in Seaborn, (found somewhere on web), so thought of sharing it. This image depicts the color style in which assigning is done for different features based on either Sequential, Diverging or Qualitative.

With that we end this article on Colors and in the next one we shall start drilling one by one into the commonly used Seaborn plots. Till then, Enjoy Visualizing!

EDIT: Here is Resource Content (List of all the Parts of this Series).

Data Visualization with Python and Seaborn — Part 2

Data Visualization with Python and Seaborn — Part 4

--

--