Beautiful custom colormaps with Matplotlib | by Kerry Halupka | Towards Data Science

If your Matplotlib chart needs a colormap and you’re not using an inbuilt map, chances are you’re going to have a bad time. I used to dread editing colormaps in Python. Every help thread I looked at showed a different approach, and none of them quite matched my situation. This was always disappointing because colormaps can vastly change the message you’re sending with your data visualisation, and can even go so far as to make your chart un-useable.
Don’t believe me? Check this out.
Each of these visualisations show identical data (estimated population of local government areas in Australia), but with different colormaps. The data is continuous and positive, which is shown by carefully examining the legend for each. However, the colormaps tell a different story, one that’s a bit like the tale of Goldilocks:
The first chart uses a sequential colormap, where the lightness value changes (either increasing or decreasing) monotonically throughout. If the detail in your visualisation is important then sequential probably isn’t your best bet, since it can be difficult to compare areas with similar values.The second chart uses a diverging colormap. With more colours it’s easier to tell the difference between similar values, but it also suggests to the viewer that the data is centred about a normal baseline, like zero. If we were to normalise our data about the mean then this scale would be appropriate, but since we’re just showing a range of positive values it doesn’t work here.The third chart is just right. This is similar to a sequential map since the color changes gradually throughout, with one end that clearly indicates higher values, and one that indicates lower values. However this map includes more colors, which allows the viewer to more easily compare small differences.
The first chart uses a sequential colormap, where the lightness value changes (either increasing or decreasing) monotonically throughout. If the detail in your visualisation is important then sequential probably isn’t your best bet, since it can be difficult to compare areas with similar values.
The second chart uses a diverging colormap. With more colours it’s easier to tell the difference between similar values, but it also suggests to the viewer that the data is centred about a normal baseline, like zero. If we were to normalise our data about the mean then this scale would be appropriate, but since we’re just showing a range of positive values it doesn’t work here.
The third chart is just right. This is similar to a sequential map since the color changes gradually throughout, with one end that clearly indicates higher values, and one that indicates lower values. However this map includes more colors, which allows the viewer to more easily compare small differences.
These are just a few examples of the colormaps you can use, for more details and options, check out this guide from Matplotlib.
Designing and creating a colormap gets even harder if you are attempting to make it fit in with a theme. For example, a visualisation embedded within a dashboard or website with an existing color scheme. It’s worth putting in the extra work for a thoroughly professional end product, and this guide will help you get there.
Let’s create a test image to work with, and turn off the axis ticks to make it look a bit nicer.
Now let’s edit the image, and test out 4 different inbuilt Matplotlib colormaps.
If the Matplotlib default colormaps don’t suit your need, you can always create your own. For this tutorial I’m going to assume you have some colors you’d like to use in a colormap. If not, scroll down to the bottom for some resources to help choose your colors.
If you have a specific set of colors to use based on a brand or website theme, chances are they’ll be in HEX format. So first up let’s define some functions to convert HEX to RGB, and RGB to Decimal (value between 0 and 1 for each of RBG channels).
My HEX colors are shown below, along with their RGB equivalents (the code I used to generate this image is here).
Let’s create a continuous colormap containing all of the colors above. We’ll be using the matplotlib.colors function called LinearSegmentedColormap. This function accepts a dictionary with a red, green and blue entries. Each entry should be a list of x, y0, y1 tuples, forming rows in a table. So, if you want red to increase from 0 to 1 over the bottom half, green to do the same over the middle half, and blue over the top half. Then you would use:
cdict = {'red':   [(0.0,  0.0, 0.0),                   (0.5,  1.0, 1.0),                   (1.0,  1.0, 1.0)],         'green': [(0.0,  0.0, 0.0),                   (0.25, 0.0, 0.0),                   (0.75, 1.0, 1.0),                   (1.0,  1.0, 1.0)],         'blue':  [(0.0,  0.0, 0.0),                   (0.5,  0.0, 0.0),                   (1.0,  1.0, 1.0)]}
Confused? I was too. So I wrote some code (below) to wrap this function and make it more manageable. The code below can be used to map between an arbitrary number of hex colors in a list, it uses the functions we defined earlier to convert from hex to decimal.
By providing a list of floats from 0 to 1 we can also map the colors to specific locations on the colorbar, in order to stretch the representations of certain parts of the map.
We can also use this code to create a diverging colormap, which is useful if our data is to be displayed about some midpoint, like zero. If the data is not equally centred about the midpoint, for example if it ranges from -2 to 5, we need to shift the centre of the colormap to the midpoint of our data. The code below shows how to do this by using TwoSlopeNorm to create a norm, which is then used within imshow to scale the data to the [0, 1] range before mapping to colors.
Keep in mind that, while I won’t go in to detail in this post, your choice of colors goes beyond mere aesthetics, there is a whole field dedicated to to understanding the effect of different colors and combinations on human understanding. There is also the consideration of how your colormap would look to people with color blindness. You should consider both of these things when choosing your colors.
If you’re in need of some inspiration in choosing your colors, here are some sources I find helpful.
CoolorsCoolors is a fantastic app with so many features. For the purpose of creating a continuous colorscale I prefer their color gradient generation service, which has tonnes of beautiful color palettes that transition well in to continuous scales, and can be tweaked to suit your needs.
Gregor Aisch’s ChromaChroma is useful for optimizing your color palettes. It can be a little bit buggy, but it helps you take two or more colors and generate a full scale of in-between values. It also helpfully tells you whether your scale is colorblind safe.
W3schools color palettesThis has some nice example color palettes. W3 also provides other free services to choose palettes based on color theory, convert between different color formats (e.g. Hex, RGB etc), and lots of other helpful tools.
Hayk An’s color scale generatorI stumbled across this color scale generator during my last project. It’s a great resource where you can generate random, visually pleasing color scales, and then adjust their properties, including adding a larger range of colors and adjusting things like saturation and lightness.
Checkout my GitHub for the code for this tutorial.