0

Question:

I have a pandas dataframe df with 6 rows representing different variables.
I want to plot the two first columns in a bar graph and I would like to use the third column score to colorize the bars based on an existing colormap, for example the matplotlib viridis one.

This dataframe looks like this:

    ID  count   score
0    4      1       3
1    5      4       4
2    5      8       5
3    3      7       2
4    1      5       5
5    1      3       4

What my code looks like for the moment:

df.plot('ID', 'count', kind='bar', figsize=(15,5), ax=plt.subplot(122), colors=cm.viridis.colors)
plt.show()

But the color of all bar is a unique purple.
I want, let say, to sample the viridis colormap proportionally to values in my score column.
Is there a simple way to achieve that?

Edit [2019-10-31]:

Using seaborn as proposed in the first answer gives me an error:

my_palette = sns.color_palette(plt.get_cmap('viridis'), 5)
sns.barplot(x="New ID", y="count", hue="Note", data=df, palette=my_palette)

The error returned:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-1943cafa0d79> in <module>
----> 1 my_palette = sns.color_palette(plt.get_cmap('viridis'), 5)

/usr/local/lib/python3.6/dist-packages/seaborn/palettes.py in color_palette(palette, n_colors, desat)
    238 
    239     # Always return as many colors as we asked for
--> 240     pal_cycle = cycle(palette)
    241     palette = [next(pal_cycle) for _ in range(n_colors)]
    242 

TypeError: 'ListedColormap' object is not iterable

Edit [2019-11-05]:

Using the proposed code lead the resulting graph to have misaligned bars with the x-ticks (which I expected to be centered under the bar on the x-axis), especially when there is only one bar per category as the next figure shows:

misaligned bars and x-ticks

In addition, I would like to be able to take into consideration 'NaN' values in the df['count'] column. Currently, if there is one 'NaN' value, it raises a:
TypeError: unsupported operand type(s) for /: 'str' and 'int'
So, I have to set this value equal to 0 even if it is NOT truly a zero.

2
  • What colour would you want if there's a NaN in 'score'? Commented Nov 6, 2019 at 10:42
  • But if there is 'NaN' in my count attribute, there is actually no bar. So, the color doesn't matter. Commented Nov 6, 2019 at 15:42

2 Answers 2

2

The simplest is to use seaborn.barplot this way:

import seaborn as sns
ax = sns.barplot(x="ID", y="count", hue="score", data=df, palette=your_palette)

You can create a palette this way:

your_palette = sns.color_palette('inferno', n_point)

where n_point are the number of different colors in your custome palette.

enter image description here

Hope it helps.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer, unfortunately this gave me an error. My version of seaborn is 0.9.0 (downloaded from PyPi using pip).
I changed the code. Sorry for the error. color_palette is a method that accepts the name of a colormap and the number of point. I tested it again and it works now.
I can see that the bars are randomly aligned with the x-ticks, this is annoying and I've search the documentation without finding anything to fix it.
I don't think they are 'randomly' aligned. The sample data you provided has two entries with id=1. How would you like these to be plotted?
1

You also can do this with matplotlib

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({
    'ID': [4, 5, 5, 3, 1, 1],
    'count': [1, 4, 5, 6, 7, 3],
    'score': [3, 4, 5, 2, 5, 4],
})

cm = plt.get_cmap('viridis')
maxval = max(df.score)

df.plot('ID', 'count', kind='bar', 
        figsize=(15,5), ax=plt.subplot(122), 
        color=cm(df.score/maxval))
plt.show()

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.