【问题标题】:How do I add multiple bar graphs from a pandas dataframe on one plot in matplotlib?如何在 matplotlib 的一个图上从 pandas 数据框中添加多个条形图?
【发布时间】:2021-03-02 23:34:07
【问题描述】:

我有两个不同的数据框:

df_test1 = pd.DataFrame(
    [['<18', 80841], ['18-24', 334725], ['25-44', 698261], ['45-64', 273087], ['65+', 15035]],
    columns = ['age_group', 'total_arrests']
)

df_test2 = pd.DataFrame(
    [['<18', 33979], ['18-24', 106857], ['25-44', 219324], ['45-64', 80647], ['65+', 4211]],
    columns = ['age_group','total_arrests']
)

我使用 matplotlib 创建了以下绘图:

fig, ax = plt.subplots()

ax.bar(df_test1.age_group, df_test1.total_arrests, color = 'seagreen')
ax.bar(df_test2.age_group, df_test2.total_arrests, color = 'lightgreen')
ax.set_xlabel('Age Group')
ax.set_ylabel('Number of Arrests')
ax.set_title('Arrests vs. Felony Arrests by Age Group')
plt.xticks(rotation=0)
plt.legend(['All Arressts', 'Felony Arrests'])

ax.yaxis.set_major_formatter(
ticker.FuncFormatter(lambda y,p: format(int(y), ','))
)

for i,j in zip(df_test1.age_group, df_test1.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j))

for i,j in zip(df_test2.age_group, df_test2.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j))

plt.show()

我期待 2 个单独的条形图,每个数据框列一个,df_test1.total_arrestsdf_test2.total_arrests,但我得到了一个堆积条形图。我怎样才能得到一个与Matplotlib plot multiple bars in one graph 的图表类似的条形图?我尝试将我的代码调整为该示例中的代码,但我无法得到它。

【问题讨论】:

    标签: python pandas dataframe matplotlib


    【解决方案1】:

    只有两个酒吧,这相当容易。解决方法是对齐刻度线“边缘”上的条形图,一条条向左对齐,另一个向右对齐。

    重复相同的逻辑以正确对齐注释。其中一半是左对齐,其他是右对齐

    fig, ax = plt.subplots()
    
    ax.bar(df_test1.age_group, df_test1.total_arrests, color = 'seagreen', width=0.4, align='edge')
    ax.bar(df_test2.age_group, df_test2.total_arrests, color = 'lightgreen', width=-0.4, align='edge')
    ax.set_xlabel('Age Group')
    ax.set_ylabel('Number of Arrests')
    ax.set_title('Arrests vs. Felony Arrests by Age Group')
    plt.xticks(rotation=0)
    plt.legend(['All Arressts', 'Felony Arrests'])
    ax.yaxis.set_major_formatter(
    matplotlib.ticker.FuncFormatter(lambda y,p: format(int(y), ','))
    )
    
    for i,j in zip(df_test1.age_group, df_test1.total_arrests):
        ax.annotate(format(j, ','), xy=(i,j))
    
    for i,j in zip(df_test2.age_group, df_test2.total_arrests):
        ax.annotate(format(j, ','), xy=(i,j), ha='right')
    
    plt.show()
    

    如果您有超过 2 个条,那么情况会更复杂(请参阅上面链接的代码)。使用seaborn 会更轻松,但您必须稍微转换一下数据框:

    df = pd.merge(left=df_test1, right=df_test2, on='age_group')
    
    df.columns=['age_group','all_arrests', 'felonies']
    df = df.melt(id_vars=['age_group'], var_name='Type', value_name='Number')
    
    fig, ax = plt.subplots()
    sns.barplot(y='Number',x='age_group',hue='Type', data=df, hue_order=['felonies','all_arrests'])
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2021-11-13
      • 2020-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多