如何用总值的百分比标记堆积条形图的每个条形图?

How to label each bar of a stacked bar plot with percentage of total values?

我正在尝试绘制堆积条形图,其中绘制了我的数据,如下图所示。 标签是每个容器的确切值。我想将这些放在每个柱 总值 百分比值 中。到目前为止,我没有这样做。将不胜感激。

这是标签的代码:

for i, rect in enumerate(ax.patches):
    # Find where everything is located
    height = rect.get_height()
    width = rect.get_width()
    x = rect.get_x()
    y = rect.get_y()
    label_text = f"{height:.02f}"

    label_x = x + width / 2
    label_y = y + height / 2
    ax.text(
        label_x,
        label_y,
        label_text,
        ha="center",
        va="center",
        fontsize=4,
        weight="bold",
    )

给定以下玩具数据框:

import pandas as pd
from matplotlib import pyplot as plt

df = pd.DataFrame(
    {
        "A": {2019: 125, 2020: 124, 2021: 50, 2022: 63},
        "B": {2019: 129, 2020: 40, 2021: 85, 2022: 47},
        "C": {2019: 126, 2020: 95, 2021: 51, 2022: 44},
        "D": {2019: 99, 2020: 120, 2021: 106, 2022: 117,},
    }
)
print(df)
# Output
        A    B    C    D
2019  125  129  126   99
2020  124   40   95  120
2021   50   85   51  106
2022   63   47   44  117

这是一种方法:

# Setup figure
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(7, 4))

# Add bars
ax.bar(df.index, df["A"], label="A")
ax.bar(df.index, df["B"], bottom=df["A"], label="B")
ax.bar(df.index, df["C"], bottom=df["A"] + df["B"], label="C")
ax.bar(df.index, df["D"], bottom=df["A"] + df["B"] + df["C"], label="D")

# Add percentages as labels
for idx in df.index:
    start = 0
    for col in df.columns:
        y = df.loc[idx, col]
        value = df.loc[idx, col]
        total = df.loc[idx, :].sum()
        ax.text(
            x=idx,
            y=start + y / 2,
            s=f"{round(100 * value / total, 1)}%",
            fontsize=10,
            ha="center",
            color="w",
        )
        start += y

# Add other useful informations
plt.xticks(df.index, df.index)
ax.legend()

plt.show()

输出: