Python 如何将seaborn用于具有嵌套数据的时间序列箱线图? 处境

Python 如何将seaborn用于具有嵌套数据的时间序列箱线图? 处境,python,seaborn,boxplot,categorical-data,Python,Seaborn,Boxplot,Categorical Data,我正在尝试创建包含单个和嵌套/分组数据的箱线图。我使用的数据集表示多个家庭的信息,其中1阶段和3阶段系统之间存在区别(#) #注意如果id只出现一次,则家庭为单相(1相),重复的为3相系统。由于存在重复项,通过pd.read_csv(..)读取csv文件将扩展重复项的名称(即1、1.1和1.2) 使用基本绘图技术可提供: In [4]: VoltageProfileFile= pd.read_csv(dest + '/VoltageProfiles_' + str(PV_par['value_

我正在尝试创建包含单个和嵌套/分组数据的箱线图。我使用的数据集表示多个家庭的信息,其中1阶段和3阶段系统之间存在区别(#)

#注意如果id只出现一次,则家庭为单相(1相),重复的为3相系统。由于存在重复项,通过
pd.read_csv(..)
读取csv文件将扩展重复项的名称(即
1
1.1
1.2

使用基本绘图技术可提供:

In [4]: VoltageProfileFile= pd.read_csv(dest + '/VoltageProfiles_' + str(PV_par['value_PV']) + '%PV.csv', dtype= 'float')
   ...: VoltageProfileFile.boxplot(figsize=(20,5), rot= 60)
   ...: plt.ylim(0.9, 1.1)
   ...: plt.show()

Out[4]:

结果是正确的,但如果只有1个勾号表示1、1.1和1.2或5、5.1、5.2等,则是干净的

问题: 我想通过使用“分类”箱线图来解决这个问题,其中来自重复(三相系统)的值被分组在同一id下。我知道seaborn允许用户使用色调参数:
sns.boxplot(x='',色调='',y='',数据='')
来创建分类图()。然而,我不知道如何格式化我的数据集来实现这一点?我尝试通过
pd.melt(..)
函数(cfr.),但结果格式改变了值的显示顺序(*)

(*)每个id都有一个到一个参考点的长度,因此x轴上的出现顺序必须保持不变

解决这个问题的好办法是什么? 理想情况下,箱线图将三相系统分组在一个id下,并显示1ph和3ph系统的不同颜色

亲切问候,


Rémy

对于seaborn绘图,数据应采用长格式,而不是宽格式,因为它具有不同的指标,如家庭、阶段、价值

请考虑让熊猫重命名第1、1.1、1.2列,然后运行<代码> Pd。Eclipse < /C> >对生成的<代码>家庭< /代码>和<代码>阶段< /代码>使用“<代码>赋值< /代码>,在代码< >代码> >代码>,分别取第一部分和第二部分:

VoltageProfileFile_long = (pd.melt(VoltageProfileFile, var_name = 'phase')
                             .assign(household = lambda x: x['phase'].str.split("\\.").str[0].astype(int),
                                     phase = lambda x: pd.to_numeric(x['phase'].str.split("\\.").str[1]).fillna(0).astype(int).add(1))
                             .reindex(['household', 'phase', 'value'], axis='columns')
                          )

下面是一个随机数据的演示

数据(转储到csv,然后读回用于熊猫重命名过程)

绘图(经过相同的处理生成
电压档案文件_long

np.random.seed(111620)

VoltageProfileFile = pd.DataFrame([np.random.uniform(0.95, 1.05, 13) for i in range(50)], 
                                  columns = [1, 1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9])
VoltageProfileFile.to_csv('data.csv', index=False)

VoltageProfileFile = pd.read_csv('data.csv')
VoltageProfileFile.head(10)
#           1       1.1       1.2         2         3  ...       5.2         6         7         8         9
# 0  1.012732  1.042768  0.975577  0.965508  1.048544  ...  1.010898  1.008921  1.006769  1.019615  1.036926
# 1  1.013457  1.048378  1.025201  0.982988  0.995133  ...  1.024578  1.024362  0.985693  1.041609  0.995037
# 2  1.024739  1.008590  0.960278  0.956811  1.001739  ...  0.969436  0.953134  0.966851  1.031544  1.036572
# 3  1.037998  0.993246  0.970146  0.989196  0.959527  ...  1.015577  1.027020  1.038941  0.971666  1.040658
# 4  0.995877  0.955734  0.952497  1.040942  0.985759  ...  1.021805  1.044108  0.980657  1.034179  0.980722
# 5  0.994755  0.951557  0.986580  1.021583  0.959249  ...  1.046740  0.998429  1.027406  1.007391  0.989477
# 6  1.023979  1.043418  1.020745  1.006081  1.030413  ...  0.964579  1.035479  0.982969  0.953484  1.005889
# 7  1.018904  1.045440  1.003997  1.018295  0.954814  ...  0.955295  0.960958  0.999492  1.010163  0.985847
# 8  0.960913  0.982671  1.016659  1.030384  1.043750  ...  1.042720  0.972287  1.039235  0.969571  0.999418
# 9  1.017085  0.998049  0.989664  0.953420  1.018018  ...  0.953041  0.955883  1.004630  0.996443  1.017762

sns.set()

fig, ax = plt.subplots(figsize=(8,4))

sns.boxplot(x='household', y='value', hue='phase', data=VoltageProfileFile_long, ax=ax)
plt.title('Boxplot of Values by Household and Phases')
plt.tight_layout()

plt.show()
plt.clf()
plt.close()