【问题标题】:Matplotlib put x ticks above barMatplotlib 将 x 刻度放在条形上方
【发布时间】:2018-01-04 21:24:36
【问题描述】:

有没有办法将 x 刻度放在堆叠条形图中每个堆叠条的上方,而不是 x 轴下方?需要明确的是,我并不是说将 x-tick 放在单个堆叠条中的每个单独条上方,我的意思是将 x-tick 放在堆叠条本身上方。以下是我创建情节的方式:

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 轴的特定点放置一些文本。我将这些网站存储在一个列表中:

sites = [19, 173, 1002] # the number and elements of this list vary

因此,例如,在 x = 173 处,我想在位置 173 处放置文本“站点 (173)”以及一个刻度。

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

【问题讨论】:

  • 是的,但我想把 x val 放在栏的顶部,而不是 y val。我已经尝试使用链接中的代码(调整为放置 x val 而不是 y),但由于它是堆叠图,它似乎不起作用
  • 你能发布你更新的代码吗?我无法根据您发布的内容获得合理的情节;假设导入了 np、pd、plt。
  • 尝试为 ax.bar() 传递宽度...在某些情况下,这些条似乎太细而无法显示。 width = 15 为我工作

标签: python pandas matplotlib plot figure


【解决方案1】:

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

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

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

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

您可以在特定站点的 x 轴下方添加更多文本,只需使用sites 的内容作为 x 位置,使用 ax.text,并将 y 位置设置为轴下方(-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()

这给出了以下图表:

注意:这有时看起来很乱,因为条形非常细且散开,并且可以彼此靠近放置,这意味着值可能会开始重叠。

【讨论】:

    【解决方案2】:

    如果您的意思是在图形框架的顶部设置 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)
    

    【讨论】:

    • 我希望将 x 刻度放在条本身的顶部,而不是图框的顶部。
    • 您是否有任何所需结果的示例图像?不确定我以前是否见过这样放置的 x-ticks。
    • 当然 - 我在我的问题中添加了一张图片。
    猜你喜欢
    • 2021-06-18
    • 2019-08-06
    • 2013-03-31
    • 2019-07-03
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    相关资源
    最近更新 更多