Matplotlib填补缺少抽动标签

时间:2014-11-19 13:52:56

标签: python matplotlib pandas plot

我有一个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 一切看起来很好,除了xtic标签,我期望根据它的值间隔(即“-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))

产生这个(想要的)结果:

enter image description here

注意:每个条形的宽度设置为1.0,并且它们已经移动了-0.5,以便将每个条形图集中在tic标记上方。

2 个答案:

答案 0 :(得分:1)

看起来Pandas还没有(还)给它的条形图包装功能明确放置条形位置。 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中修复的错误。您可以先将索引转换为普通的numpy数组,或者只升级pandas。

答案 1 :(得分:0)

你问了一个非常好的问题。感谢您拥有可重复的示例,这使得它更容易提供帮助。

问题是Pandas条形图代码假定x轴上的分类数据。显然你没有分类数据。然而,没有好的方法告诉M​​atplotlib通过Pandas情节界面(我知道)。

对我来说最明显的解决方案就是你提出的增值方法。我可能会通过加入来做到这一点。我将现有数据框加入一个索引,该索引具有x轴上我想要的所有值,并使用how='outer'选项进行连接。