如何增加子图文本大小并添加自定义条形图注释
How to Increase subplot text size and add custom bar plot annotations
我有以下数据框,代表每个地区 department/area 的员工总数。
Finance HR IT Marketing Medical Operations Sales
Business Unit
Cardiology 0 2 1 0 3 0 0
Genetics 1 4 3 1 3 1 1
Imaging 34 74 70 38 68 18 33
Labs 63 130 131 66 130 32 68
Pathology 2 5 10 4 8 3 6
使用此数据框,我使用以下代码生成了波纹管图:
#Plot the graph
fig, ax = plt.subplots(1, 5, figsize=(30, 15), sharey = True)
iax = iter(ax.flatten())
for n, g in df.groupby('Business Unit'):
g.loc[n, :].plot.bar(ax=next(iax), title=f'{n}', stacked=True, legend = True, fontsize = 30)
如您所见,通知业务部门的子图的文本大小以及图例大小(在顶角)太小了。我怎样才能增加他们两个的文本?
此外,我是否可以在此代码中添加一种方法来显示每一列中总计的百分比?
非常感谢您的帮助!
- 我会用
pandas.DataFrame.plot
, which plots the index as the xaxis. As such, the dataframe needs to be transposed with .T
- 这使用
matplotlib
和默认绘图后端
- 使用
subplots=True
,df.plot
被分配给axes
,这是AxesSubplots
[=46=的arrays
的array
]
- 可以使用
.bar_label
添加注释,可以使用labels=
参数自定义标签。以下链接包含自定义 labels
的示例。
- Bar Label Demo
- stack bar plot in matplotlib and add label to each section
- 在
pandas 1.3.0
和 matplotlib 3.4.2
中测试
import pandas as pd
# load dataframe
data = {'Cardiology': {'Finance': 0, 'HR': 2, 'IT': 1, 'Marketing': 0, 'Medical': 3, 'Operations': 0, 'Sales': 0}, 'Genetics': {'Finance': 1, 'HR': 4, 'IT': 3, 'Marketing': 1, 'Medical': 3, 'Operations': 1, 'Sales': 1}, 'Imaging': {'Finance': 34, 'HR': 74, 'IT': 70, 'Marketing': 38, 'Medical': 68, 'Operations': 18, 'Sales': 33}, 'Labs': {'Finance': 63, 'HR': 130, 'IT': 131, 'Marketing': 66, 'Medical': 130, 'Operations': 32, 'Sales': 68}, 'Pathology': {'Finance': 2, 'HR': 5, 'IT': 10, 'Marketing': 4, 'Medical': 8, 'Operations': 3, 'Sales': 6}}
df = pd.DataFrame.from_dict(data, orient='index')
# get the total for each business unit; used to calculate percent
bu_total = df.sum(axis=1)
# get the total for each division; used to calculate percent
div_total = df.sum(axis=0)
# plot
axes = df.T.plot(kind='bar', subplots=True, layout=(1, 5), figsize=(22, 6), sharey=True, ylabel='Expenditures ($)')
# iterate through axes subplots
for ax in axes[0]:
# title is used to get the total from bu_total
title = ax.get_title()
ax.legend(fontsize=15)
ax.set_xticklabels(ax.get_xticklabels(), fontdict={'fontsize':24})
ax.set_title(title, fontdict={'fontsize':24})
ax.set_ylabel(ax.get_ylabel(), fontdict={'fontsize':24})
# customized labels for % business unit total
bu_labels = [f'{(v.get_height() / bu_total[title])*100 :.0f}%' for v in ax.containers[0]]
# customized labels for % division total
div_labels = [f'{(v.get_height() / div_total[i])*100 :.0f}%' for i, v in enumerate(ax.containers[0])]
# annotate as desired: use bu_lables or div_labels
ax.bar_label(ax.containers[0], labels=bu_labels, label_type='edge', fontsize=10)
# pad the spacing between the number and the edge of the figure
ax.margins(y=0.1)
我有以下数据框,代表每个地区 department/area 的员工总数。
Finance HR IT Marketing Medical Operations Sales
Business Unit
Cardiology 0 2 1 0 3 0 0
Genetics 1 4 3 1 3 1 1
Imaging 34 74 70 38 68 18 33
Labs 63 130 131 66 130 32 68
Pathology 2 5 10 4 8 3 6
使用此数据框,我使用以下代码生成了波纹管图:
#Plot the graph
fig, ax = plt.subplots(1, 5, figsize=(30, 15), sharey = True)
iax = iter(ax.flatten())
for n, g in df.groupby('Business Unit'):
g.loc[n, :].plot.bar(ax=next(iax), title=f'{n}', stacked=True, legend = True, fontsize = 30)
如您所见,通知业务部门的子图的文本大小以及图例大小(在顶角)太小了。我怎样才能增加他们两个的文本?
此外,我是否可以在此代码中添加一种方法来显示每一列中总计的百分比?
非常感谢您的帮助!
- 我会用
pandas.DataFrame.plot
, which plots the index as the xaxis. As such, the dataframe needs to be transposed with.T
- 这使用
matplotlib
和默认绘图后端
- 这使用
- 使用
subplots=True
,df.plot
被分配给axes
,这是AxesSubplots
[=46=的arrays
的array
] - 可以使用
.bar_label
添加注释,可以使用labels=
参数自定义标签。以下链接包含自定义labels
的示例。- Bar Label Demo
- stack bar plot in matplotlib and add label to each section
- 在
pandas 1.3.0
和matplotlib 3.4.2
中测试
import pandas as pd
# load dataframe
data = {'Cardiology': {'Finance': 0, 'HR': 2, 'IT': 1, 'Marketing': 0, 'Medical': 3, 'Operations': 0, 'Sales': 0}, 'Genetics': {'Finance': 1, 'HR': 4, 'IT': 3, 'Marketing': 1, 'Medical': 3, 'Operations': 1, 'Sales': 1}, 'Imaging': {'Finance': 34, 'HR': 74, 'IT': 70, 'Marketing': 38, 'Medical': 68, 'Operations': 18, 'Sales': 33}, 'Labs': {'Finance': 63, 'HR': 130, 'IT': 131, 'Marketing': 66, 'Medical': 130, 'Operations': 32, 'Sales': 68}, 'Pathology': {'Finance': 2, 'HR': 5, 'IT': 10, 'Marketing': 4, 'Medical': 8, 'Operations': 3, 'Sales': 6}}
df = pd.DataFrame.from_dict(data, orient='index')
# get the total for each business unit; used to calculate percent
bu_total = df.sum(axis=1)
# get the total for each division; used to calculate percent
div_total = df.sum(axis=0)
# plot
axes = df.T.plot(kind='bar', subplots=True, layout=(1, 5), figsize=(22, 6), sharey=True, ylabel='Expenditures ($)')
# iterate through axes subplots
for ax in axes[0]:
# title is used to get the total from bu_total
title = ax.get_title()
ax.legend(fontsize=15)
ax.set_xticklabels(ax.get_xticklabels(), fontdict={'fontsize':24})
ax.set_title(title, fontdict={'fontsize':24})
ax.set_ylabel(ax.get_ylabel(), fontdict={'fontsize':24})
# customized labels for % business unit total
bu_labels = [f'{(v.get_height() / bu_total[title])*100 :.0f}%' for v in ax.containers[0]]
# customized labels for % division total
div_labels = [f'{(v.get_height() / div_total[i])*100 :.0f}%' for i, v in enumerate(ax.containers[0])]
# annotate as desired: use bu_lables or div_labels
ax.bar_label(ax.containers[0], labels=bu_labels, label_type='edge', fontsize=10)
# pad the spacing between the number and the edge of the figure
ax.margins(y=0.1)