Reputation: 4336
I have list of numbers, and want to assign a color for each of them from the ylorbr
colormap in python.
If my intuition of a colormap is correct, its just a range of colors - so, ylorbr
goes from yellow to orange to brown.
I just want to get n
equally spaced tuples of colors from this colormap, starting from 0
(in this case, that is yellow).
This is the simple code I tried:
from matplotlib import cm
import numpy as np
ylorbr = cm.get_cmap('YlOrBr', 8)
x = ylorbr(np.arange(0,1,0.1))
print(x)
When I try this, x
is not a set of evenly spaced colors - in fact, colors are repeated. I also could not find other solutions for this - or there may be, but I am new to plotting.
I am new to plotting, but not new to python. Is there a reason, why getting a simple list of evenly spaced RGB from a given colormap is hard? I used "python sense" to do the above test, and actually expected an evenly spaced list of RGB tuples.
Can someone tell me how then a colormap works in python, and how to simply assign n
sorted integers to n
colors from a colormap in the shortest way possible?
Edit : I assumed here, that colormap is a discrete list of colors. I just want the first item , last item and every item at 1/n of that list of colors.
Edit2 : Based on Mark's comment below, I tried to access the list of colors of a map using the .colors
attribute after get_cmap
. But while it works when the colormap is viridis
, it does not work when I set it to YlOrBr
and I get the error : 'LinearSegmentedColormap' object has no attribute 'colors'
Upvotes: 2
Views: 3871
Reputation: 21947
Colormaps have a resampled
function, about what you want
(but interpolating in RGB space can give you ugly colors, make color connoisseurs cry)
#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as pl
from matplotlib.colors import Colormap, ListedColormap, LinearSegmentedColormap # ? in ipython
def cmaparray( cmap: Colormap ) -> "N x 3 rgb array":
# only ListedColormap has .colors, this works for both Listed and Linseg
return cmap( np.linspace( 0, 1, cmap.N )) [:,:3]
def printcmap( cmap: Colormap ):
print( f"{cmap.name} len {cmap.N}:" )
print( cmaparray( cmap ).T, "\n" )
#...............................................................................
if __name__ == "__main__":
np.set_printoptions( precision=2 )
print( 80 * "▄" )
cmapname = "YlOrBr" # Linseg
# cmapname = "viridis" # ListedColormap
nin = 8
nout = 10
print( f"params: {cmapname = } {nin = } {nout = } \n" )
cmap = pl.get_cmap( cmapname, nin ) # ListedColormap / LinearSegmentedColormap
printcmap( cmap )
sample = cmap.resampled( nout ) # does np.interp ? no dups
sample.name = "sample"
printcmap( sample )
Upvotes: 0
Reputation: 54698
You asked it to make a colormap with 8 entries. It shouldn't be surprising that you get repeats when you ask for 10 results.
I can hear you screaming "arrgggh" from here.
Upvotes: 3