python - 如何在 matplotlib 的一个图上从 pandas 数据框中添加多个条形图?
问题描述
我有两个不同的数据框:
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_arrests
但df_test2.total_arrests
我得到了一个堆积条形图。如何获得一个条形图并排的图表,类似于Matplotlib 在一个图表中绘制多个条形图?我尝试将我的代码调整为该示例中的代码,但我无法得到它。
解决方案
只有两个酒吧,这相当容易。解决方案是对齐刻度线“边缘”上的条形图,一条条向左对齐,另一个向右对齐。
重复相同的逻辑以正确对齐注释。其中一半为左对齐,其他为右对齐
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'])
推荐阅读
- sql - 使用季度数据查找每位员工的年度 MAX 和 MIN
- sql - 如何在postgres中显示哈希数组中的键?
- css - maven 会创建 css 文件的副本吗?
- ios - 在使用主题获得响应后将数据从父 VC 传递到子 VC
- html - 行全宽中的引导跨度元素
- macos - 如何在 Safari Web Inspector 中查看导致 'safari-resource:/ErrorPage.html' (HTTP 403) 的初始 Web 请求?
- mysql - Mysql查询 - 一张表 - 一天内找到两个日期 - 来自不同列的同一实体+差异计算
- authentication - 无法使用有效凭据登录詹金斯
- windows-update - Windows 更新代理 WUA 如何识别要安装的 KB?
- python - vtkSplineRepresentation () 的 Actor