Объединение Pandas Subplots в одну фигуру - PullRequest
0 голосов
/ 06 ноября 2018

У меня проблемы с пониманием подзаговоров 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 голосов
/ 06 ноября 2018

Когда вы используете 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...