【发布时间】:2020-10-21 02:50:45
【问题描述】:
我正在尝试使用注释上的自定义文本构建堆叠条形图。条形图是使用商店位置列表的“morning_sales”和“afternoon_sales”条目构建的,我想为每个盒子构建一个自定义标签以显示盒子的高度和另一列的相关值(在这个例,将“morning_staff”与“morning_sales”匹配,将“afternoon_staff”与“afternoon_sales”匹配)。
我的方法有效,但依赖于知道条形图矩形的顺序...我担心如果我对条形图或相关操作进行任何重新排序,事情可能会分崩离析。谁能推荐一个更好的方法来做到这一点?请注意,这是一个“虚拟”数据帧;我的真实数据集是几十万行。
我不确定是否可以使用“handles, labels = ax.get_legend_handles_labels()”方法提取文本?
代码如下:
import pandas as pd
data = {'location': ['Toronto', 'Vancouver', 'Edmonton', 'Calgary'],
'morning_staff': [3, 12, 25, 6],
'afternoon_staff': [2, 8, None, 8],
'morning_sales': [8000, 25000, 40000, 15000],
'afternoon_sales': [4000, 15000, None, 6000]
}
df = pd.DataFrame(data, columns = ['location', 'morning_staff', 'afternoon_staff', 'morning_sales', 'afternoon_sales' ])
# > Drop 'Calgary' from plot dataset and extract columns for plotting
df_plot = df.loc[df['location'] != 'Calgary', ['location', 'morning_sales', 'afternoon_sales']]
ax = df_plot.plot.bar(x='location', stacked=True, figsize=(8,6), colormap='tab10', fontsize=14)
# Add an annotation to each bar -> Showing staff required for sales
col_tags = ['morning_staff', 'afternoon_staff']
locations = df_plot['location'].tolist()
bar_labels = []
for col_tag in col_tags: # morning_sales, afternoon_sales
for location in locations:
idx = df.loc[df['location'] == location].index[0]
bar_label = df.loc[idx, col_tag].item()
bar_labels.append(bar_label)
rects = ax.patches
for rect, bar_label in zip(rects, bar_labels):
width, height = rect.get_width(), rect.get_height()
if ((height != 0) & (bar_label != np.nan)) :
x, y = rect.get_xy()
text = f'{int(bar_label)}: {int(height)}'
ax.text(x+width/2,
y+height/2,
text,
horizontalalignment='center',
verticalalignment='center',
fontsize=12)
【问题讨论】:
-
您期望的目标是什么?例如任何想要的输出?
标签: python pandas matplotlib bar-chart