Skip to content

Instantly share code, notes, and snippets.

@jakevdp
Last active March 8, 2024 14:54
Show Gist options
  • Save jakevdp/91077b0cae40f8f8244a to your computer and use it in GitHub Desktop.
Save jakevdp/91077b0cae40f8f8244a to your computer and use it in GitHub Desktop.
Small utility to create a discrete matplotlib colormap
# By Jake VanderPlas
# License: BSD-style
import matplotlib.pyplot as plt
import numpy as np
def discrete_cmap(N, base_cmap=None):
"""Create an N-bin discrete colormap from the specified input map"""
# Note that if base_cmap is a string or None, you can simply do
# return plt.cm.get_cmap(base_cmap, N)
# The following works for string, None, or a colormap instance:
base = plt.cm.get_cmap(base_cmap)
color_list = base(np.linspace(0, 1, N))
cmap_name = base.name + str(N)
return base.from_list(cmap_name, color_list, N)
if __name__ == '__main__':
N = 5
x = np.random.randn(40)
y = np.random.randn(40)
c = np.random.randint(N, size=40)
# Edit: don't use the default ('jet') because it makes @mwaskom mad...
plt.scatter(x, y, c=c, s=50, cmap=discrete_cmap(N, 'cubehelix'))
plt.colorbar(ticks=range(N))
plt.clim(-0.5, N - 0.5)
plt.show()
@zafarali
Copy link

This piece of code has literally saved me so much time, thank you very much for sharing!

@paulaceccon
Copy link

Really nice example!

@jameswinegar
Copy link

Very useful for several projects I am working on.

@pkaf
Copy link

pkaf commented Oct 29, 2015

fantabulous !

@TomCMM
Copy link

TomCMM commented Nov 14, 2015

Thanks it helps :)

@arganish
Copy link

this is awesome, thank you!

@celiacintas
Copy link

awesome!!!

@Zsailer
Copy link

Zsailer commented Aug 18, 2016

Super useful. Thanks!

Minor bug -- if you leave the base_cmap keyword argument as None, it raises this error:

AttributeError: 'ListedColormap' object has no attribute 'from_list'

Edit: Just realized that you mentioned this in the commented line. Sorry!

@spthm
Copy link

spthm commented Nov 26, 2016

Thanks, this is great! I did however notice that it doesn't work for the perceptually uniform colormaps (at least, not in 1.5.1) because they are ListedColormap instances.

Replacing return base.from_list(cmap_name, color_list, N) with return LinearSegmentedColormap.from_list(cmap_name, color_list, N) is sufficient (LinearSegmentedColormap is in matplotlib.colors).

@paramoreta
Copy link

This is brilliant. Thanks a lot for the time saved. :)

@trontrytel
Copy link

Thank you for sharing this! This is great and simple. A function like this should be part of matplotlib.

@smba
Copy link

smba commented Aug 3, 2018

This is exactly what I was looking for, glad you shared your ideas! Thanks a lot!

Copy link

ghost commented Mar 7, 2019

Thanks a lot for this guide. But I have a question. How to handle the guide when you want your colorbar from 3 to 6 as an example? Because in your code it always starts with 0.

@egpbos
Copy link

egpbos commented Aug 27, 2019

Not sure why, but it doesn't actually work for me. I had to replace the final line in the function with return ListedColormap(color_list, name=cmap_name).

@chagaz
Copy link

chagaz commented Mar 3, 2021

Thanks!

I received a ValueError complaining that cmap_name was not a valid value for name; supported values are (followed by the list of predefined color map names).
To fix it, I had to register the colormap. Specifically, I replaced return base.from_list(cmap_name, color_list, N) with

custom_cmap = base.from_list(cmap_name, color_list, N)
plt.cm.register_cmap(name=cmap_name, cmap=custom_cmap)
return custom_cmap

@cvanelteren
Copy link

This worked for me

def discrete_cmap(N, base_cmap=None):
    """Create an N-bin discrete colormap from the specified input map"""

    # Note that if base_cmap is a string or None, you can simply do
    #    return plt.cm.get_cmap(base_cmap, N)
    # The following works for string, None, or a colormap instance:

    base = plt.cm.get_cmap(base_cmap)
    color_list = base(np.linspace(0, 1, N, 0))
    cmap_name = base.name + str(N)
    return plt.cm.colors.ListedColormap(color_list, color_list, N)

@fraclad
Copy link

fraclad commented May 3, 2021

Exactly what I need! Thank you so much for sharing!

@ionymikler
Copy link

Incrediubly great snippet, thanks a lot.
I have a qustion though.
How would you go about inputting your own list of discreet colors?

@ShazAlvi
Copy link

ShazAlvi commented Mar 8, 2024

Thank you so much for this piece of code!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment