在堆叠的条形图中添加标签 [英] Adding labels to stacked bar chart
问题描述
我正在绘制某些类别中各个办公室的交叉列表.我想放一张水平堆叠的条形图,在其中标记每个办公室及其值.
I'm plotting a cross-tabulation of various offices within certain categories. I'd like to put together a horizontal stacked bar chart where each office and its value is labeled.
下面是一些示例代码:
df = pd.DataFrame({'office1': pd.Series([1,np.nan,np.nan], index=['catA', 'catB', 'catC']),
'office2': pd.Series([np.nan,8,np.nan], index=['catA', 'catB', 'catC']),
'office3': pd.Series([12,np.nan,np.nan], index=['catA', 'catB', 'catC']),
'office4': pd.Series([np.nan,np.nan,3], index=['catA', 'catB', 'catC']),
'office5': pd.Series([np.nan,5,np.nan], index=['catA', 'catB', 'catC']),
'office6': pd.Series([np.nan,np.nan,7], index=['catA', 'catB', 'catC']),
'office7': pd.Series([3,np.nan,np.nan], index=['catA', 'catB', 'catC']),
'office8': pd.Series([np.nan,np.nan,11], index=['catA', 'catB', 'catC']),
'office9': pd.Series([np.nan,6,np.nan], index=['catA', 'catB', 'catC']),
})
ax = df.plot.barh(title="Office Breakdown by Category", legend=False, figsize=(10,7), stacked=True)
这给了我一个很好的起点:
This gives me a fine starting point:
但是,我想要的是:
However, what I'd like to have is this:
经过研究,我想出了以下代码,可以在类别"轴上正确地排列标签:
After some research, I came up with the following code that correctly lines up labels on the 'category' axis:
def annotateBars(row, ax=ax):
for col in row.index:
value = row[col]
if (str(value) != 'nan'):
ax.text(value/2, labeltonum(row.name), col+","+str(value))
def labeltonum(label):
if label == 'catA':
return 0
elif label == 'catB':
return 1
elif label == 'catC':
return 2
df.apply(annotateBars, ax=ax, axis=1)
但是,这不包括条的堆积".我还尝试了遍历plot命令返回的patches
容器(它可以让我检索每个矩形的x和y位置),但是随后我失去了与办公室标签的任何连接.
But this doesn't factor in the "stacking" of the bars. I've also tried iterating through the patches
container returned by the plot command (which can let me retrieve x & y positions of each rectangle), but I then lose any connection to the office labels.
推荐答案
弄清楚了.如果我遍历数据帧每一行的列,则可以建立一个与ax.patches
中的矩形进度匹配的标签列表.下面的解决方案:
Figured it out. If I iterate through the columns of each row of the dataframe I can build up a list of the labels I need that matches the progression of the rectangles in ax.patches
. Solution below:
labels = []
for j in df.columns:
for i in df.index:
label = str(j)+": " + str(df.loc[i][j])
labels.append(label)
patches = ax.patches
for label, rect in zip(labels, patches):
width = rect.get_width()
if width > 0:
x = rect.get_x()
y = rect.get_y()
height = rect.get_height()
ax.text(x + width/2., y + height/2., label, ha='center', va='center')
添加到上面的代码后,会产生:
Which, when added to the code above, yields:
现在只需要处理太小的条形标签的重新排列...
Now to just deal with re-arranging labels for bars that are too small...
这篇关于在堆叠的条形图中添加标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!