使用色调和不同比例轴的Seaborn(时间序列)箱线图

时间:2018-05-13 12:34:46

标签: python pandas time-series seaborn boxplot

我有一个数据框,每个日期有多个值(日期时间字段)。使用列将此值分类为U(用户)和S(会话)。 Seaborn用于显示每个日期的两个箱图,其中色调设置为 Group

当考虑到与U(用户)对应的值比对应于S( session )的值大得多时,问题就出现了,使得S数据难以辨认。因此,我需要提出一个解决方案,允许我以可理解的方式在同一图中绘制系列(U和S)。

我想知道是否可以为每个色调设置独立的Y轴(具有不同的比例),以便显示两个Y轴(如使用twinx但不失去色调可视化功能)。

欢迎任何其他替代方案=)

S boxplot时间序列boxplot:

The S boxplot time series boxplot

使用色调的组合boxplot时间序列。显然,由于Y轴的比例,不可能看到有关S组的任何信息:

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)|

生成组合boxplot的代码行:

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.

在这种情况下,过于密集而无法发布。因此,我会采用基于子图的可视化,因为Parfait在他/她的答案中持续存在。

这对我来说不是一个明显的解决方案,所以我要感谢Parfait的回答。

2 个答案:

答案 0 :(得分:1)

因此,使用两个单独的轴进行分组箱线图的一种选择是在 hue_order= ['value, np.nan] 的参数中使用 sns.boxplot

fig = plt.figure(figsize=(14,8))

ax = sns.boxplot(x="lon_bucketed", y="value", data=m, hue='name', hue_order=['co2',np.nan],
                 width=0.75,showmeans=True,meanprops={"marker":"s","markerfacecolor":"black", "markeredgecolor":"black"},linewidth=0.5 ,palette = customPalette)
ax2 = ax.twinx()

ax2 = sns.boxplot(ax=ax2,x="lon_bucketed", y="value", data=m, hue='name', hue_order=[np.nan,'g_xco2'],
                 width=0.75,showmeans=True,meanprops={"marker":"s","markerfacecolor":"black", "markeredgecolor":"black"},linewidth=0.5, palette = customPalette)
ax1.grid(alpha=0.5, which = 'major')
plt.tight_layout()
ax.legend_.remove()
GW = mpatches.Patch(color='seagreen', label='$CO_2$')
WW = mpatches.Patch(color='mediumaquamarine', label='$XCO_2$')

ax, ax2.legend(handles=[GW,WW], loc='upper right',prop={'size': 14}, fontsize=12)

ax.set_title("$XCO_2$ vs. $CO_2$",fontsize=18)
ax.set_xlabel('Longitude [\u00b0]',fontsize=14)
ax.set_ylabel('$CO_2$ [ppm]',fontsize=14)
ax2.set_ylabel('$XCO_2$ [ppm]',fontsize=14)
ax.tick_params(labelsize=14)

enter image description here

答案 1 :(得分:0)

考虑在同一图上构建单独的图,其中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