0

How to assign different colors to the indices of a barh plot in pandas.DataFrame.plot ? I have a dataframe:

group      clicks_per_visit     bookings_per_visit     rev_per_visit
test1          0.90                0.039                   0.737
test2          0.87                0.034                   0.726

I plot this using:

temp3.plot(kind='barh',subplots=True,grid=True,figsize=(10,7))

to get this plot:

enter image description here

I want the bars to have different colors to highlight the different test groups and I am also open to any other ideas or solutions to make a more 'fancy' visualization of this data.

JohanC
  • 71,591
  • 8
  • 33
  • 66
N91
  • 395
  • 1
  • 3
  • 14
  • Does this help? https://stackoverflow.com/questions/44493417/pandas-dataframe-bar-plot-plot-bars-different-colors-from-specific-colormap – KyleL Mar 27 '20 at 12:16
  • I tried that, it does not work for me. maybe some other lib/package like sns or matplotlib has this flexibility – N91 Mar 27 '20 at 12:25

2 Answers2

2

The behavior of pandas' DataFrame.plot() can be complicated and not always intuitive. In theory, you can pass an array of colors to plot(), which will be passed to the underlying plotting function.

In fact, since you are plotting 3 subplots, you would pass a list of 3 sub-lists, each containing the colors of each of your bars.

df.plot(kind='barh', subplots=True,grid=True,figsize=(10,7), color=[['C0','C1']]*3, legend=False)

However, doing this causes the labels on the y-axis to disappear. For some reason, you have to specify the names of the columns you want to use in the call to plot() to get the to appear again.

df.plot(kind='barh',x='group', y=['clicks_per_visit','bookings_per_visit','rev_per_visit'], subplots=True,grid=True,figsize=(10,7), color=[['C0','C1']]*3, legend=False)

enter image description here

Since you are asking for other visualization options, I can show you that you can get roughly the same output, with an easier syntax using seaborn. The only "catch" is that you have to "stack" your dataframe to be long-form instead of wide-form

df2 = df.melt(id_vars=['group'],value_vars=['clicks_per_visit', 'bookings_per_visit', 'rev_per_visit'])
plt.figure(figsize=(8,4))
sns.barplot(y='variable',x='value',hue='group', data=df2, orient='h')
plt.tight_layout()

enter image description here

Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
0

You can do this, it is a very manual way but it will work:

axes = temp3.plot(kind='barh',subplots=True,grid=True,figsize=(10,7))

axes[0].get_children()[0].set_color('r')

This will assign the second bar from the first axis as red, then you can choose the other ones by getting the other axis and children.

Bruno Mello
  • 4,448
  • 1
  • 9
  • 39