【问题标题】:How to use seaborn for a time series boxplot with nested data?如何将 seaborn 用于具有嵌套数据的时间序列箱线图?
【发布时间】:2021-02-28 02:38:01
【问题描述】:

情况

我正在尝试使用单个和嵌套/分组数据创建箱线图。我使用的数据集代表了许多家庭的信息,其中一相和三相系统之间存在区别(#)

#NOTE id只出现一次的地方,户型是单相(1-phase),重复是3-phase system。由于重复,通过pd.read_csv(..) 读取 csv 文件将扩展重复的名称(即11.11.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='',hue='', y='', data='') 来创建分类图(Plotting with categorical data)。但是,我不知道如何格式化我的数据集以实现这一点?我尝试通过pd.melt(..) 函数(cfr.pandas.melt),但生成的格式改变了值出现的顺序(*)

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

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

亲切的问候,

雷米

【问题讨论】:

    标签: python seaborn boxplot categorical-data


    【解决方案1】:

    对于 seaborn 绘图,数据应该采用长格式而不是宽格式,因为您拥有不同的指标,例如 householdphasevalue。

    因此考虑实际上让 Pandas 重命名列 1、1.1、1.2,然后将 pd.melt 运行为长格式,并使用 assign 调整生成的 householdphase 列,在 . 上拆分并取分别是第一部分和第二部分:

    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 然后读回以进行 pandas 重命名过程)

    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
    
    

    绘图 (经过相同处理生成VoltageProfileFile_long

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2018-10-23
      相关资源
      最近更新 更多