79073583

Date: 2024-10-10 09:12:40
Score: 0.5
Natty:
Report link

When creating annotations their actual position is based on their index in the dataframe not on your variable xval.

import pandas as pd
from matplotlib import pyplot as plt

data = [
    [0.0, 4.9, 19.9, 8.1, 0.0],
    [0.12, 4.5, 27.0, 10.1, 0.0],
    [0.24, 2.8, 9.3, 4.6, 0.0],
    [0.36, 2.2, 9.1, 2.7, 0.0],
    [0.48, 2.2, 7.3, 3.1, 0.0],
    [1.0, 4.9, 26.4, 11.2, 0.0],
    [1.12, 5.9, 25.3, 8.7, 0.0],
    [1.24, 3.7, 13.3, 7.1, 0.0],
    [1.36, 3.0, 9.5, 3.4, 0.0],
    [1.48, 3.2, 8.9, 4.7, 0.0],
    [2.0, 8.4, 24.8, 20.2, 0.0],
    [2.12, 9.5, 19.3, 22.5, 0.0],
    [2.24, 5.7, 11.8, 6.6, 0.0],
    [2.36, 4.1, 11.1, 5.1, 0.0],
    [2.48, 5.4, 8.0, 4.6, 0.0],
]

df = pd.DataFrame(columns=["xval", "y1", "y2", "y3", "y4"], data=data)
df1 = df.copy()
df1['total'] = df[['y1', 'y2', 'y3', 'y4']].sum(axis=1)


fig, ax = plt.subplots()
df.plot(x="xval", kind="bar", ax=ax, stacked=True, width=0.11)

padding = 0.03 #percentage, needed for putting some space between the annotations and bars

for i, x in enumerate(df1['xval']):
    total = df1['total'][i]
    ax.annotate(f'{x:.2f}-{df1["total"][i]:.2f}',
                (i, total + padding * total),  # Add padding to the y-coordinate
                rotation='vertical', 
                fontsize=10, 
                ha='center', 
                va='bottom') #set position

#set xticks and labels
ax.set_xticks(range(len(df1['xval'])))
ax.set_xticklabels([f'{x:.2f}' for x in df1['xval']])

ax.set_ylim(0, 80) #makes space for the annotations

ax.grid(False) #looks better without grid in my opinion
plt.tight_layout()
plt.show()

Result: enter image description here

Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Starts with a question (0.5): When
  • Low reputation (0.5):
Posted by: Márton Horváth