Seaborn (временные ряды) boxplot с использованием оттенка и различных масштабных осей - PullRequest
0 голосов
/ 13 мая 2018

У меня есть датафрейм, который имеет количество значений на дату (поле даты и времени). Эти значения классифицируются по U ( пользователи ) и S ( сессия ) с использованием столбца Группа . Seaborn используется для визуализации двух коробочных графиков за дату, где оттенок установлен на Group .

Проблема возникает, если учесть, что значения, соответствующие U ( users ), намного больше, чем значения, соответствующие S ( session ), что делает данные S неразборчивыми. Таким образом, мне нужно найти решение, которое позволило бы мне представить обе серии (U и S) на одном и том же рисунке понятным образом.

Интересно, можно ли установить независимые оси Y (с разными масштабами) для каждого оттенка, чтобы отображались обе оси Y (как при использовании twinx, но без потери возможностей визуализации оттенка).

Любая другая альтернатива будет приветствоваться =)

Бокс-график временного ряда S boxplot:

The S boxplot time series boxplot

Комбинированные временные ряды с использованием оттенков. Очевидно, что невозможно увидеть какую-либо информацию о группе S из-за масштаба оси Y:

The combined boxplot time series using hue. Obviously it's not possible to see any information about the S group because of the scale of the Y axis

Столбцы кадра данных:

| День (дата / время) | n_data (числовой) | Группа (S или U) |

Строка кода, генерирующая комбинированный блок-график:

seaborn.boxplot(ax=ax,x='Day', y='n_data', hue='Group', data=df, 
                palette='PRGn', showfliers=False)

Удалось найти решение с помощью twinx:

fig,ax= plt.subplots(figsize=(50,10))

tmpU = groups.copy() 
tmpU.loc[tmp['Group']!='U','n_data'] = np.nan

tmpS = grupos.copy()
tmpS.loc[tmp['Group']!='S','n_data'] = np.nan

ax=seaborn.boxplot(ax=ax,x='Day', y = 'n_data', hue='Group', data=tmpU, palette = 'PRGn', showfliers=False)

ax2 = ax.twinx()

seaborn.boxplot(ax=ax2,x='Day', y = 'n_data', hue='Group', data=tmpS, palette = 'PRGn', showfliers=False)

handles,labels = ax.get_legend_handles_labels()
l= plt.legend(handles[0:2],labels[0:2],loc=1)

plt.setp(ax.get_xticklabels(),rotation=30,horizontalalignment='right')
for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

plt.show()
plt.close('all')

Код выше генерирует следующий рисунок:

the following figure.

Который в этом случае оказывается слишком плотным для публикации. Поэтому я бы использовал визуализацию, основанную на сюжетах, как предположил Парфе в своем ответе.

Это не было для меня очевидным решением, поэтому я хотел бы поблагодарить Парфе за его / ее ответ.

1 Ответ

0 голосов
/ 14 мая 2018

Рассмотрите возможность построения отдельных графиков на одном и том же рисунке с диапазонами осей Y, адаптированными к поднастроенным данным. Ниже демонстрируются случайные данные, отобранные для воспроизводимости (для читателей этого поста).

Данные (со значениями U выше, чем значения S)

import pandas as pd
import numpy as np
import seaborn
import matplotlib.pyplot as plt

np.random.seed(2018)
u_df = pd.DataFrame({'Day': pd.date_range('2016-10-01', periods=10)\
                              .append(pd.date_range('2016-10-01', periods=10)),
                     'n_data': np.random.uniform(0,800,20),
                     'Group': 'U'})

s_df = pd.DataFrame({'Day':  pd.date_range('2016-10-01', periods=10)\
                               .append(pd.date_range('2016-10-01', periods=10)),
                     'n_data': np.random.uniform(0,200,20),
                     'Group': 'S'})

df = pd.concat([u_df, s_df], ignore_index=True)
df['Day'] = df['Day'].astype('str')

Участок

fig = plt.figure(figsize=(10,5))

for i,g in enumerate(df.groupby('Group')):                
    plt.title('N_data of {}'.format(g[0]))    
    plt.subplot(2, 1, i+1) 

    seaborn.boxplot(x="Day", y="n_data", data=g[1], palette="PRGn", showfliers=False)

plt.tight_layout()
plt.show()
plt.clf()
plt.close('all')

Box Plot Output without Hue


Чтобы сохранить исходный оттенок и группировку, визуализируйте все не-группы n_data в np.nan:

fig = plt.figure(figsize=(10,5))

for i,g in enumerate(df.Group.unique()):             
    plt.subplot(2, 1, i+1)  

    tmp = df.copy()
    tmp.loc[tmp['Group']!=g, 'n_data'] = np.nan

    seaborn.boxplot(x="Day", y="n_data", hue="Group", data=tmp,
                    palette="PRGn", showfliers=False)

plt.tight_layout()
plt.show()
plt.clf()
plt.close('all')

Box Plot Output with Hue

...