【问题标题】:Pandas stacked bar chart went wrongPandas 堆积条形图出错了
【发布时间】:2019-11-18 05:39:51
【问题描述】:

我试图从普通条形图更改为堆叠条形图,但结果有问题。

数据:

                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')

这是我添加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')

我所期望的是图表应该是这样的:

【问题讨论】:

    标签: python pandas stacked


    【解决方案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')
    
    

    输出

    或者,您可以减去临时 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')
    

    输出

    【讨论】:

    • 我真正的意思是:例如,35381.25(实际时间)和 42592(工作时间)。我真的不希望橙色条堆叠为 35381.25+42592 约为 78000 但实际上我希望它们都像我在问题中发布的那样(预期输出)
    • @FirdhausSaleh 已编辑。对不起,我刚才误读了你的问题。
    • 感谢@QuantStats,它是完美的
    • @FirdhausSaleh 另请参阅通过堆叠它们的差异来实现它的替代方法,我认为这更容易。
    猜你喜欢
    • 2016-05-24
    • 2018-05-09
    • 2018-11-26
    • 1970-01-01
    • 2020-11-03
    • 2020-09-29
    • 1970-01-01
    相关资源
    最近更新 更多