我在理解Pandas子图时遇到了麻烦-以及如何创建轴以便显示所有子图(不会被后续图覆盖)。
对于每个“站点”,我想绘制数据框中所有列的时间序列图。
这里的“站点”是“鲨鱼”和“独角兽”,都有两个变量。输出应为4条绘制的线-每个站点上Var 1和Var2的时间索引图。
使用Nans编制时间索引数据:
df = pd.DataFrame({
# some ways to create random data
'Var1':pd.np.random.randn(100),
'Var2':pd.np.random.randn(100),
'Site':pd.np.random.choice( ['unicorn','shark'], 100),
# a date range and set of random dates
'Date':pd.date_range('1/1/2011', periods=100, freq='D'),
# 'f':pd.np.random.choice( pd.date_range('1/1/2011', periods=365,
# freq='D'), 100, replace=False)
})
df.set_index('Date', inplace=True)
df['Var2']=df.Var2.cumsum()
df.loc['2011-01-31' :'2011-04-01', 'Var1']=pd.np.nan
为每个站点制作一个带有子图的图:
fig, ax = plt.subplots(len(df.Site.unique()), 1)
counter=0
for site in df.Site.unique():
print(site)
sitedat=df[df.Site==site]
sitedat.plot(subplots=True, ax=ax[counter], sharex=True)
ax[0].title=site #Set title of the plot to the name of the site
counter=counter+1
plt.show()
但是,这不能按书面规定进行。第二个子图最终覆盖第一个子图。在我的实际用例中,每个数据帧中有14个可变数量的站点,以及可变数量的“ Var1、2 ...”。因此,我需要一个不需要手动创建每个轴(ax0,ax1,...)的解决方案。
作为奖励,我希望在该地块上方的每个“站点”都拥有一个标题。
答案 0 :(得分:1)
使用DataFrame.plot(..., subplot=True)
时,需要提供将用于每列的正确轴数(如果使用layout=
,则具有正确的几何形状)。在您的示例中,您有2列,因此plot()
需要两个轴,但是您只能在ax=
中传递一个,因此pandas除了删除所有轴并创建适当数量的轴外别无选择本身。
因此,您需要传递长度与数据框中的列数相对应的长度轴数组。
# the grouper function is from itertools' cookbook
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
fig, axs = plt.subplots(len(df.Site.unique())*(len(df.columns)-1),1, sharex=True)
for (site,sitedat),axList in zip(df.groupby('Site'),grouper(axs,len(df.columns)-1)):
sitedat.plot(subplots=True, ax=axList)
axList[0].set_title(site)
plt.tight_layout()