How can I change the column colors of a stacked pyplot chart to indicate whether another column is true or false?
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Over a Mysterious Island Looping
--
Chapters
00:00 Question
01:58 Accepted answer (Score 2)
02:19 Answer 2 (Score 2)
03:34 Thank you
--
Full question
https://stackoverflow.com/questions/6514...
Question links:
[image]: https://i.stack.imgur.com/tvKjQ.png
[Color matplotlib bar chart based on value]: https://stackoverflow.com/questions/3347...
Accepted answer links:
[image]: https://i.stack.imgur.com/cOlVi.png
Answer 2 links:
[image]: https://i.stack.imgur.com/RqUyj.png
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #pandas #matplotlib #colors #barchart
#avk47
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Over a Mysterious Island Looping
--
Chapters
00:00 Question
01:58 Accepted answer (Score 2)
02:19 Answer 2 (Score 2)
03:34 Thank you
--
Full question
https://stackoverflow.com/questions/6514...
Question links:
[image]: https://i.stack.imgur.com/tvKjQ.png
[Color matplotlib bar chart based on value]: https://stackoverflow.com/questions/3347...
Accepted answer links:
[image]: https://i.stack.imgur.com/cOlVi.png
Answer 2 links:
[image]: https://i.stack.imgur.com/RqUyj.png
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #pandas #matplotlib #colors #barchart
#avk47
ACCEPTED ANSWER
Score 2
There may be a better approach, but here is one using a loop:
for idx, row in df.iterrows():
color = ['tab:blue', 'tab:orange'] if row['restricted'] else ['tab:blue', 'tab:red']
plt.bar(row['Country'], row['V1%'], color=color[0])
plt.bar(row['Country'], row['V2%'], bottom=row['V1%'], color=color[1])
Output:
ANSWER 2
Score 1
Probably this is not the most beautiful approach, but it works. I'm using the keyword argument color from the plot method. As argument, we can you a dictionary based on the 'restricted' condition. I've use some buint-in colors defined in matplotlib colormaps, but you can use the colors of your choice, of course:
from matplotlib import cm
palette1 = cm.get_cmap('autumn', 2)
palette2 = cm.get_cmap('winter', 2)
colors = {
'V1': [palette1(0) if restricted else palette2(0) for restricted in df['restricted']],
'V2': [palette1(1) if restricted else palette2(1) for restricted in df['restricted']]
}
xx = df.plot(kind="bar", x='Country', stacked=True, color=colors, legend=False, figsize=(20, 10))
Since this messes up the default legend, I've tried making one (not the prettiest, though):
from matplotlib.lines import Line2D
custom_legend = [
Line2D([0], [0], color=palette1(0), lw=3),
Line2D([0], [0], color=palette1(1), lw=3),
Line2D([0], [0], color=palette2(0), lw=3),
Line2D([0], [0], color=palette2(1), lw=3),
]
plt.legend(custom_legend, ['V1 (Restricted)',
'V2 (Restricted)',
'V1 (Non-Restricted)',
'V2 (Non-Restricted'])
plt.show()
This gives us the following plot as output:

