I have the following problem, I want to create my own colormap (red-mix-violet-mix-blue) that maps to values between -2 and +2 and want to use it to color points in my plot.
The plot should then have the colorscale to the right.
That is how I create the map so far. But I am not really sure if it mixes the colors.
cmap = matplotlib.colors.ListedColormap(["red","violet","blue"], name='from_list', N=None)
m = cm.ScalarMappable(norm=norm, cmap=cmap)
That way I map the colors to the values.
colors = itertools.cycle([m.to_rgba(1.22), ..])
Then I plot it:
for i in range(0, len(array_dg)):
plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next())
My problems are:
1. I can't plot the color scale.
2. I am not completely sure if my scale is creating a continues (smooth) colorscale.
This question is related to
python
matplotlib
plot
Since the methods used in other answers seems quite complicated for such easy task, here is a new answer:
Instead of a ListedColormap
, which produces a discrete colormap, you may use a LinearSegmentedColormap
. This can easily be created from a list using the from_list
method.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
x,y,c = zip(*np.random.rand(30,3)*4-2)
norm=plt.Normalize(-2,2)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["red","violet","blue"])
plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()
More generally, if you have a list of values (e.g. [-2., -1, 2]
) and corresponding colors, (e.g. ["red","violet","blue"]
), such that the n
th value should correspond to the n
th color, you can normalize the values and supply them as tuples to the from_list
method.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
x,y,c = zip(*np.random.rand(30,3)*4-2)
cvals = [-2., -1, 2]
colors = ["red","violet","blue"]
norm=plt.Normalize(min(cvals),max(cvals))
tuples = list(zip(map(norm,cvals), colors))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", tuples)
plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()
If you want to automate the creating of a custom divergent colormap commonly used for surface plots, this module combined with @unutbu method worked well for me.
def diverge_map(high=(0.565, 0.392, 0.173), low=(0.094, 0.310, 0.635)):
'''
low and high are colors that will be used for the two
ends of the spectrum. they can be either color strings
or rgb color tuples
'''
c = mcolors.ColorConverter().to_rgb
if isinstance(low, basestring): low = c(low)
if isinstance(high, basestring): high = c(high)
return make_colormap([low, c('white'), 0.5, c('white'), high])
The high and low values can be either string color names or rgb tuples. This is the result using the surface plot demo:
This seems to work for me.
def make_Ramp( ramp_colors ):
from colour import Color
from matplotlib.colors import LinearSegmentedColormap
color_ramp = LinearSegmentedColormap.from_list( 'my_list', [ Color( c1 ).rgb for c1 in ramp_colors ] )
plt.figure( figsize = (15,3))
plt.imshow( [list(np.arange(0, len( ramp_colors ) , 0.1)) ] , interpolation='nearest', origin='lower', cmap= color_ramp )
plt.xticks([])
plt.yticks([])
return color_ramp
custom_ramp = make_Ramp( ['#754a28','#893584','#68ad45','#0080a5' ] )
Source: Stackoverflow.com