
做科研的人,写论文时最头疼的事情之一,大概就是怎么把数据“说清楚”。我们习惯用柱状图加误差棒,或者箱线图,一眼看上去很干净,但仔细一看,经常会发现它们把分布形状、个体差异、甚至是否存在多峰,都藏起来了。读者看到的只是一个均值和置信区间,却很难判断这个效应到底靠不靠谱,或者背后数据是不是有异常模式。
2019年前后,Micah Allen、Davide Poggiali、Kirstie Whitaker等人提出的云雨图(Raincloud Plot),就是在这种背景下出现的。它把概率密度(云)、原始数据点(雨)和中心趋势统计量(通常是箱线图或均值)叠在一起,既保留了“一眼能看出差异”的直观性,又把底层数据尽量摊开。
在其论文中,还配套了R、Python、MATLAB的开源代码,之后在心理学、神经科学、医学等多个领域慢慢流行起来。
这篇文章我想尽量实在地介绍:它到底是什么、什么时候用最合适、以及目前主流的几种画法。希望能帮到那些正在准备投稿、或者想把图表做得更透明的同事。
什么是云雨图(Raincloud Plot)?
云雨图本质上是一种组合可视化。它通常由三部分构成:
1. 云(Cloud):半小提琴图(half-violin / split-half violin),也就是只画概率密度的一边,避免传统小提琴图对称镜像带来的冗余。
2. 雨(Rain):抖动后的原始数据点(jittered points / strip plot / beeswarm),让每一条观测都可见。
3. 统计摘要:常加箱线图(显示中位数、四分位距、异常值),或者均值+置信区间。
名字的由来很形象:半小提琴像云,数据点像雨点落下来,合在一起就成了“雨云”。它既不是单纯的小提琴图,也不是单纯的散点图,而是把分布形状、个体位置和汇总统计放在同一幅图里,尽量减少信息损失。

雨云图示例(来源:https://wellcomeopenresearch.org/articles/4-63/v2)
经典文献里,Allen等人特别强调它解决了柱状图和箱线图的两个常见问题:一是隐藏了数据分布(比如偏态、多峰),二是掩盖了样本量与个体模式。半小提琴只画一边,也符合Tufte提出的“数据墨水比”原则——不画多余的对称部分。
云雨图适用场景
不是所有数据都适合云雨图,但下面这些情况它往往比柱状图或普通箱线图更有说服力:
- 样本量中等、需要展示分布形状时。比如每组n在20–200之间,既想看中位数差异,又想知道数据是否偏态、是否有双峰。临床量表、行为实验反应时、基因表达量这类连续变量很常见。
- 组间比较,尤其关心个体变异。心理学、神经科学里的组别设计(对照组 vs 实验组)、药物试验前后对比,都能用它同时看到“整体趋势”和“每个人的位置”。
- 重复测量或配对数据。现在的`ggrain`等包支持用线把同一个体前后点连起来,能直观看到谁上升、谁下降、变异是否缩小。
- 探索性分析或开放科学报告。当审稿人要求“请展示原始数据”时,云雨图比单纯加散点的箱线图更完整;也方便读者自己判断统计假设是否合理。
- 需要兼顾美观与信息量的投稿图。很多期刊现在更欢迎透明可视化,云雨图在Psychonomic Bulletin & Review等期刊里的使用比例已明显上升。
不太适合的情况也要心里有数:样本量极小(n<10)时密度估计不稳定;组数特别多(>10)时图会变得拥挤;分类数据或严格的有序量表有时用其他图更合适。
总之,它的核心优势是透明:读者能同时看到“云”的形状、“雨”的个体和摘要统计,减少“只看均值就下结论”的风险。
如何画云雨图
目前主流实现主要集中在R和Python,MATLAB也有官方函数。下面按常用程度简单列出,代码都尽量可直接运行。
1. R
推荐:ggrain包(CRAN可直接安装)
R
install.packages("ggrain")
library(ggrain)
library(ggplot2)
# 最简单的例子:iris数据
ggplot(iris, aes(Species, Sepal.Length, fill = Species)) +
geom_rain() +
theme_classic() +
scale_fill_brewer(palette = "Dark2")
geom_rain()默认把半小提琴、箱线图和抖动点组合在一起。常用参数:
- rain.side = "l"或 "r":雨点放左边还是右边
- id.long.var:重复测量时连接同一个体的线
- 各组件可用violin.args、boxplot.args、point.args单独调整透明度、颜色等
更早期的raincloudplots包(https://github.com/jorvlan/raincloudplots )也很好用,尤其适合1×1、2×2等设计。原始教程脚本在RainCloudPlots仓库的tutorial_R文件夹。

用ggdist也可以自己拼:
R
library(ggdist)
# 半眼图 + 点间隔 的组合也能做出类似效果
2. Python
ptitprince包
bash
pip install ptitprince
python
import ptitprince as pt
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset("iris")
f, ax = plt.subplots(figsize=(7, 5))
pt.RainCloud(x="species", y="sepal_length", data=df,
palette="Set2", bw=0.2, width_viol=0.6,
ax=ax, orient="h")
plt.show()
另外还有raincloudpy等较新的实现,支持密度对齐的散点。
3. 其他
- MATLAB:从R2023b起有raincloudplot函数,直接传向量或矩阵即可。
- JASP等统计软件也开始内置云雨图选项,适合不太写代码的用户。
画图时建议注意几点:
- 半小提琴的带宽要根据数据调整,过平滑会掩盖多峰。
- 抖动宽度适中,避免点重叠严重。
- 颜色尽量用色盲友好的调色板,并考虑黑白打印。
- 如果投稿,记得在图注里说明“半小提琴显示密度估计,箱线图显示中位数与四分位距,点为原始观测”。
原论文和GitHub仓库提供了大量可复现的教程(https://github.com/RainCloudPlots/RainCloudPlots ),从最基础的柱状图对比到重复测量、因子设计都有,建议直接下载代码改自己的数据。
最后
云雨图不是万能的,但它确实把“展示分布 + 展示个体 + 展示摘要”这件事做得比较干净。对很多需要报告组间差异或前后变化的科研工作来说,它能减少读者(和审稿人)的猜疑,也更符合当前开放科学对透明可视化的要求。
如果你正在准备下一篇投稿,不妨先用自己的数据试画一张,对比一下原来的柱状图或箱线图——很多时候差异会比想象中明显。
