Matplotlib 填充缺失的刻度标签

3

我有一个Pandas数据框架列表(示例):

df1 = pd.DataFrame({'Number':[-9,-8,0,1,2,3], 'A':[3,6,4,1,7,19], 'B':[2,4,4,0,7,1]})
df1.set_index('Number',inplace=True)

df2 = pd.DataFrame({'Number':[0,5,6,7,8,9], 'A':[8,7,3,5,2,15], 'B':[1,7,1,1,1,3]})
df2.set_index('Number',inplace=True)

df_list = [df1, df2] #In reality there are more than two in the list

我正在尝试使用Matplotlib绘制它们:

nrow = 2
ncol = 2
fig, axs = plt.subplots(nrow,ncol)

for i in range(nrow*ncol):
    #Convert 1D to 2D
    row = i / ncol
    col = i % ncol
    if i >= len(df_list):
        axs[row,col].axis('off')
    else:
        df_list[i]['A'].plot(kind='bar',
              ax=axs[row,col],
              ylim=(0,20),
              xlim=(-10,10),
              figsize=(20,15),
              color=('green'),
              legend=False,
              )
        df_list[i]['B'].plot(kind='bar',
              ax=axs[row,col],
              ylim=(0,20),
              xlim=(-10,10),
              figsize=(20,15),
              color=('yellow'),
              legend=False,
              ) 

生成的图表如下所示: enter image description here 除了x轴刻度标签之外,其他都看起来很好。我期望这些标签根据其值进行间隔(例如,"-9"不应该在图的中间,"0"不应该紧贴着"5"等)。实际上,由于我的x范围大约是(-10,10),我希望在x轴上显示整个范围,并使彩色条根据它们的“数字”进行定位。我想到的一个可能的解决方案是使用Pandas填充从(-10,10)丢失的值,但我认为有更好/更明显的方法来处理这个问题。我只是一直没有能够找到那个解决方案。

更新:

感谢Ajean和JD Long在下面的回复中提供的代码,我现在正在使用这个Matplotlib代码:

df_list = [df1, df2]

nrow = 2
ncol = 2
fig, axs = plt.subplots(nrow,ncol,figsize=(20,15))

for i in range(nrow*ncol):
    #Convert 1D to 2D
    row = i / ncol
    col = i % ncol
    if i >= len(df_list):
        axs[row,col].axis('off')
    else:
        axs[row,col].bar(np.array(df_list[i].index)-0.5, df_list[i]['A'], width=1, color='green')
        axs[row,col].bar(np.array(df_list[i].index)-0.5, df_list[i]['B'], width=1, color='yellow')
        axs[row,col].set_xlim([-10,10])
        axs[row,col].set_ylim([0,20])
        axs[row,col].xaxis.set_ticks(np.arange(-10, 11, 1))

这将产生所需的结果:

在此输入图片描述

注意:每个条形图的宽度都设置为1.0,并且它们已经向左移动了-0.5,以使每个条形图位于刻度线中心。


另外,你目前重叠了你的条形图,所以如果黄色的条形比绿色的高,它们将覆盖绿色的条形。当然,你可能想要这样做,但如果你想要一个堆积条形图,你可以使用“bottom”关键字FYI :)。 - Ajean
@Ajean:是的,我希望我的条形图重叠(黄色应小于或等于绿色),但我肯定将来会用到堆积条形图,所以我一定会记住“bottom”。谢谢你提醒! - slaw
2个回答

1
看起来Pandas还没有(至今)赋予其条形图包装功能显式放置条形位置的能力。 "What's New" 0.14.0指出,“条形图的坐标现在位于整数值上(0.0、1.0、2.0 ...)”,截至我所知,到0.15.1为止都没有改变。

因此,我会跳过Pandas接口(您肯定在使用)并直接使用Matplotlib。

nrow = 1
ncol = 2
fig, axs = plt.subplots(nrow,ncol)

for i in range(nrow*ncol):
    if i >= len(df_list):
        axs[i].axis('off')
    else:
        # You could theoretically turn this into a loop over your columns
        # with appropriate widths and offsets
        axs[i].bar(df_list[i].index-0.4, df_list[i]['A'], width=0.4, color='green')
        axs[i].bar(df_list[i].index, df_list[i]['B'], width=0.4, color='yellow')

上述代码根据您定义的DataFrame列表生成以下图表(为简洁起见,我删除了额外的轴)。

bar chart at exact locations

注意: 在pandas 0.14.0版本下,操作df_list[i].index-0.4会产生错误,这是一个已在0.15.1版本中修复的Bug。您可以通过先将索引转换为普通的numpy数组来解决它,或者升级pandas。


0

你提出了一个非常好的问题。感谢您提供了可重现的示例,这使得帮助变得更加容易。

问题在于Pandas条形图代码假定x轴上的数据是分类数据。显然,您没有分类数据。但是,我不知道有什么好方法告诉Matplotlib通过Pandas绘图界面。

对我来说,最明显的解决方案是您提出的添加值的方法。我可能会通过连接来完成这个操作。我将现有的数据框与一个具有我想要在x轴上显示的所有值的索引的数据框连接,并使用how='outer'选项进行连接。


谢谢!你是不是指的是 "Matplotlib 条形图" 而不是 Pandas?也许我弄错了,但我的印象是我直接用 Matplotlib 绘图(即我没有做像"df1.plot(kind="bar")" 这样的操作)。如果是这样,是否有一种直接告诉 Matplotlib 如何处理 x 标签的方法?或者是否有一种使用 Matplotlib 实现相同视觉效果的不同方式,例如不同的绘图类型、不同的可视化(绘制矩形形状),或使用不同的参数等。 - slaw
当你调用df1.plot(kind="bar")时,你绝对是在做正确的事情,因为df_list[i]['B']是一个数据框。话虽如此,Pandas会调用matplotlib,但你肯定是在使用Pandas的接口。 - JD Long

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接