I'm plotting some curves from a dataframe "self.data" in a class. Each column of the dataframe is a curve and the column name is written at the end of the line.
I made this program to do so:
cmap = plt.cm.get_cmap('brg', len(self.data.columns)+1)
for i in range(len(self.data.columns)): #plot curves and add legend
self.courbe.plot(self.data[self.data.columns[i]],c=cmap(i))
angle=20
self.courbe.annotate(self.data.columns[i],
xy= (max(self.data.index),self.data.at[max(self.data.index),self.data.columns[i]]),
textcoords='offset points',
xytext=(2, 0),
va='bottom',
rotation=angle,c=cmap(i))
So i used the "brg" colormap but i'd like to use only a part of this color map ( for example removing the light green part).
I tried some proposed solutions on stackoverflow like how to extract a subset of a colormap as a new colormap in matplotlib? but all curves were in the same color. Do someone knows another way to do that?
Thanks and have a good day :)
A norm
is used to map a range of numbers towards the range 0..1 needed by the colormap. We can create a special norm to get the desired effect.
A norm depends on a vmin, the lowest index, and a vmax, the highest index. vmin
would be mapped to 0 and vmax to 1.
Choosing an upper and lower color (each between 0 and 1), for example upper=0.9 to stop at the light greens in bgr. And lower=0 to get all the colors up to the dark blue.
A formula finds the vmin and vmax which would map index i=0
to the lower_color and index i=num_colors-1
to the upper_color. The formula follows from the unique linear equation which maps:
0
tolower_color
num_colors - 1
toupper_color
vmin
to0
vmax
to1
You find the color index for a value i=0..num_colors-1
as norm(i)
and the corresponding color as cmap(norm(i))
.
import matplotlib.pyplot as plt
import matplotlib as mpl
cmap = plt.cm.get_cmap('brg')
# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors = 20 # len(self.data.columns)
factor = (num_colors - 1)/(upper_color - lower_color)
norm = mpl.colors.Normalize(vmin=-lower_color*factor, vmax=(1 - lower_color)*factor)
for i in range(num_colors):
plt.plot([0, 1], [0, i], c=cmap(norm(i)))
plt.show()
An example with the brg
map and choosing colors between 0.3 and 0.8, just to show how it works. For reference, there is a colorbar with the same limits applied. And a full colorbar for brg
.
The colorbars were generated as follows:
c_map_ax = plt.gcf().add_axes([0.84, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax, cmap=cmap, orientation='vertical')
c_map_ax.axes.set_ylim(lower_color, upper_color)
c_map_ax2 = plt.gcf().add_axes([0.92, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax2, cmap=cmap, orientation='vertical')
plt.subplots_adjust(right=0.8)