python - 如何使用seaborn绘制带有嵌套数据的时间序列箱线图?

标签 python seaborn boxplot categorical-data

情况

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

Snippet from the exported csv

#NOTE Where the id appears only once, the household is single phased (1-phase) and duplicates are 3-phase system. Due to the duplicates, reading the csv-file via pd.read_csv(..) will extend the duplicate's names (i.e. 1, 1.1 and 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]:

Boxplot year simulation

结果是正确的,但如果只有 1 个刻度代表 1、1.1 和 1.2 或 5、5.1、5.2 等,那就很干净了。

问题

我想通过使用“分类”箱线图来清理这个问题,其中重复项(三相系统)的值被分组在同一 ID 下。我知道seaborn允许用户使用hue参数:sns.boxplot(x='',hue='', y='', data='')来创建分类图( Plotting with categorical data)。但是,我不知道如何格式化我的数据集才能实现这一目标?我尝试通过 pd.melt(..) 函数(cfr. pandas.melt ),但生成的格式更改了值出现的顺序 (*)

(*) Every id is accompanied by a length up to a reference point, thus the order of appearance on the x-axis must remain.

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

亲切的问候,

雷米

最佳答案

对于seaborn绘图,数据应该采用长格式而不是宽格式,因为你有不同的指标,例如家庭阶段值(value).

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

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

Image Output

关于python - 如何使用seaborn绘制带有嵌套数据的时间序列箱线图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64865779/

相关文章:

python - 为什么变量在 BGE Python 中不是全局的

python - 如何在seaborn中对齐x标签和y标签?

r - 将因子转换为 R 中箱线图的日期失败,并将 "st" "nd" "rd" "th"添加到日期

r - ggplot2 - 手动指定箱线图分面标签作为符号/数学表达式

python - 异常 : Failed to start new browser session: Error while launching browser Selenium in Python

python - Python 2.6 之前版本中 urllib2.urlopen() 的超时

javascript - 将单行 JavaScript 注释 (//) 与 re 匹配

python - 在 sns.kdeplot 中对 Z 轴进行对数变换

python - 控制散点图中的颜色

r - Ggplot2 Boxplot 宽度设置更改 x Axis