I'm working on creating a python visual in powerbi, where for each project i can see the 'Total estimated budget' stacked with the 'budget Updated by' amount stacked with ' Additional amount invested' and then have a smaller bar running through the stacked bars showing the current fees as they work through the budget.
I'm having problems with adding labels to each stacked bar, the first stack has labels that are fine but the 2nd and 3rd are not aligning properly - I haven't even attempted the 3rd set of labels im stuck at the 2nd.
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
# Retrieve the data and group by project name
df = dataset[['Project Name', 'Total Estimated Budget','Additional Amount Invested','Current Total of Fees & WIP','Budget updated by']].groupby('Project Name').sum().reset_index()
#sort ascending from largest budget to smallest budget project
df = df.sort_values(by='Total Estimated Budget', ascending=True)
# Create a stacked horizontal chart using Matplotlib
#Axis
fig, ax = plt.subplots(figsize=(20, 10))
# custom color palette powerbi
colors = ['#225880', '#A7A7B6', '#CDC58A','#329D9C']
#Create stacked bars
ax.barh(df['Project Name'], df['Total Estimated Budget'], color=colors[0], label='Total Estimated Budget')
ax.barh(df['Project Name'], df['Budget updated by'], left=df['Total Estimated Budget'], color=colors[1], label='Budget updated by')
ax.barh(df['Project Name'], df['Additional Amount Invested'], left=df['Total Estimated Budget'] + df['Budget updated by'], color=colors[2], label='Additional Amount Invested')
# Add the smaller red bar for Current Total of Fees & WIP through each project
ax.barh(df['Project Name'], df['Current Total of Fees & WIP'], height=0.2, align='center', color='r', label='Current Total of Fees & WIP')
#labelling for 1st stack
for i, v in enumerate(df['Total Estimated Budget']):
ax.text(v/2, i, '${:.0f}K'.format(v/1000), color = 'white')
# Output the chart
plt.show()
I tried a few things using chatgpt to help
# Add value labels to the bars
for i, v1 in enumerate(df['Annual MVE']):
ax.text(v1/2, i, '${:.1f}M'.format(v1/1000000), color='white', ha='center', va='center', fontname='Segoe UI Semibold', fontsize=50)
if df['DIFFERENCEMVEUpdatedby'][i] > 0:
v2 = df['DIFFERENCEMVEUpdatedby'][i]
ax.text(v1 + v2/2, i, '${:.0f}K'.format(v2/1000), color='white', ha='center', va='center', fontname='Segoe UI Semibold', fontsize=50)
if df['Additional Amount Invested'][i] > 0:
v3 = df['Additional Amount Invested'][i]
ax.text(v1 + df['DIFFERENCEMVEUpdatedby'][i] + v3/2, i, '${:.0f}K'.format(v3/1000), color='white', ha='center', va='center', fontname='Segoe UI Semibold', fontsize=50)
# Add the text labels for DIFFERENCEMVEUpdatedby column
for i2, v2 in enumerate(df['DIFFERENCEMVEUpdatedby']):
# Calculate the total width of the bar
total_width = df['Annual MVE'][i2] + v2
# Add the text label at the end of the bar
ax.text(total_width + 100000, i2, '${:.0f}K'.format(v2/1000), color='white')