我有一个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,
)
结果图如下所示: 一切看起来很好,除了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))
产生这个(想要的)结果:
注意:每个条形的宽度设置为1.0,并且它们已经移动了-0.5,以便将每个条形图集中在tic标记上方。
答案 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列表的变化而生成下面的图表(为简单起见,我删除了额外的轴)。
注意:pandas 0.14.0下的操作df_list[i].index-0.4
会产生错误,这是一个已在0.15.1中修复的错误。您可以先将索引转换为普通的numpy数组,或者只升级pandas。
答案 1 :(得分:0)
你问了一个非常好的问题。感谢您拥有可重复的示例,这使得它更容易提供帮助。
问题是Pandas条形图代码假定x轴上的分类数据。显然你没有分类数据。然而,没有好的方法告诉Matplotlib通过Pandas情节界面(我知道)。
对我来说最明显的解决方案就是你提出的增值方法。我可能会通过加入来做到这一点。我将现有数据框加入一个索引,该索引具有x轴上我想要的所有值,并使用how='outer'
选项进行连接。