熊猫堆积的条形图出错

时间:2019-11-18 05:39:51

标签: python pandas stacked

我尝试从普通条形图更改为堆积条形图,但结果出了点问题。

数据:

                Total Monthly Actual Hours  Total Monthly Work Hours
Activity Month                                                      
Apr-19                            35381.25                     42592
May-19                            31722.50                     44528
Jun-19                            27708.50                     38720
Jul-19                            34283.50                     44528
Aug-19                            32225.60                     42592

这是正常图表:

ax = dfWorkActual.plot(kind='bar')
ax.tick_params(rotation = 0)

for date, (p, q) in enumerate(zip(dfWorkActual["Total Monthly Actual Hours"],dfWorkActual["Total Monthly Work Hours"])):
    ax.annotate(f"{round(p,2)}\n({(p/q)*100:.0f}%)", (date-0.25, p*1.02))
    ax.annotate(f"{round(q,2)}\n({(q/q)*100:.0f}%)", (date, q*1.02))

plt.ylabel('Work Hours')
plt.xlabel('Month')
plt.title("Chart 5: (Total Monthly Work Hours + Total Actual Work Hours) vs Month", fontweight='bold')

enter image description here

这是我添加stacked = True后的结果:

ax = dfWorkActual.plot(kind='bar')
ax.tick_params(rotation = 0)

for date, (p, q) in enumerate(zip(dfWorkActual["Total Monthly Actual Hours"],dfWorkActual["Total Monthly Work Hours"])):
    ax.annotate(f"{round(p,2)}\n({(p/q)*100:.0f}%)", (date-0.25, p*1.02))
    ax.annotate(f"{round(q,2)}\n({(q/q)*100:.0f}%)", (date, q*1.02))

# for p in ax.patches:
    # ax.annotate(str(round(p.get_height(), 2)), (p.get_x() * 1.005, p.get_height() * 1.005))

plt.ylabel('Work Hours')
plt.xlabel('Month')
plt.title("Chart 5: (Total Monthly Work Hours + Total Actual Work Hours) vs Month", fontweight='bold')

enter image description here

我期望的图表应该是这样的: enter image description here

1 个答案:

答案 0 :(得分:1)

您可以使用此代码先绘制较高的条,然后再绘制较低的条。不过,您必须以其他颜色绘制它们,否则它们将不会显示在图形上。

代码

fig, ax= plt.subplots()

col = dfWorkActual.columns[::-1]

color = ['y','b']

for i in range(0,len(col)):
    dfWorkActual[col[i]].reset_index().plot(kind='bar',ax=ax,x='Activity Month',color=color[i],figsize=(25,20))

for date, (p, q) in enumerate(zip(dfWorkActual["Total Monthly Actual Hours"],dfWorkActual["Total Monthly Work Hours"])):
    ax.annotate(f"{round(p,2)}\n({(p/q)*100:.0f}%)", (date-0.45, p*1.02))
    ax.annotate(f"{round(q,2)}\n({(q/q)*100:.0f}%)", (date-0.1, q*1.02))

plt.ylabel('Work Hours')
plt.xlabel('Month')
plt.title("Chart 5: (Total Monthly Work Hours + Total Actual Work Hours) vs Month", fontweight='bold')

输出

enter image description here

或者,您可以减去临时df中的差异,然后堆叠它们,我认为这更容易。

代码

df = dfWorkActual.copy()
df['Total Monthly Work Hours'] = df['Total Monthly Work Hours']-df['Total Monthly Actual Hours']

ax = df.plot(kind='bar',stacked=True,figsize=(18,15))
ax.tick_params(rotation=0)

for date, (p, q) in enumerate(zip(dfWorkActual["Total Monthly Actual Hours"],dfWorkActual["Total Monthly Work Hours"])):
    ax.annotate(f"{round(p,2)}\n({(p/q)*100:.0f}%)", (date-0.45, p*1.02))
    ax.annotate(f"{round(q,2)}\n({(q/q)*100:.0f}%)", (date-0.1, q*1.02))

plt.ylabel('Work Hours')
plt.xlabel('Month')
plt.title("Chart 5: (Total Monthly Work Hours + Total Actual Work Hours) vs Month", fontweight='bold')

输出 enter image description here