云雨图&小提琴图的作用
1. 云雨图(Half-Violin Plot)
定义
云雨图是一种结合了 小提琴图 和 散点图 的图形表现形式,其中:
- 一侧展示小提琴图(通常用于显示数据的分布密度)。
- 另一侧叠加散点图,展示每个数据点的原始数值分布。
特点
- 半小提琴图(half-violin):将传统小提琴图切为一半,通常位于图形的右侧或左侧。
- 散点图叠加:用于展示每个数据点的具体位置,从而避免分布密度掩盖数据细节。
作用
- 数据分布和细节并重:
- 小提琴部分展示数据的全局分布(如峰值和尾部情况)。
- 散点部分提供具体的观测点分布,帮助发现异常值或分布的离散程度。
- 易于分组对比:适合分组数据的可视化(如不同实验条件、类别变量)。
2. 小提琴图(Violin Plot)
定义
小提琴图是一种结合了 箱线图 和 核密度图 的数据可视化工具,用于描述数据的分布形态。
特点
- 中心部分包含一个 箱线图,显示分布的五数概要(最小值、第一四分位数、中位数、第三四分位数、最大值)。
- 两侧对称展示 核密度估计,表示数据的分布密度。
- 形状宽度反映数据分布的密集程度(宽的部分表示该范围内的数据点更多)。
作用
- 显示数据分布形态:
- 比单纯的箱线图更详细,能够直观地看到数据分布的偏态、峰值和多模态特征。
- 数据对比:
- 特别适合多个分组的数据比较。
- 不同宽度的区域展示了各分组的分布差异,例如分布是否对称、是否存在多个峰值。
- 整合数据摘要:
- 通过同时显示箱线图和核密度估计,小提琴图提供了数据的全景视角。



数据结构

