3

I am using seaborn to make a colormap and using the below code:

import seaborn as sns

cmap = sns.color_palette("dark:#034694", as_cmap=True)

Now I want the list of all the color-codes from this cmap, its type is matplotlib.colors.LinearSegmentedColormap. What should I do to get all the color-codes from the variable cmap.

slothfulwave612
  • 1,349
  • 9
  • 22
  • Maybe this link might help: https://python-graph-gallery.com/100-calling-a-color-with-seaborn/ – mpx Feb 12 '21 at 12:02
  • This gives all the colors seaborn has like black, red, blue etc, instead I want all the color codes for the `cmap` variable that I created using the above script. – slothfulwave612 Feb 12 '21 at 12:04
  • Does this answer your question? [Extract RGB or 6 digit code from Seaborn palette](https://stackoverflow.com/questions/38249454/extract-rgb-or-6-digit-code-from-seaborn-palette) – mpx Feb 12 '21 at 12:06
  • No, it says `'LinearSegmentedColormap' object is not iterable` when I tried the first answer. – slothfulwave612 Feb 12 '21 at 12:10
  • `LinearSegmentedColormap` is generative, it doesn't contain a defined set of color codes that you could get "all" of. It might help if you give some more context for what you're trying to do. – mwaskom Feb 12 '21 at 12:24
  • @mwaskom I don't understand this comment. `cmap.N` provides us with the number of colors of the `LinearSegmentedColormap` (256 in this case), so why does it not contain a defined set of colors? Strangely enough, `sns.color_palette("dark:#034694").as_hex()` contains only 6 entries. Why does the matplotlib `LinearSegmentedColormap` consists then of 256 entries? – Mr. T Feb 12 '21 at 12:53
  • 1
    @Mr.T Internally there is a lookup table with a defined resolution, but it's a private attribute. If you want a defined number of discrete hex colors from `seaborn.color_palette`, generally you would not add `as_cmap=True`. That's why I'm trying to understand the context of the question better. – mwaskom Feb 12 '21 at 15:06
  • I want to extract the color-codes from a color-pallete. The below solution answers the question. Just I have to use `mpl.colors.rgb2hex()` method on the list values to get the color codes. – slothfulwave612 Feb 12 '21 at 17:56
  • But why add `as_cmap`? You get the color codes directly if you don't do that. – mwaskom Feb 12 '21 at 18:03
  • If I just do this `sns.color_palette("dark:#034694")`, it is giving me a colorbar, instead I want all the color-codes used in building that colorbar – slothfulwave612 Feb 12 '21 at 18:06
  • 1
    You mean like the already mentioned: `sns.color_palette("dark:#034694").as_hex()`? – Mr. T Feb 12 '21 at 19:50
  • Ah! it seems that there are multiple ways to do it. This code is again returning R,G,B and A values then again we have to use `mpl.colors.rgb2hex() ` to get the hexcodes. – slothfulwave612 Feb 12 '21 at 19:56
  • 1
    `print(sns.color_palette("dark:#034694").as_hex())` returns `['#23262d', '#1d2c41', '#163356', '#10396b', '#09407f', '#034694']`, not sure why you think these are RGBA values. – Mr. T Feb 12 '21 at 19:59
  • Oh! I was trying without the print statement in the jupyter notebook and it was giving me a colorbar. Also your code only gives 6 hex-codes. But the below answer is giving all the hexcodes that are in the color-palette. So, I think the below solution answers the question better. – slothfulwave612 Feb 13 '21 at 14:18

1 Answers1

0

clumsy workaround

The idea is to get more colors than are contained in the colormap and then limit the result to the unique colours.

list(set([cmap(a) for a in np.linspace(0,1,1000)]))

longer answer

looking into the source we can see that LinearSegmentedColormap inherits from Colormap, meaning that the __call__ method of Colormap will be executed when we do something like cmap(0.5).

Looking at this method:

    def __call__(self, X, alpha=None, bytes=False):
        
        [...]
        
        if not self._isinit:
            self._init()

        [...]

        if bytes:
            lut = (self._lut * 255).astype(np.uint8)
        else:
            lut = self._lut.copy()  # Don't let alpha modify original _lut.

        [...]

        rgba = lut[xa]
        if not np.iterable(X):
            # Return a tuple if the input was a scalar
            rgba = tuple(rgba)
        return rgba
[omissions mine]
   

we can see that the lookup table self._lut is initialised by self._init(), stored in lut and optionally scaled.

i could not find when exactly _init() is defined.

in any case, we can call _init() and then access the lookup table:

cmap = sns.color_palette("dark:#034694", as_cmap=True)
cmap._init()

rgbas = cmap._lut

and then convert to hex as pointed out in your comment

hexes = [matplotlib.colors.rgb2hex(x) for x in rgbas]
warped
  • 8,947
  • 3
  • 22
  • 49