情况
我正在尝试使用单独和嵌套/分组数据创建箱线图。我使用的数据集代表了许多家庭的信息,其中一相系统和三相系统之间存在区别(#)
#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
and1.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允许用户使用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
运行为长格式,并调整生成的 household
和 phase
列使用 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()
关于python - 如何使用seaborn绘制带有嵌套数据的时间序列箱线图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64865779/