云雨图代码
1. 导入库和读取数据
library(ggplot2)
library(dplyr)
library(RColorBrewer)
library(viridis)
library(ggpubr)
library(rstatix)
library(gghalves)
library(patchwork)
library(openxlsx)
data1 <- read.xlsx("aaa.xlsx")
data1$prob <- factor(data1$prob)
data1$outcome <- factor(data1$outcome)
data1$delay <- as.numeric(data1$delay)
-
加载库:
ggplot2:主要用于数据可视化。dplyr:用于数据过滤和处理。openxlsx:读取 Excel 数据。- 其他库(如
gghalves)提供了额外的绘图功能,如半小提琴图。
-
数据预处理:
- 使用
read.xlsx读取 Excel 文件aaa.xlsx。 - 将
prob和outcome转换为因子(分类变量),便于分组绘图。 - 将
delay转换为数值型,以便用于数值分布图。
- 使用
2. 定义颜色映射
colors = c('#889ECE','#F4E636','#29C4A1','#F3640E','lightgreen')
names(colors) = c('20','30','70','80','90')
- 定义了一组颜色
colors,并将颜色与prob的具体分类值(20、30、70、80、90)绑定。 scale_fill_manual和scale_color_manual后续会引用这些颜色,用于为小提琴图、箱线图和散点图分组上色。
3. 按分组绘图
for (outcome_id in unique(data1$outcome)) {
data_outcome <- data1 %>%
filter(outcome == outcome_id)
- 循环:
- 遍历
outcome的所有唯一值。 - 使用
filter筛选出当前循环下的子数据data_outcome,确保每个分组独立绘图。
- 遍历
4. 构建图形
p <- ggplot(data_outcome, aes(x = prob, y = delay)) +
geom_half_violin(aes(fill = prob, color = prob), side = 'r', position = position_nudge(x = 0.35, y = 0)) +
geom_boxplot(aes(fill = prob, color = prob), outliers = FALSE, width = 0.12, cex = 0.8, alpha = 0.5, position = position_nudge(x = 0.22, y = 0)) +
geom_jitter(color = "grey60", width = 0.1, size = 0.6, alpha = 0.9) +
...
绘图层解析:
-
geom_half_violin:- 功能:绘制半小提琴图,展示每组数据的分布形态。
- 参数:
fill和color按prob分类着色。side = 'r':小提琴图在右侧。position_nudge:将小提琴图稍微向右平移,避免与其他图层重叠。
-
geom_boxplot:- 功能:绘制箱线图,显示分组的五数概要(最小值、四分位数和最大值)。
- 参数:
outliers = FALSE:隐藏离群点。width = 0.12:调整箱线图宽度。position_nudge:将箱线图向右平移,与小提琴图对齐。
-
geom_jitter:- 功能:叠加散点图,展示每个数据点的分布。
- 参数:
color = "grey60":散点颜色设置为灰色。width = 0.1:在 X 轴方向上添加少量随机抖动,避免散点重叠。
5. 坐标轴与配色
scale_color_manual(values = colors) +
scale_fill_manual(values = colors) +
scale_y_continuous(limits = c(0,50)) +
scale_x_discrete() +
coord_flip()
-
颜色:
scale_color_manual和scale_fill_manual使用自定义颜色colors。
-
坐标轴:
scale_y_continuous设置 Y 轴范围为 [0, 50]。coord_flip将 X 和 Y 轴翻转,使分类变量prob位于垂直方向。
6. 图表标签与标题
labs(
x = "Probability (%)",
y = "Delay (Months)",
fill = "概率水平",
color = "概率水平"
) +
ggtitle(paste("个体等量参数转换点---", outcome_id, "元"))
-
标签:
- 自定义 X 轴和 Y 轴的标题。
- 为图例设置标题
fill和color,同时支持中文显示。
-
标题:
ggtitle动态生成标题,包含当前分组的outcome值。
7. 自定义主题
theme_minimal() +
theme(
text = element_text(size = 13),
plot.title = element_text(size = 15.5, face = "bold", family = "Arial", color = "black", hjust = 0.5),
axis.text.x = element_text(size = 14, family = "Arial", color = "black", margin = margin(t = 6)),
axis.text.y = element_text(size = 14, family = "Arial", color = "black", margin = margin(r = 4)),
...
)
- 使用
theme_minimal创建简洁的主题,并细化各部分样式。 - 细节调整:
- 标题字体设置为加粗 (
face = "bold")。 - 轴标签、图例标题和文本字体大小分别调整。
- 标题字体设置为加粗 (
8. 保存图像
ggsave(filename = paste0("云雨图_修订", outcome_id, ".png"), plot = p, width = 8, height = 6)
- 每次循环保存当前分组的图像,文件名包含分组信息
outcome_id。 - 图像格式为 PNG,尺寸为 8 × 6 英寸。
总结
# 加载必要的库
library(ggplot2) # 数据可视化
library(dplyr) # 数据处理
library(RColorBrewer) # 调色板
library(viridis) # 色盲友好配色方案
library(ggpubr) # 增强 ggplot2 功能
library(rstatix) # 统计分析辅助
library(gghalves) # 半小提琴图
library(patchwork) # 组合图表
library(openxlsx) # 读取 Excel 数据
# 读取数据
data1 <- read.xlsx("aaa.xlsx") # 读取 Excel 文件
data1$prob <- factor(data1$prob) # 将 prob 转换为因子变量
data1$outcome <- factor(data1$outcome) # 将 outcome 转换为因子变量
data1$delay <- as.numeric(data1$delay) # 将 delay 转换为数值型变量
# 自定义颜色映射
colors <- c('#889ECE', '#F4E636', '#29C4A1', '#F3640E', 'lightgreen')
names(colors) <- c('20', '30', '70', '80', '90') # 将颜色与 prob 分类值绑定
# 循环绘图并保存
for (outcome_id in unique(data1$outcome)) {
# 筛选当前分组数据
data_outcome <- data1 %>%
filter(outcome == outcome_id)
# 创建图形
p <- ggplot(data_outcome, aes(x = prob, y = delay)) +
# 添加半小提琴图
geom_half_violin(
aes(fill = prob, color = prob),
side = 'r', # 半小提琴在右侧
position = position_nudge(x = 0.35, y = 0) # 平移位置避免重叠
) +
# 添加箱线图
geom_boxplot(
aes(fill = prob, color = prob),
outliers = FALSE, # 不显示离群点
width = 0.12, # 箱线图宽度
cex = 0.8, # 边框线宽
alpha = 0.5, # 半透明效果
position = position_nudge(x = 0.22, y = 0) # 平移位置
) +
# 添加散点图
geom_jitter(
color = "grey60", # 散点颜色
width = 0.1, # 水平方向抖动
size = 0.6, # 散点大小
alpha = 0.9 # 不透明度
) +
# 自定义颜色映射
scale_color_manual(values = colors) +
scale_fill_manual(values = colors) +
# 设置坐标轴范围
scale_y_continuous(limits = c(0, 50)) +
scale_x_discrete() +
coord_flip() + # 翻转坐标轴(X 和 Y 交换位置)
# 设置标签
labs(
x = "Probability (%)", # X 轴标签
y = "Delay (Months)", # Y 轴标签
fill = "概率水平", # 填充图例标题
color = "概率水平" # 边框图例标题
) +
# 设置图表标题
ggtitle(paste("个体等量参数转换点---", outcome_id, "元")) +
# 设置主题样式
theme_minimal() +
theme(
text = element_text(size = 13), # 全局文字大小
plot.title = element_text(size = 15.5, face = "bold", family = "Arial", color = "black", hjust = 0.5),
axis.text.x = element_text(size = 14, family = "Arial", color = "black", margin = margin(t = 6)),
axis.text.y = element_text(size = 14, family = "Arial", color = "black", margin = margin(r = 4)),
axis.title.x = element_text(size = 15, family = "Arial", color = "black"),
axis.title.y = element_text(size = 15, family = "Arial", color = "black"),
legend.title = element_text(size = 11, family = "Arial", color = "black", face = "bold"),
legend.text = element_text(size = 10, family = "Arial", color = "black"),
axis.ticks.x = element_line(linewidth = 0.6), # X 轴刻度线宽度
axis.ticks.y = element_line(linewidth = 0.6), # Y 轴刻度线宽度
axis.ticks.length = unit(-0.15, "cm"), # 刻度线长度
axis.line = element_line(linewidth = 0.7), # 坐标轴线宽度
panel.grid = element_blank() # 去除网格线
)
# 保存图像
ggsave(
filename = paste0("云雨图_修订", outcome_id, ".png"), # 动态生成文件名
plot = p,
width = 8,
height = 6
)
}
小提琴图代码
在上面代码的基础上稍微更改一下即可
# 加载必要的库
library(ggplot2) # 数据可视化
library(dplyr) # 数据操作
library(openxlsx) # 读取 Excel 数据
# 读取数据
data1 <- read.xlsx("aaa.xlsx") # 读取 Excel 文件
data1$prob <- factor(data1$prob) # 将 prob 转换为因子变量
data1$outcome <- factor(data1$outcome) # 将 outcome 转换为因子变量
data1$delay <- as.numeric(data1$delay) # 将 delay 转换为数值型变量
# 按分组绘制并保存图形
for (outcome_id in unique(data1$outcome)) {
# 筛选当前分组的数据
data_outcome <- data1 %>%
filter(outcome == outcome_id)
# 绘制图形
p <- ggplot(data_outcome, aes(x = prob, y = delay, fill = prob)) +
# 小提琴图
geom_violin(trim = FALSE, scale = "width", color = NA, alpha = 0.35) +
# trim = FALSE 保留尾部;scale = "width" 保持宽度一致;color = NA 去除边框
# 叠加箱线图
geom_boxplot(width = 0.2, color = "black", outlier.shape = NA, alpha = 0.4) +
# width 调整宽度;color 设置边框颜色;outlier.shape = NA 隐藏离群点;alpha 设置透明度
# 叠加散点图
geom_jitter(aes(color = prob), width = 0.2, height = 0, alpha = 1) +
# width = 0.2 添加抖动;height = 0 保持垂直对齐;alpha = 1 不透明
# 自定义坐标轴
scale_x_discrete() +
scale_y_continuous(breaks = seq(0, 60, by = 20)) +
coord_cartesian(ylim = c(0, 60)) +
# coord_cartesian 限制 Y 轴范围为 0 到 60
# 自定义填充和边框颜色
scale_fill_manual(values = c("palevioletred", "peachpuff", "lightgreen", "lightblue", "plum")) +
scale_color_manual(values = c("palevioletred", "peachpuff", "lightgreen", "lightblue", "plum")) +
# 添加标签
labs(
x = "Probability (%)", # X 轴标签
y = "Delay (Months)", # Y 轴标签
fill = "概率水平", # 填充图例标题
color = "概率水平" # 边框图例标题
) +
# 添加图表标题
ggtitle(paste("个体等量参数转换点---", outcome_id, "元")) +
# 设置主题
theme_minimal() +
theme(
text = element_text(size = 13), # 全局文本大小
plot.title = element_text(size = 15.5, face = "bold", family = "Arial", color = "black", hjust = 0.5),
axis.text.x = element_text(size = 14, family = "Arial", color = "black", margin = margin(t = 6)),
axis.text.y = element_text(size = 14, family = "Arial", color = "black", margin = margin(r = 4)),
axis.title.x = element_text(size = 15, family = "Arial", color = "black"),
axis.title.y = element_text(size = 15, family = "Arial", color = "black"),
legend.title = element_text(size = 11, family = "Arial", color = "black", face = "bold"),
legend.text = element_text(size = 10, family = "Arial", color = "black"),
axis.ticks.x = element_line(linewidth = 0.6),
axis.ticks.y = element_line(linewidth = 0.6),
axis.ticks.length = unit(-0.15, "cm"),
axis.line = element_line(linewidth = 0.7),
panel.grid = element_blank()
)
# 保存图像
ggsave(
filename = paste0("小提琴图_", outcome_id, "元", ".png"), # 文件名动态生成
plot = p,
width = 8,
height = 6
)
}



1244

被折叠的 条评论
为什么被折叠?



