12
votes

First of all, I'm pretty new to colors in Matplotlib or Seaborn. My purpose is to create a barplot with bars coloured according to a custom palette. Something like this, but with my custom palette (see below, a palette with red, orange, green and blue):

barplot

I have created my custom sequential palette using the LinearSegmentedColormap method, but I'm not able to use it in a simple plt.barplot(). Sure it's not difficult, but I can't see the way. I created the palette using the function below, got from this thread: Create own colormap using matplotlib and plot color scale

def make_colormap(seq):
"""Return a LinearSegmentedColormap
seq: a sequence of floats and RGB-tuples. The floats should be increasing
and in the interval (0,1).
"""
seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
cdict = {'red': [], 'green': [], 'blue': []}
for i, item in enumerate(seq):
    if isinstance(item, float):
        r1, g1, b1 = seq[i - 1]
        r2, g2, b2 = seq[i + 1]
        cdict['red'].append([item, r1, r2])
        cdict['green'].append([item, g1, g2])
        cdict['blue'].append([item, b1, b2])

return mcolors.LinearSegmentedColormap('CustomMap', cdict)

#main#
c = mcolors.ColorConverter().to_rgb
rvb = make_colormap(
[c('red'), 0.125, c('red'), c('orange'), 0.25, c('orange'),c('green'),0.5, c('green'),0.7, c('green'), c('blue'), 0.75, c('blue')])

N = 1000
array_dg = np.random.uniform(0, 10, size=(N, 2))
colors = np.random.uniform(0, 5, size=(N,))
plt.scatter(array_dg[:, 0], array_dg[:, 1], c=colors, cmap=rvb)
plt.colorbar()
plt.show()

That returns this plot:

plot palette ok

As far as I can understand, I can't use a colormap (object type from LinearSegmentedColormap()? ) for barplots, but colormap is the unique way I have achieved a custom sequential palette.

In summary, I want to apply the colormap of the second plot (the scatterplot) to the first plot (the barplot). For now I can't do it because the barplot() function has not an argument that accepts a LinearSegmentedColormap object type.

I'm probably making it harder than it really is, so I would appreciate any cleaner or more correct way.

2
I do not see the problem at all. The code is working fine. What exactly is the question here?ImportanceOfBeingErnest
Sorry, probably did not explain my problem enough. I want to know how to use this colormap in a barplot, like "plt.barplot(x, y, color= "my_custom_colormap"). As you can see in the first comment, the palette works fine in the scatter plot ( plt.scatter(...c = colors, cmap = rvb) ). The problem is that in the barplot function there isn't an argument like "cmap".Dani Carrillo
In your code you have a scatterplot, not a barplot. Which quantity would you like the colors in the barplot to represent? Please edit your question to reflect the problem itself, not something that is actually working fine.ImportanceOfBeingErnest
your indentation is all wrong. please fix itPaul H

2 Answers

12
votes

To obtain a barplot with the bars colored according to a colormap you can use the color argument of bar(x,y, color=colors), where colors is a list of length number of bars, containing all the colors. I.e. the ith entry in that list is the color for the ith bar.
In order to create this list from the colormap, you need to call the colormap with the respective value.

enter image description here

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np

clist = [(0, "red"), (0.125, "red"), (0.25, "orange"), (0.5, "green"), 
         (0.7, "green"), (0.75, "blue"), (1, "blue")]
rvb = mcolors.LinearSegmentedColormap.from_list("", clist)

N = 60
x = np.arange(N).astype(float)
y = np.random.uniform(0, 5, size=(N,))

plt.bar(x,y, color=rvb(x/N))
plt.show()
5
votes

Seaborn barplot is great for this, example:

ax = sns.barplot("size", y="total_bill", data=tips, palette="Blues_d")