将熊猫子图组合成单个图形

时间:2018-11-06 00:56:25

标签: pandas dataframe matplotlib plot visualization

我在理解Pandas子图时遇到了麻烦-以及如何创建轴以便显示所有子图(不会被后续图覆盖)。

对于每个“站点”,我想绘制数据框中所有列的时间序列图。

这里的“站点”是“鲨鱼”和“独角兽”,都有两个变量。输出应为4条绘制的线-每个站点上Var 1和Var2的时间索引图。

enter image description here

使用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,...)的解决方案。

作为奖励,我希望在该地块上方的每个“站点”都拥有一个标题。

当前代码将第二个覆盖第一个“站点”图。我在这里想念的东西是什么? enter image description here

1 个答案:

答案 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()

enter image description here