Reputation: 611
I have a df with two columns:
I also have a colormap with four different colors that I made myself and it's a ListedColorMap object.
I want to create a bar chart with the four categories (days of the week) in the x axis and their corresponding values in the y axis. At the same time, I want each bar to have a different color using my colormap.
This is the code I used to build my bar chart:
def my_barchart(my_df, my_cmap):
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap)
return fig
However, I get the following error: "object of type 'ListedColormap' has no len()", so it seems that I'm not using my_cmap correctly.
If I remove that from the function and run it, my bar chart looks ok, except that all bars have the same color. So my question is: what is the right way to use a colormap with a bar chart?
Upvotes: 22
Views: 43328
Reputation: 611
Okay, I found a way to do this without having to scale my values:
def my_barchart(my_df, my_cmap):
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap.colors)
return fig
Simply adding .colors
after my_cmap
works!
Upvotes: 15
Reputation: 1740
The color
argument wants either a string or an RGB[A] value (it can be a single colour, or a sequence of colours with one for each data point you are plotting). Colour maps are typically callable with floats in the range [0, 1].
So what you want to do is take the values you want for the colours for each bar, scale them to the range [0, 1], and then call my_cmap
with those rescaled values.
So, say for example you wanted the colours to correspond to the y values (heights of the bars), then you should modify your code like this (assumes you have called import numpy as np
earlier on):
def my_barchart(my_df, my_cmap):
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap(rescale(my_df['y'])))
return fig
Here is a self-contained minimal example of using the color
argument with the output from a cmap
:
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
my_cmap = plt.get_cmap("viridis")
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))
plt.bar(x, y, color=my_cmap(rescale(y)))
plt.savefig("temp")
Output:
Upvotes: 21