Last active
July 27, 2021 10:04
-
-
Save jsoma/c61e56819e4ae315ad5d194a630ccb23 to your computer and use it in GitHub Desktop.
A perfect easy beautiful simple way to label a stacked bar chart in Python using pandas/matplotlib. Put this in your Jupyter notebook!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# WAIT!!! | |
# WAIT!!! | |
# You probably don't need this any more! Newer versions of matplotlib | |
# can do this with built-in magic. See these StackOverflow answers: | |
# | |
# https://stackoverflow.com/questions/41296313/stacked-bar-chart-with-centered-labels/60895640#60895640 | |
# https://stackoverflow.com/questions/28931224/adding-value-labels-on-a-matplotlib-bar-chart/67561982#67561982 | |
# | |
# Big thanks to @trenton3983 for keeping us all up to date! | |
# | |
%matplotlib inline | |
import pandas as pd | |
df = pd.DataFrame({ | |
'cat': [3, 5, 4, 3, 3, 23, 4], | |
'dog': [3, 23, 4, 3, 5, 4, 3], | |
'mouse': [3, 23, 4, 3, 5, 4, 3] | |
}) | |
# Save the chart that's drawn | |
ax = df.plot(stacked=True, kind='barh', figsize=(10, 5)) | |
# .patches is everything inside of the chart, lines and | |
# rectangles and circles and stuff. In this case we only | |
# have rectangles! | |
for rect in ax.patches: | |
# Find where everything is located | |
height = rect.get_height() | |
width = rect.get_width() | |
x = rect.get_x() | |
y = rect.get_y() | |
# The width of the bar is also not pixels, it's the | |
# number of animals. So we can use it as the label! | |
label_text = width | |
# ax.text(x, y, text) | |
label_x = x + width / 2 | |
label_y = y + height / 2 | |
ax.text(label_x, label_y, label_text, ha='center', va='center') |
Hi! This was so helpful for me! I was wondering if you guys had advice on getting the label_text = to equal a different column in the data frame?Such that each data label is a cell in the same row as each rectangle but a different column.
- You will need to find a way to select the data from the other column, if the index is the same as the column plotted, then you can enumerate the loop, and use
i
to select the data from the other column.
for i, rect in enumerate(ax.patches):
desired_value = df.iloc[i, desire_col_idx]
Praise be to the matplotlib gods! Thanks a zillion for posting this, just updated the original!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi! This was so helpful for me! I was wondering if you guys had advice on getting the label_text = to equal a different column in the data frame?Such that each data label is a cell in the same row as each rectangle but a different column.
I have tried the following and a few other random code attempts with no luck. Any advice?
My full code is here:
The following code to create a dataframe and remove duplicated rows is always executed and acts as a preamble for your script:
dataset = pandas.DataFrame(Industrial Opps.OpportunityName, MP Count, REQ_DATE, RA)
dataset = dataset.drop_duplicates()
Paste or type your script code here:
import matplotlib.pyplot as plt
ax=dataset.groupby(['REQ_DATE','Industrial Opps.OpportunityName']).sum().unstack().plot(kind='bar', y='MP Count', stacked=True, figsize=(20, 10))
ax.set_xlabel("Demand Date", labelpad=20, weight='bold', size=25)
ax.set_ylabel("MP Count", labelpad=20, weight='bold', size=25)
.patches is everything inside of the chart, lines and
rectangles and circles and stuff. In this case we only
have rectangles!
for rect in ax.patches:
# Find where everything is located
height = rect.get_height()
width = rect.get_width()
x = rect.get_x()
y = rect.get_y()
plt.show()