Seaborn Color Palettes and How to Use Them

Seaborn Color Palettes and How to Use Them

I love how easy it is to make a visually pleasing plot with seaborn color palettes. I’ve compiled a list of available palettes based on data types, and added a few tips on how to use them.

Some Color Palettes Basics

A seaborn color palette is given either as a List of colors, or a matplotlib.colors.Colormap object. In this post, I will focus on the first type. As the default, the palette provided by seaborn is a list is of RBG tuples.

1
2
3
4
5
6
7
import seaborn as sns

palette = sns.color_palette() # Default color palette
print(palette)  # Prints the RGB tuples that make up this color palette
sns.palplot(palette) # Plotting your palette!
sns.palplot(sns.color_palette('husl', 10)) # Seaborn color palette, with 10 colors
sns.color_palette("rocket", as_cmap=True) # Get a CMap

There are some really great posts out there full of useful information, including Seaborn’s own tutorial, but I couldn’t find a clear list of all the pre-made options, sectioned into types. I tried to list all of them (updated for seaborn 0.11.2), and though I’m sure I’ve missing some, it is more comprehensive than what I was able to find online. The palette chosen should fit the data, and so, the palettes are given by types. I use the three palette classes seaborn uses in their documentation - qualitative, sequential and diverging, as well as matplotlib’s miscellaneous.

Named seaborn Palettes by Category

Qualitative color palettes

Best for categorical data, as they vary mostly in the hue component (the most noticeable exceptions here are tab20b and tab20c). This pattern of variations creates different colors with very similar luminosity and saturation, so the palette looks cohesive, and there is no “special” color that stands out compared to the others.

matplotlib palettes, and Seaborn variations

The matlab default palette we all know and love is called tab10, and is also the default palette for most seaborn functions. The seaborn variations are: deep, muted, pastel, bright, dark, and colorblind, while the matplotlib palettes are tab20, tab20b and tab20c.

tab10 / default
tab10
deep
deep
muted
muted
pastel
pastel
bright
bright
dark
dark
colorblind
colorblind
tab20
tab20
tab20b
tab20b
tab20c
tab20c


What about the rest of the matlab palettes? There are several Color Brewer and matplotlib palettes that share the same name such as Set2 and Accent. There is an option to use the original matplotlib functionality by using the mpl_palette function instead of color_palette. The colors for both are the same, but they handle the palette length differently. For lengths longer than the original list, the Color Brewer option will repeat colors to return the size requested. The matplotlib function will return the original list, without any repetitions.

Circular palettes

As the name would suggest, this type of palettes is made out of evenly spaced colors that create a full spectrom, by changing the hue while keeping the brightness and saturation constant. This means larger palettes can be generated, and therefor it is good to use in the case of an arbitrary (possibly large) number of categories. These palettes are: hls and husl.

hls
hls
husl
husl


Qualitative Color Brower palettes

As mentioned previously, the default behavior for these palettes is a bit different - unless length is specified, the full list will be returned, which is of varying sizes. This is why I usually use the n argument, just to be on the safe side. The palettes in this category are: Set1, Set2, Set3, Paired, Accent, Pastel1, Pastel2 and Dark2. For all of these, there are reversed (add _r to the original name) and dark (_d) variations as well. Note where the colors repeat due to the palette containing less than ten colors. If you need many distinct colors - go with a circular palette instead.

Set1
Set1
Set2
Set2
Set3
Set3
Paired
Paired
Accent
Accent
Pastel1
Pastel1
Pastel2
Pastel2
Dark2
Dark2


Sequential color palettes

Large palettes, best for big data ranges. Note that all of the palettes in this category can also be given as a cmap (using the as_cmap=True argument).

Perceptually uniform palettes

This category includes the original Seaborn palettes rocket, mako, flare, and crest, as well as the matplotlib palettes viridis, plasma, inferno, magma and cividis. All of these palettes also have a reveresed (_r) version.

rocket
rocket
mako
mako
flare
flare
crest
crest
viridis
viridis
plasma
plasma
inferno
inferno
magma
magma
cividis
cividis


Sequential Color Brewer palettes

Single-hue and multi-hue (up to three) options, which are: Greys, Reds, Greens, Blues, Oranges, Purples, BuGn, BuPu, GnBu, OrRd, PuBu, PuRd, RdPu, YlGn, PuBuGn, YlGnBu, YlOrBr and YlOrRd. The options here include reversed (_r) and dark (_d).

Greys
Greys
Reds
Reds
Greens
Greens
Blues
Blues
Oranges
Oranges
Purples
Purples
BuGn
BuGn
BuPu
BuPu
GnBu
GnBu
OrRd
OrRd
PuBu
PuBu
RdPu
RdPu
YlGn
YlGn
PuBuGn
PuBuGn
YlGnBu
YlGnBu
YlOrBr
YlOrBr
YlOrRd
YlOrRd


Diverging color palettes

Best used for a wide range data which has a (if there are multiple, these palettes can be manipulated to accomodate that) categorical bound - typically 0, but not always.

Perceptually uniform diverging palettes

Seaborn provides us with the original vlag and icefire palettes and their reveresed (_r) counterparts, as well as the matplotlib palettes coolwarm, bwr, and seismic (again see the remark above about the ColorBrewer and matplotlib counterparts). I personally like to use vlag when plotting diverging data (with TwoSlopeNorm! Mental note, write about that too sometime).

vlag
vlag
icefire
icefire
coolwarm
coolwarm
bwr
bwr
seismic
seismic


Diverging Color Brewer palettes

These include RdBu, RdGy, PRGn, PiYG, BrBG, RdYlBu, RdYlGn and Spectral, and their reversed (_r) variations.

RdBu
RdBu
RdGy
RdGy
PRGn
PRGn
PiYG
PiYG
BrBG
BrBG
RdYlBu
RdYlBu
RdYlGn
RdYlGn
Spectral
Spectral


Miscellaneous Colormaps

These are matplotlib colormaps that are available in seaborn, but as they were not classified as any type, but rather, each created for a specific task. For example, gist_earth, ocean, and terrain are all for topological plotting. While we can technically use these as List color palettes, they were not really intended for this usage. This category includes the following, and their reversed (_r) counterparts: flag, prism, ocean, gist_earth, terrain, gist_stern, gnuplot, gnuplot2, CMRmap,cubehelix, brg, gist_rainbow, rainbow, jet, turbo, nipy_spectral and gist_ncar. For the colors, see matplotlib’s documentation.

Creating a Customized Color Palette

We can also create our own color palette, either based on colors from existing palettes, or by defining them on our own. I personally prefer to create a custom color theme for each project, and use it throughout, not only when ploting, but in related papers, presentations, and so on.

In this example, we’ll use my current favorite free online tool, Coolors, to select the colors for our new color palette, then recreate it in seaborn. For those of you who don’t want to spend too much time on that, Coolors has a trending palettes section, from which I chose the following:

Custom color palette

By default, the colors are displayed in HEX format, though you can select other formats as well. I personally prefer to use it, as seaborn palettes can be created as a list of HEX values, and generally it is an easy to use across multiple technical decks (Python / HTML / PowerPoint / …). Note that the HEX representation provided by Coolers is missing a starting #, so be sure to add that character to every color code.

1
2
3
4
5
6
7
8
9
import seaborn as sns
from matplotlib import pyplot as plt

tips = sns.load_dataset("tips") # some example data
palette = ["#F72585", "#7209B7", "#3A0CA3", "#4361EE", "#4CC9F0"]
sns.set()
# or: sns.set_palette(palette), then the palette argument below is not needed
sns.catplot(x="day", y="total_bill", data=tips, palette=palette)
plt.tight_layout()

And here is the resulting graph: seaborn plot with custom palette

A bit about colorblind palettes

A few months back a friend asked how to make a graph more grayscale friendly and colorblind friendly. The first thing that came to mind was using hatches for bar plots. Seaborn does have a colorblind palette (mentioned above), but I wondered if there’s anything else I’ll be able to use to adjust my own palettes. I am still looking for more resources on the topic, but in the meantime, I found a really cool free feature on Coolors, aptly named ‘color blindness’:

Custom color palette

Clicking the button will reveal a list of types of colorblindness. Clicking each will allow you to have a hint of how color blind people will see your palette, and hopefully avoid pitfalls:

Custom color palette

Using Your Color Palette

We can use the palette as shown above. The thing is, that way we are not really defining a specific color for each hue category, which is fine if there is no need in highlighting specific data, but the color assignment still relies on the order of the data. If we were diligent enough to define an order to all of our dataframe columns, the order, and the subsequent coloring, would remain the same, but what if we plot only a portion of the data? In that case, the color assignment for the remaining data may be inconsistent with other plots.

That is why we are going to use the palette argument, but instead of just passing the initial colors, we are going to use a dictionary (which I implement as a global variable on actual projects), mapping each dataset/category to a specific color from the color palette. This is an incredibly simple trick to have in your arsenal, so much so I feel stupid even typing it, but it has really simplified my entire workflow. I ardently use it in every new project, not only for color palettes, but also for markers, hatches and line types.

1
2
3
4
5
6
7
8
9
import seaborn as sns
from matplotlib import pyplot as plt

tips = sns.load_dataset("tips") # some example data
# hand picking each colors per category
palette = {'Fri': "#F72585", 'Sun':  "#4CC9F0", 'Sat': "#7209B7", 'Thur': "#3A0CA3"}
sns.set_palette(palette)
sns.catplot(x="day", y="total_bill", data=tips)
plt.tight_layout()

This way, the order of the categories stays the same (since we have not defined a new order on the day column), but we can control the color assignment: seaborn plot with custom palette