Search code examples
python-3.xmatplotlibcolor-blindness

List of color names for matplotlib style 'tableau-colorblind10'


As a colorblind person I find the matplotlib sytle 'tableau-colorblind10' great to work with. It is as simple as adding to your code these lines: import matplotlib.pyplot as plt plt.style.use('tableau-colorblind10')

I can easily distinguish the colors from each other, however I have difficulties naming the colors when I'm showing the plots to my colleagues.

Does Matplotlib have color names (non hex code) for this sytle? I only found a handful of colors that have official names (strings such as 'blue', 'red', etc.) associated with them.

Anyway, the matplotlib hex codes for the tableau-colorblind10 style are here. And this very useful website tells you the color names from its HEX code (or RGB or HSB)

Using both, here's the list of color names for 'tableau-colorblind10' matplotlib sytle:

Hex Color name/hue
'006BA4' Cerulean/Blue
'FF800E' Pumpkin/Orange
'ABABAB' Dark Gray/Gray
'595959' Mortar/Grey
'5F9ED1' Picton Blue/Blue
'C85200' Tenne (Tawny)/Orange
'898989' Suva Grey/Grey
'A2C8EC' Sail/Blue
'FFBC79' Macaroni And Cheese/Orange
'CFCFCF' Very Light Grey/Grey

Hope some of you find this as useful as I did.


Solution

  • UPDATE

    There are numerous possible colors can be displayed on your screen among which few are named by human with a human-readable name. Therefore you can hardly get a unique name from any possible RGB value or hex code. However, if you really need a method, there's a way based on KNN algorithm.

    Infer Human-Readable Names for Any Possible Colors

    I encapsuled a class with all CSS name data stored in matplotlib.colors and implemented a KNN algorithm in it like this:

    import matplotlib.colors as mcolors
    import numpy as np
    from sklearn.neighbors import NearestNeighbors
    
    class NearestColorNames:
        def __init__(self,n_neighbors=3):
            cnames = mcolors.CSS4_COLORS
            self.names = np.array(list(cnames.keys()))
            rgb_arr = np.array([mcolors.to_rgb(hex) for hex in cnames.values()])
            self.knn = NearestNeighbors(n_neighbors=n_neighbors)
            self.knn.fit(rgb_arr)
        
        def get_nearest_rgb(self,rgb_tpl,return_string=False):
            dists,ids = self.knn.kneighbors([rgb_tpl])
            names = self.names[ids[0]]
            result = {
                name:dist
                for name,dist in zip(names,dists[0])
            }
            if return_string:
                return ", ".join([f"{name}({dist:.3f})" for name,dist in result.items()])
            else:
                return result
        
        def get_nearest_hex(self,hex_code,return_string=False):
            if not hex_code.startswith("#"):
                hex_code = "#"+hex_code
            return self.get_nearest_rgb(mcolors.to_rgb(hex_code),return_string=return_string)
    

    And when it goes to your specific question, you just do this:

    names_picker = NearestColorNames(3)
    for color in ['006BA4', 'FF800E', 'ABABAB', '595959', '5F9ED1', 'C85200', '898989', 'A2C8EC', 'FFBC79', 'CFCFCF']:
        names = names_picker.get_nearest_hex(color,return_string=True)
        print(color,names)
    

    You can see the result is:

    006BA4 darkcyan(0.159), teal(0.163), steelblue(0.296)
    FF800E darkorange(0.072), orange(0.155), chocolate(0.208)
    ABABAB darkgray(0.014), darkgrey(0.014), silver(0.143)
    595959 dimgrey(0.109), dimgray(0.109), darkslategray(0.174)
    5F9ED1 cornflowerblue(0.117), steelblue(0.186), cadetblue(0.192)
    C85200 chocolate(0.153), darkgoldenrod(0.218), orangered(0.222)
    898989 grey(0.061), gray(0.061), lightslategrey(0.095)
    A2C8EC lightsteelblue(0.079), lightblue(0.080), skyblue(0.109)
    FFBC79 lightsalmon(0.110), burlywood(0.141), sandybrown(0.143)
    CFCFCF lightgray(0.027), lightgrey(0.027), thistle(0.080)
    

    The algorithm helps you find k nearest named colors in the RGB color space (you can specify the value of k whatever you want, and here in my above code k=3), return the distance and the names for you. For example:

    006BA4 darkcyan(0.159), teal(0.163), steelblue(0.296)
    

    This line means the color #006BA4 is nearest darkcyan and also similar with teal, besides those two colors, is also slightly like steelblue, according to the distances specified in breckets.


    There's a _color_data.py file in matplotlib stores all the color names and its hex code. I suppose that's what you want and you can either check it directly here on github or do something like this:

    >>> from matplotlib import _color_data
    >>> dir(_color_data)
    ['BASE_COLORS', 'CSS4_COLORS', 'TABLEAU_COLORS', 'XKCD_COLORS', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
    

    where BASE_COLORS, CSS4_COLORS, ... are all dicts with human-readable names as keys and hex codes or rgb tuples as values.