python绘制雨云图(Raincloud)
2022-01-11
技术
在做探索性分析时,箱线图和小提琴图已经很常见,但如果你既想保留分布信息,又想让图形更有层次感,雨云图通常会更有表现力。它把小提琴图、箱线图和散点层叠在一起,既能看总体分布,也能看到离散点细节。
这篇文章重点解决 3 个问题:
- 雨云图到底由哪些图层组成
- 如何用 Python 一步步把这些图层叠出来
- 输出后应该检查哪些细节,避免图看起来漂亮但不够清楚
介绍
雨云图其实是一种混合图,由四部分组成,它们分别是 violin plot(云)、boxplot(伞)、swarm plot(雨)。
数据准备
仍然以企鹅数据作为示例,本站也已经提供,可直接下载: 企鹅数据
下载数据
pip install ptitprince
wget https://www.bobobk.com/wp-content/uploads/2021/12/penguins.csv
这里用的是企鹅数据集,比较适合演示分类变量加连续变量的分布差异。
载入数据
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("penguins.csv")
df.head()
结果
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
0 Adelie Torgersen 39.1 18.7 181.0 3750.0 MALE
1 Adelie Torgersen 39.5 17.4 186.0 3800.0 FEMALE
2 Adelie Torgersen 40.3 18.0 195.0 3250.0 FEMALE
3 Adelie Torgersen NaN NaN NaN NaN NaN
4 Adelie Torgersen 36.7 19.3 193.0 3450.0 FEMALE
开始绘图
前面我们通过pip已经安装了ptitprince包,现在真正开始绘制
violin图
首先是一半的小提琴图,即雨云图的云的部分,数据是bill_length_mm这个变量,以岛屿分组,其中half_violinplot函数负责半个小提琴图(violin plot),inner控制下方的小线条,为了使云位置摆放正确,将变量放在Y轴上
import matplotlib.pyplot as plt
import ptitprince as pt
pt.half_violinplot(data=df,y="island",x="bill_length_mm",inner=None)
plt.savefig("half_violin.png",dpi=200)

boxplot图
接下来是伞的部分
pt.half_violinplot(data=df,y="island",x="bill_length_mm",inner=None)
sns.boxplot(data=df,y="island",x="bill_length_mm",width = .15, zorder = 10,boxprops = {'facecolor':'none', "zorder":10},
whiskerprops = {'linewidth':2, "zorder":10})
plt.savefig("violin_box.png",dpi=200)

strip plot图
雨云图的雨部分,使用stripplot,并通过jitter参数将散点分散
pt.half_violinplot(data=df,y="island",x="bill_length_mm",inner=None)
sns.boxplot(data=df,y="island",x="bill_length_mm",width = .15, zorder = 10,boxprops = {'facecolor':'none', "zorder":10},
whiskerprops = {'linewidth':2, "zorder":10})
sns.stripplot(data=df,y="island",x="bill_length_mm",jitter=1,edgecolor = "white",zorder = 0)
plt.savefig("raincloud.png",dpi=200)

R 实现
同样这里将R语言实现的雨云图一并呈上
library(ggplot2)
library(ggdist)
df = read.table("penguins.csv",sep=",",header=TRUE)
pdf("raincloud.pdf",width=14, height=7)
ggplot(data=df,aes(y=bill_length_mm,x=factor(island),fill=factor(island)))+
ggdist::stat_halfeye(adjust=0.5,justification=-.2,.width=0,point_colour=NA) +
geom_boxplot(width=0.2,outlier.color=NA) +
ggdist::stat_dots(side="left",justification=1.1)
dev.off()

实际使用时优先调整哪些参数
如果你要把图放到论文、汇报或者网页里,通常先调这几项:
jitter:控制散点分散程度,避免点完全重叠width:控制 boxplot 宽度,让伞不要遮住云层adjust或 violin 的平滑程度:避免云层过宽或过窄- 配色:尽量避免颜色太杂,优先统一风格再做局部高亮
如何检查雨云图是否足够清晰
绘图完成后,建议至少确认:
- 各组分布是否都能看清,没有图层互相遮挡
- 散点密集区域是否还能分辨
- 分类标签和数值轴是否完整显示
- 导出的图片缩小后是否仍然可读
如果你准备正式使用,建议导出一张高分辨率图片:
plt.savefig("raincloud.png", dpi=300, bbox_inches="tight")
常见问题
1. 图层叠在一起后显得太乱
最常见原因是点太密、颜色太重,或者箱线图太宽。
修复:
- 降低
jitter或减小点大小 - 缩小
boxplot宽度 - 减少颜色种类
2. 小提琴图看起来不自然
通常是平滑参数不合适,或者样本量太小。
修复:
- 调整
adjust - 对样本太少的分组谨慎使用 violin 层
- 必要时只保留 boxplot + stripplot
3. 导出的图片不够清楚
修复:
- 提高
dpi - 使用
bbox_inches="tight" - 在正式排版前先看缩小后的效果
延伸阅读
总结
本文通过将violin小提琴图与boxplot箱线图,stripplot进行结合创造出雨云图,该图在展示数据分布上更加直观,好看。
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/791.html
- 版权声明:本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。