Matplotlib将x刻度放在条形图上方

时间:2018-01-04 21:24:37

标签: python pandas matplotlib plot figure

有没有办法将每个堆叠条形图上方的x-ticks放在堆积条形图中,而不是放在x轴下方?要清楚,我并不是指将x-tick放在单个堆叠条中的每个单独条上方,我的意思是将x-tick放在堆叠条本身上方。这就是我创建情节的方式:

WHERE 
  UPR30300.PAYROLCD in (@Paycodes,@Benefits,@Deductions) 
  and UPR30300.chekdate between (@Begindate) and (@Enddate)

此外,我想在x轴的特定点放置一些文字。我将这些网站存储在一个列表中:

df = pd.DataFrame(np.random.randint(1, 5, size=(3200, 3)))    
df.loc[np.random.choice(df.index, size=3190, replace=False), :] = 0

df_select = df[df.sum(axis=1)>1]
fig, ax = plt.subplots()

ax.bar(df_select.index, df_select.iloc[:,0], label = df_select.columns[0], wdith = 15)

if df_select.shape[1] > 1:
    for i in range(1, df_select.shape[1]):
        bottom = df_select.iloc[:,np.arange(0,i,1)].sum(axis=1)
        ax.bar(df_select.index, df_select.iloc[:,i], bottom=bottom, label = 
df_select.columns[i], width = 15)

ax.set_xticks(df_select.index)
plt.legend(loc='best', bbox_to_anchor=(1, 0.5))
plt.xticks(rotation=90, fontsize=8) #this puts the x ticks below the x axis

因此,例如,在x = 173时,我想将文本'site(173)'与173位的刻度一起放置。

供您参考,我发布了当前代码产生的图像,以及我想要制作的内容: 当前:https://i.stack.imgur.com/QDlEP.png 目标:https://i.stack.imgur.com/IJJo4.png

2 个答案:

答案 0 :(得分:2)

这可以通过使用@Evan链接到此评论中的示例来实现,即this one。重要的位是链接示例中名为autolabel的函数。将显示的值从y轴值更改为x轴值很容易,将height替换为rect.get_x()。比较棘手的是将值放在条形的顶部。您可以通过汇总DataFrame中的值来找到条形图的总高度。

heights = df_select.iloc[:,:].sum(axis=1)

然后需要将其传递给autolabel函数并用作条形的高度。可以使用

删除x刻度标签
ax.get_xaxis().set_ticklabels([])

您只需使用ax.text的内容sites作为x位置,并将y位置设置为低于轴( - ),即可在x轴下方为特定网站添加更多文字0.5或者什么)。

综上所述,我们得到以下工作示例:

def autolabel(rects, heights):
    """
    Attach a text label above each bar displaying its height
    Modified for use with a stacked bar chart
    """
    for i, rect in enumerate(rects):
        x = rect.get_x()
        wid = rect.get_width()
        height = heights.values[i]

        ax.text(x + wid/2., 1.05*height,
                '%d' % (int(x) + int((wid/2)+0.5)),
                ha='center', va='bottom', rotation=90)


df = pd.DataFrame(np.random.randint(1, 5, size=(3200, 3)))    
df.loc[np.random.choice(df.index, size=3190, replace=False), :] = 0

df_select = df[df.sum(axis=1)>1]
fig, ax = plt.subplots()

ax.bar(df_select.index, df_select.iloc[:,0], label = df_select.columns[0], width = 15)

if df_select.shape[1] > 1:
    for i in range(1, df_select.shape[1]):
        bottom = df_select.iloc[:,np.arange(0,i,1)].sum(axis=1)
        rects1 = ax.bar(df_select.index, df_select.iloc[:,i], bottom=bottom, label = 
df_select.columns[i], width = 15)

ax.set_xticks(df_select.index)
ax.get_xaxis().set_ticklabels([])   # turn off the x tick labels

plt.legend(loc='best', bbox_to_anchor=(1, 0.5))

heights = df_select.iloc[:, :].sum(axis=1)
autolabel(rects1, heights)

# Select 3 random value to add labels below the x axis. Make sure they are
# within the axis limits
sites = np.random.choice(df_select.index, 3)

for site in sites:
    ax.text(site, -0.5,
        'site(%s)' % site,
        ha='center', va='bottom',fontsize=6)

plt.show()

其中给出了以下图表:

enter image description here

注意:这有时看起来很麻烦,因为条很细并且展开,并且可以彼此靠近放置,这意味着值可能开始重叠。

答案 1 :(得分:0)

如果您的意思是在图的框架顶部设置x-tick标签,请尝试当前代码底部的ax.xaxis.tick_top()

要在自定义x轴位置放置文字标签:根据these docs,这应该有效:

locs, labels = plt.xticks(rotation=90, fontsize=8)
sites = [19, 173, 1002]
site_labels = ['label at 19', 'label at 173', 'label at 1002']
new_locs = np.append(locs, sites)
new_labels = np.append(labels, site_labels)
plt.xticks(new_locs, new_labels)