0

Last update: I figured it out by looking at a million different stackoverflow posts.

  1. To turn off the scientific notation for tick labels, I added:
    ax.ticklabel_format(useOffset=False,style='plain')
    ax.get_yaxis().set_major_formatter(matplotlib.ticket.FuncFormatter(lambda y, pos: f'{y:,.0f}'))

  2. To turn off the scientific notation for bar_label, I added:
    for container in ax.containers:
    ax.bar_label(container,label_type="center",labels=[f'{x:,.0f}' for x in container.datavalues]

  3. To plot the bars as stacked instead of overlapping, I added:
    p2=ax.bar(pivot.index,pivot['Unrecovered'], bottom=pivot['Paid'], label="Unrecovered")

2nd Update: I upgraded matplotlib to version 3.5.1. As a result, the value labels are showing up but they are still in scientific notation. See screenshot below
enter image description here
Update: Based on user's comments below, I read through the bar_label demo from matplotlib, which was super helpful, and re-wrote my python code to mimic the bar_label demo.

However, I've run into the following problems with my new code:

  1. I'm still not getting value labels and getting an AttributError: 'AxesSupplot' object has no attribute 'bar_label'
  2. It is not plotting Paidfor Fiscal Year = 2022
  3. Y-axis is using scientific notation and I want the ax.set_ylim(0,10000000)

See screenshot of my new code belowenter image description here

Can someone help me debug these issues? Thank you!

Original Post question:

I have a pivot table called claims where the index = 'fiscal years' and the values = {'Claim', 'Paid'}.

pivot = claims.pivot_table(values={'Claim','Paid'}, index='Fiscal Year', aggfunc='sum') claim.pivot_table

I then added calculated values to the pivot table to show 'Unrecovered' and 'Recovered' where 'Recovered' is the percentage of 'Paid' divided by 'Claim'

pivot['Unrecovered'] = pivot['Claim] - pivot['Paid']
pivot['Recovered'] = ((pivot['Paid] / pivot['Claim']) * 100)
Calculate recovered vs. unrecovered

Using the pivot table, I created a stacked bar chart where x = 'Fiscal year' and y = {'Paid' 'Unrecovered'} and with secondary y-axis showing % Recovered

ax = pivot.plot(y = ['Paid','Unrecovered'],kind='bar',rot=0,stacked = True,ylabel = "Amount ($)")

Now I format the y-axis tick labels with commas
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda y, pos: f'{y:,.0f}'))

And then I add line over stacked bar chart where y ='Unrecovered'

ax1 = pivot.reset_index()["Recovered"].plot(secondary_y = True,color = 'k',marker = 'o')
ax1.set_ylabel("Recovered (%)") # adds a label to the second y-axis
ax1.set_ylim(0,100) # forces the y-axis to show 0 thru 100 instead of decimals

This section below is where I have been trying to add value labels to the stacked bar chart using 'plt.annotate' but nothing actually appears in the chart

for x,y in zip():label = '{:.0f}'.format(y)
plt.annotate(label,(x,y), textcoords="offset points",xytext=(0,10),ha='center')

plt.show()
plot stacked bar chart

I want to add value labels to the stacked bar chart showing the amount for each fiscal year in the center of the bars.

I have tried so many solutions but none seem to work for me. My latest attempt uses plt.annotate but nothing appears in the bar chart.

I will really appreciate if someone could help guide me through this!!

Niki
  • 13
  • 4
  • This seems promising: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar_label.html – Paul H Apr 14 '22 at 16:44
  • If that doesn't, here's an old answer: https://stackoverflow.com/questions/19917587/matplotlib-advanced-bar-plot/19919397#19919397 – Paul H Apr 14 '22 at 16:46
  • Neither of those two links seems to fix my issue. I tried to use `ax.bar(left=pivot.index,height='Paid',align='center)` but I get an error message that says `bar() missing 1 required positional argument: 'x'` but nothing I try makes the error go away. – Niki Apr 14 '22 at 17:13
  • I also tried entering `x='Fiscal Year'` but then I get an error message saying that `'Rectangle' object has no property 'left'` – Niki Apr 14 '22 at 17:19
  • "Paid" is a string labeling a column in your dataframe, but you didn't pass the dataframe to `ax.bar`. – Paul H Apr 14 '22 at 19:00
  • I changed it to `ax['Paid']` and now I get a new error `TypeError: 'AxesSubplot' object is not subscriptable.` – Niki Apr 14 '22 at 20:11
  • `ax` is a Matplotlib object. Your data is in a pandas dataframe called `pivot`. There's no inherent relationship between the two. – Paul H Apr 14 '22 at 20:41
  • ok. I'm not sure what to do with that info. – Niki Apr 14 '22 at 21:13
  • I recommend you read the Matplotlib docs on bar plots. Here's an official example which includes the use of `bar_label`: https://matplotlib.org/3.5.0/gallery/lines_bars_and_markers/bar_label_demo.html#sphx-glr-gallery-lines-bars-and-markers-bar-label-demo-py – Paul H Apr 14 '22 at 21:18
  • I have read through the `bar_label` demo from matplotlib which is super helpful. I re-wrote my python code to mimic the bar_label demo but I'm still getting an `AttributError: 'AxesSupplot' object has no attribute 'bar_label'`. I'll update my question with my latest attempt. – Niki Apr 19 '22 at 17:30
  • `bar_label` is pretty new. I bet you need to update your version of Matplotlib – Paul H Apr 19 '22 at 17:35
  • my env is using `matplotlib version = 3.3.1` – Niki Apr 19 '22 at 18:12
  • I just upgraded `matplotlib_version ==3.5.1` and now the value labels are showing but they are showing in scientific notation. Anyway to force the y-axis and value labels to display with formatting? – Niki Apr 19 '22 at 18:50
  • y-axis formatting is covered in a lot of question on this site – Paul H Apr 19 '22 at 19:35
  • Ok. Do you think you can help me debug why `Paid` is overlapping `Unrecovered`? – Niki Apr 20 '22 at 14:36
  • I figured it out by searching other stackoverflow posts. – Niki Apr 20 '22 at 15:12

0 Answers0