install.packages("ggplot2")
install.packages("dplyr")
install.packages("GGally")
install.packages("corrplot")
install.packages("vcd")R语言绘图:标注、气泡图、散点图矩阵、相关图、马赛克图与图形修改
1. 本节学习目标
本节学习以下图形:
- 图形标注、标尺、主题与刻面
- 气泡图
- 散点图矩阵
- 分组散点图
- 相关图
- 马赛克图
- 图形修改与美化
主要用到这些包:
ggplot2
dplyr
GGally
corrplot
vcd其中:
| 包 | 作用 |
|---|---|
ggplot2 |
基础绘图 |
dplyr |
数据整理 |
GGally |
散点图矩阵 |
corrplot |
相关图 |
vcd |
马赛克图,尤其是带残差着色的马赛克图 |
说明:
- 基础马赛克图使用 R 自带的
mosaicplot(); vcd::mosaic()功能更丰富,可以进行残差着色;- 但在某些中文标签或多维列联表场景下,
vcd::mosaic()在 Knit 时可能出现兼容性问题; - 因此本文保留
vcd示例,但不自动执行vcd::mosaic()代码。
2. 安装和加载包
如果没有安装,可以先运行:
加载基础包:
library(ggplot2)
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
检查后面会用到的扩展包:
if (!requireNamespace("GGally", quietly = TRUE)) {
message("未安装 GGally,散点图矩阵部分将不会绘图。")
}
if (!requireNamespace("corrplot", quietly = TRUE)) {
message("未安装 corrplot,相关图部分将不会绘图。")
}
if (!requireNamespace("vcd", quietly = TRUE)) {
message("未安装 vcd,vcd 示例代码仅展示,不影响本文运行。")
}3. 创建示例数据
我们创建一个学生数据集。
set.seed(123)
student <- data.frame(
id = 1:120,
class = rep(c("一班", "二班", "三班"), each = 40),
gender = sample(c("男", "女"), 120, replace = TRUE),
group = sample(c("实验组", "对照组"), 120, replace = TRUE),
chinese = round(rnorm(120, mean = 82, sd = 8), 1),
math = round(rnorm(120, mean = 80, sd = 10), 1),
english = round(rnorm(120, mean = 84, sd = 7), 1),
height = round(rnorm(120, mean = 168, sd = 8), 1),
weight = round(rnorm(120, mean = 62, sd = 10), 1)
)
student$total <- student$chinese + student$math + student$english
student$average <- round(student$total / 3, 1)
student$class <- factor(
student$class,
levels = c("一班", "二班", "三班"),
ordered = TRUE
)
head(student,5) id class gender group chinese math english height weight total average
1 1 一班 男 实验组 82.9 72.1 82.6 168.2 72.7 237.6 79.2
2 2 一班 男 对照组 74.4 75.0 88.6 170.5 61.7 238.0 79.3
3 3 一班 男 实验组 78.1 95.0 85.9 178.6 61.7 259.0 86.3
4 4 一班 女 实验组 80.0 68.6 91.2 169.0 46.8 239.8 79.9
5 5 一班 男 实验组 96.8 78.2 89.7 173.7 69.9 264.7 88.2
查看数据结构:
str(student)'data.frame': 120 obs. of 11 variables:
$ id : int 1 2 3 4 5 6 7 8 9 10 ...
$ class : Ord.factor w/ 3 levels "一班"<"二班"<..: 1 1 1 1 1 1 1 1 1 1 ...
$ gender : chr "男" "男" "男" "女" ...
$ group : chr "实验组" "对照组" "实验组" "实验组" ...
$ chinese: num 82.9 74.4 78.1 80 96.8 76.8 83.9 82.6 74.3 81.4 ...
$ math : num 72.1 75 95 68.6 78.2 99 79 66.4 73.4 84.9 ...
$ english: num 82.6 88.6 85.9 91.2 89.7 82.5 86.6 77.4 90 80.8 ...
$ height : num 168 170 179 169 174 ...
$ weight : num 72.7 61.7 61.7 46.8 69.9 59.9 55.4 47.9 59 53.5 ...
$ total : num 238 238 259 240 265 ...
$ average: num 79.2 79.3 86.3 79.9 88.2 86.1 83.2 75.5 79.2 82.4 ...
4. 图形标注、标尺、主题与刻面
本节主要学习如何在 ggplot2 图形中添加标注,并对图形进行常见修改,包括:
- 添加文字标注;
- 只标注部分数据点;
- 给条形图添加数值标注;
- 添加参考线和参考线说明文字;
- 修改坐标轴标尺;
- 修改图形主题;
- 使用刻面展示分组图形。
4.1 什么是图形标注?
图形标注就是在图中添加文字说明,例如:
- 给某个点添加编号;
- 给柱子添加数值;
- 标出高分学生;
- 添加参考线;
- 给参考线添加说明文字;
- 在图中添加解释性文本。
常用函数如下:
| 函数 | 作用 |
|---|---|
geom_text() |
添加普通文字 |
geom_label() |
添加带边框的标签 |
annotate() |
添加固定文字或图形 |
geom_vline() |
添加竖直参考线 |
geom_hline() |
添加水平参考线 |
geom_abline() |
添加斜线 |
4.2 散点图 + 文字标注
先画一个语文成绩和数学成绩的基础散点图。
ggplot(student, aes(x = chinese, y = math)) +
geom_point() +
labs(
title = "语文成绩与数学成绩散点图",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()如果想给每个点标注学生编号,可以使用 geom_text()。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue") +
geom_text(
aes(label = id),
vjust = -0.5,
size = 3
) +
labs(
title = "语文成绩与数学成绩散点图:标注学生编号",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()说明:
geom_point()用来画散点;geom_text()用来添加文字;aes(label = id)表示把学生编号作为文字标签;vjust = -0.5表示文字显示在点的上方。
注意:如果点很多,不建议给每个点都添加文字标注,否则图形会比较拥挤。
4.3 只标注高分学生
实际绘图时,更常见的做法是只标注部分重点数据。
例如,只标注平均分大于 95 的学生。
high_student <- student %>%
filter(average > 95)
high_student id class gender group chinese math english height weight total average
1 111 三班 女 实验组 97.6 90.1 97.8 145.5 72.6 285.5 95.2
画图:
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "grey50", alpha = 0.7) +
geom_point(
data = high_student,
color = "red",
size = 3
) +
geom_text(
data = high_student,
aes(label = id),
vjust = -0.6,
color = "red",
size = 4
) +
labs(
title = "只标注平均分大于95的学生",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()解释:
- 第一层
geom_point()画所有学生; - 第二层
geom_point(data = high_student)突出高分学生; - 第三层
geom_text(data = high_student)给高分学生加标签。
4.4 使用 geom_label() 添加标签
geom_label() 和 geom_text() 类似,但它会给文字添加一个标签框。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "grey50", alpha = 0.7) +
geom_label(
data = high_student,
aes(label = paste0("ID=", id)),
fill = "yellow",
color = "red",
size = 3
) +
labs(
title = "使用 geom_label() 标注高分学生",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()说明:
fill = "yellow"控制标签框的填充颜色;color = "red"控制文字颜色;paste0("ID=", id)把编号写成ID=编号的形式。
4.5 条形图 + 数值标注
除了散点图,条形图也经常需要添加数值标注。
下面先计算每个班级的平均分。
class_avg <- student %>%
group_by(class) %>%
summarise(
avg_score = mean(average, na.rm = TRUE), #每个班级的平均分,忽视缺失值
.groups = "drop" #手动关闭分组,把数据变回普通数据框。
)
class_avg# A tibble: 3 × 2
class avg_score
<ord> <dbl>
1 一班 81.9
2 二班 82.6
3 三班 82.3
画条形图,并在柱子上方添加平均分数值。
ggplot(class_avg, aes(x = class, y = avg_score, fill = class)) +
geom_col(width = 0.6) +
geom_text(
aes(label = round(avg_score, 1)),
vjust = -0.5,
size = 4
) +
scale_y_continuous(
limits = c(0, 100),
breaks = seq(0, 100, 20)
) +
labs(
title = "不同班级平均成绩比较",
x = "班级",
y = "平均成绩"
) +
theme_minimal() +
theme(
legend.position = "none"
)解释:
geom_col()用于画已经汇总好的柱形图;geom_text()用于给柱子添加数值;label = round(avg_score, 1)表示平均分保留一位小数;vjust = -0.5表示文字放在柱子上方;legend.position = "none"表示去掉图例。
4.6 添加参考线
参考线可以帮助读者快速判断数据是否超过某个标准。
下面添加数学 80 分横线和语文 80 分竖线。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue", alpha = 0.7) +
geom_hline(
yintercept = 80,
linetype = "dashed",
color = "red"
) +
geom_vline(
xintercept = 80,
linetype = "dashed",
color = "red"
) +
labs(
title = "语文和数学成绩散点图:添加80分参考线",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()说明:
geom_hline(yintercept = 80)添加水平参考线;geom_vline(xintercept = 80)添加竖直参考线;linetype = "dashed"表示虚线。
4.7 参考线 + 文字标注
如果只添加参考线,有时读者不一定知道参考线代表什么。
这时可以使用 annotate() 给参考线添加说明文字。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue", alpha = 0.7) +
geom_hline(
yintercept = 80,
linetype = "dashed",
color = "red"
) +
geom_vline(
xintercept = 80,
linetype = "dashed",
color = "red"
) +
annotate(
"text",
x = 95,
y = 82,
label = "数学80分参考线",
color = "red",
size = 4,
hjust = 1 #hjust = 0 → 左对齐,hjust = 0.5 → 居中(默认),hjust = 1 → 右对齐
) +
annotate(
"text",
x = 82,
y = 60,
label = "语文80分参考线",
color = "red",
size = 4,
angle = 90, # 文字旋转90度 → 竖起来了
hjust = 0 #hjust = 0 → 左对齐,hjust = 0.5 → 居中(默认),hjust = 1 → 右对齐
) +
labs(
title = "语文和数学成绩散点图:参考线与文字说明",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()解释:
annotate("text", ...)可以在图中添加固定文字;x和y控制文字位置;label控制文字内容;angle = 90可以让文字旋转 90 度;hjust控制文字的水平对齐方式。
4.8 修改坐标轴标尺
坐标轴标尺包括坐标轴范围、刻度间隔和坐标轴名称。
例如,把语文和数学成绩的坐标轴范围都设置为 50 到 110,并每隔 10 分显示一个刻度。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(aes(color = class), alpha = 0.7, size = 2) +
scale_x_continuous(
name = "语文成绩",
limits = c(50, 110),
breaks = seq(50, 110, 10)
) +
scale_y_continuous(
name = "数学成绩",
limits = c(50, 110),
breaks = seq(50, 110, 10)
) +
labs(
title = "修改坐标轴范围和刻度",
color = "班级"
) +
theme_minimal()说明:
limits = c(50, 110)设置坐标轴范围;breaks = seq(50, 110, 10)设置刻度;name = "语文成绩"设置坐标轴名称。
注意:使用 scale_x_continuous(limits = ...) 或 scale_y_continuous(limits = ...) 时,超出范围的数据会被删除。
如果只是想改变显示范围,而不删除数据,可以使用 coord_cartesian()。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(aes(color = class), alpha = 0.7, size = 2) +
coord_cartesian(
xlim = c(50, 110),
ylim = c(50, 110)
) +
labs(
title = "使用 coord_cartesian() 修改显示范围",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()两种方法的区别如下:
| 方法 | 特点 |
|---|---|
scale_x_continuous(limits = ...) |
超出范围的数据会被删除 |
coord_cartesian(xlim = ...) |
只是缩放显示区域,不删除数据 |
一般情况下,如果只是想放大或缩小图形显示区域,更推荐使用 coord_cartesian()。
4.9 修改图形主题
ggplot2 提供了多种主题,可以快速改变图形风格。
先保存一个基础图形对象:
p_theme <- ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "不同主题效果比较",
x = "语文成绩",
y = "数学成绩",
color = "班级"
)使用简洁主题:
p_theme + theme_minimal()使用经典主题:
p_theme + theme_classic()使用黑白主题:
p_theme + theme_bw()使用浅色主题:
p_theme + theme_light()常见主题如下:
| 主题 | 特点 |
|---|---|
theme_minimal() |
简洁 |
theme_classic() |
经典坐标轴 |
theme_bw() |
黑白主题 |
theme_light() |
浅色网格 |
theme_void() |
去掉坐标轴和背景 |
也可以在主题中进一步修改文字大小、标题样式和图例位置。
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "精细修改图形主题",
subtitle = "颜色表示班级",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(size = 18, face = "bold"),
plot.subtitle = element_text(size = 13),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12),
legend.position = "bottom"
)4.10 使用刻面展示分组图形
刻面可以把数据按照某个分类变量拆分成多个小图,方便比较不同组之间的差异。
例如,按照班级分别展示语文成绩和数学成绩的关系。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue", alpha = 0.7, size = 2) +
facet_wrap(~ class) +
scale_x_continuous(
limits = c(50, 110),
breaks = seq(50, 110, 20)
) +
scale_y_continuous(
limits = c(50, 110),
breaks = seq(50, 110, 20)
) +
labs(
title = "不同班级中语文成绩与数学成绩的关系",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()说明:
facet_wrap(~ class)表示按照 class 变量进行分面。
如果想按照实验组和对照组分面,也可以写:
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(alpha = 0.7, size = 2) +
facet_wrap(~ group) +
labs(
title = "按照实验组和对照组分面的散点图",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()如果想同时按照两个分类变量分面,可以使用 facet_grid()。
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue", alpha = 0.7, size = 2) +
facet_grid(gender ~ class) +
labs(
title = "按照性别和班级分面的散点图",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()解释:
facet_grid(gender ~ class)表示:
- 行方向按照
gender分组; - 列方向按照
class分组。
4.11 本节小结
本节常用代码如下:
# 添加普通文字
geom_text(aes(label = 变量名))
# 添加带边框标签
geom_label(aes(label = 变量名))
# 添加固定说明文字
annotate("text", x = 位置, y = 位置, label = "说明文字")
# 添加水平参考线
geom_hline(yintercept = 数值)
# 添加竖直参考线
geom_vline(xintercept = 数值)
# 修改坐标轴标尺
scale_x_continuous(limits = c(最小值, 最大值), breaks = seq(...))
scale_y_continuous(limits = c(最小值, 最大值), breaks = seq(...))
# 修改显示范围但不删除数据
coord_cartesian(xlim = c(最小值, 最大值), ylim = c(最小值, 最大值))
# 修改主题
theme_minimal()
theme_classic()
theme_bw()
theme_light()
# 按一个变量分面
facet_wrap(~ 分组变量)
# 按两个变量分面
facet_grid(行变量 ~ 列变量)一句话总结:
标注让图形更容易解释,标尺和主题让图形更美观,刻面让分组比较更清楚。
5. 气泡图
5.1 什么是气泡图?
气泡图本质上是散点图。
区别是:
散点图用 x 和 y 表示两个变量;
气泡图额外用点的大小表示第三个变量。
例如:
- 横轴:语文成绩;
- 纵轴:数学成绩;
- 气泡大小:英语成绩;
- 颜色:班级。
5.2 基础气泡图
ggplot(student, aes(x = chinese, y = math, size = english)) +
geom_point(alpha = 0.6) +
labs(
title = "气泡图:语文、数学和英语成绩",
x = "语文成绩",
y = "数学成绩",
size = "英语成绩"
) +
theme_minimal()5.3 分组气泡图
ggplot(student, aes(x = chinese, y = math, size = english, color = class)) +
geom_point(alpha = 0.6) +
labs(
title = "气泡图:颜色表示班级,大小表示英语成绩",
x = "语文成绩",
y = "数学成绩",
size = "英语成绩",
color = "班级"
) +
theme_minimal()5.4 调整气泡大小范围
ggplot(student, aes(x = chinese, y = math, size = english, color = class)) +
geom_point(alpha = 0.6) +
scale_size_continuous(range = c(2, 10)) +
labs(
title = "调整气泡大小范围",
x = "语文成绩",
y = "数学成绩",
size = "英语成绩",
color = "班级"
) +
theme_minimal()解释:
scale_size_continuous(range = c(2, 10))表示最小气泡大小为 2,最大气泡大小为 10。
5.5 气泡图 + 趋势线
ggplot(student, aes(x = chinese, y = math)) +
geom_point(
aes(size = english, color = class),
alpha = 0.5
) +
geom_smooth(
aes(group = 1),
method = "lm",
se = TRUE,
color = "black",
linewidth = 1
) +
scale_size_continuous(range = c(2, 10)) +
labs(
title = "气泡图 + 总体线性趋势线",
x = "语文成绩",
y = "数学成绩",
size = "英语成绩",
color = "班级"
) +
theme_minimal()`geom_smooth()` using formula = 'y ~ x'
解释:
method = "lm"表示添加线性回归趋势线;aes(group = 1)表示画一条总体趋势线,而不是每个班级一条。
6. 分组散点图
6.1 什么是分组散点图?
分组散点图是在散点图中用颜色、形状或分面表示不同组。
例如:
- 用颜色表示班级;
- 用形状表示性别;
- 用分面分别展示实验组和对照组。
6.2 用颜色分组
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "分组散点图:颜色表示班级",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()6.3 用形状分组
ggplot(student, aes(x = chinese, y = math, shape = gender)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "分组散点图:形状表示性别",
x = "语文成绩",
y = "数学成绩",
shape = "性别"
) +
theme_minimal()6.4 颜色 + 形状同时分组
ggplot(student, aes(x = chinese, y = math, color = class, shape = gender)) +
geom_point(size = 2.5, alpha = 0.8) +
labs(
title = "分组散点图:颜色表示班级,形状表示性别",
x = "语文成绩",
y = "数学成绩",
color = "班级",
shape = "性别"
) +
theme_minimal()6.5 分组散点图 + 趋势线
每个班级一条趋势线:
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "不同班级语文与数学关系趋势线",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()`geom_smooth()` using formula = 'y ~ x'
只画一条总体趋势线:
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(
aes(group = 1),
method = "lm",
se = FALSE,
color = "black"
) +
labs(
title = "分组散点图 + 总体趋势线",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()`geom_smooth()` using formula = 'y ~ x'
6.6 分面散点图
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
facet_wrap(~ group) +
labs(
title = "按照实验组/对照组分面的散点图",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()7. 散点图矩阵
7.1 什么是散点图矩阵?
散点图矩阵用于同时查看多个连续变量之间的关系。
例如同时查看:
- 语文;
- 数学;
- 英语;
- 身高;
- 体重;
- 平均分。
散点图矩阵适合初步探索多个数值变量之间的相关关系。
7.2 使用 GGally::ggpairs()
选择数值变量:
score_vars <- student %>%
select(chinese, math, english, height, weight, average)
head(score_vars,5) chinese math english height weight average
1 82.9 72.1 82.6 168.2 72.7 79.2
2 74.4 75.0 88.6 170.5 61.7 79.3
3 78.1 95.0 85.9 178.6 61.7 86.3
4 80.0 68.6 91.2 169.0 46.8 79.9
5 96.8 78.2 89.7 173.7 69.9 88.2
画散点图矩阵:
GGally::ggpairs(score_vars)7.3 分组散点图矩阵
如果想按班级上色,可以把班级变量也放进去。
score_vars_group <- student %>%
select(class, chinese, math, english, height, weight, average)
GGally::ggpairs(
score_vars_group,
aes(color = class, alpha = 0.6)
)`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.
7.4 只选择部分变量画矩阵
变量太多时图会很拥挤,建议只选 3 到 5 个变量。
GGally::ggpairs(
student,
columns = c("chinese", "math", "english", "average"),
aes(color = class, alpha = 0.6)
)8. 相关图
8.1 什么是相关图?
相关图用于展示多个连续变量之间的相关系数。
相关系数一般在 -1 到 1 之间:
| 相关系数 | 含义 |
|---|---|
| 接近 1 | 强正相关 |
| 接近 -1 | 强负相关 |
| 接近 0 | 几乎无线性相关 |
8.2 计算相关矩阵
先选择连续变量:
num_data <- student %>%
select(chinese, math, english, height, weight, total, average)
head(num_data,5) chinese math english height weight total average
1 82.9 72.1 82.6 168.2 72.7 237.6 79.2
2 74.4 75.0 88.6 170.5 61.7 238.0 79.3
3 78.1 95.0 85.9 178.6 61.7 259.0 86.3
4 80.0 68.6 91.2 169.0 46.8 239.8 79.9
5 96.8 78.2 89.7 173.7 69.9 264.7 88.2
计算相关矩阵:
cor_matrix <- cor(num_data)
cor_matrix chinese math english height weight total
chinese 1.00000000 -0.14768260 -0.07193383 -0.05882792 -0.07526751 0.43858303
math -0.14768260 1.00000000 -0.06183304 0.02451594 -0.05947660 0.65813324
english -0.07193383 -0.06183304 1.00000000 -0.14474227 0.12703379 0.43501978
height -0.05882792 0.02451594 -0.14474227 1.00000000 0.10953662 -0.09179652
weight -0.07526751 -0.05947660 0.12703379 0.10953662 1.00000000 -0.02399884
total 0.43858303 0.65813324 0.43501978 -0.09179652 -0.02399884 1.00000000
average 0.43862909 0.65812300 0.43494255 -0.09298285 -0.02430803 0.99997867
average
chinese 0.43862909
math 0.65812300
english 0.43494255
height -0.09298285
weight -0.02430803
total 0.99997867
average 1.00000000
8.3 处理缺失值时计算相关
如果数据有 NA,建议写:
cor_matrix <- cor(num_data, use = "complete.obs")或者:
cor_matrix <- cor(num_data, use = "pairwise.complete.obs")含义:
| 参数 | 含义 |
|---|---|
"complete.obs" |
只使用完整行 |
"pairwise.complete.obs" |
每一对变量分别使用非缺失值 |
8.4 使用 corrplot 画相关图
corrplot::corrplot(cor_matrix)8.5 美化相关图
corrplot::corrplot(
cor_matrix,
method = "color",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.srt = 45,
number.cex = 0.8
)解释:
| 参数 | 含义 |
|---|---|
method = "color" |
用颜色表示相关大小 |
type = "upper" |
只显示上三角 |
addCoef.col = "black" |
添加相关系数数字 |
tl.col = "black" |
变量名颜色 |
tl.srt = 45 |
变量名旋转 45 度 |
number.cex = 0.8 |
数字大小 |
8.6 圆形相关图
corrplot::corrplot(
cor_matrix,
method = "circle",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.srt = 45
)9. 马赛克图
9.1 什么是马赛克图?
马赛克图用于展示两个或多个分类变量之间的关系。
例如:
班级和性别是否有关?
它适合分类变量。
比如:
- 班级 vs 性别;
- 地区 vs 渠道;
- 是否购买 vs 性别;
- 是否及格 vs 班级。
9.2 创建分类变量:是否优秀
先创建一个是否优秀变量:
student <- student %>%
mutate(
excellent = ifelse(average >= 85, "优秀", "非优秀")
)
table(student$class, student$excellent)
非优秀 优秀
一班 29 11
二班 29 11
三班 29 11
9.3 基础马赛克图
基础 R 自带 mosaicplot()。
tab_class_excellent <- table(student$class, student$excellent)
mosaicplot(
tab_class_excellent,
main = "班级与是否优秀的马赛克图",
xlab = "班级",
ylab = "是否优秀",
color = TRUE
)解释:
- 每个矩形的面积表示人数比例;
- 如果某一块面积大,说明该组合人数多;
- 这里的颜色主要用于区分类别组合。
9.4 三个分类变量的马赛克图
例如同时查看:
- 班级;
- 性别;
- 是否优秀。
tab3 <- table(student$class, student$gender, student$excellent)
mosaicplot(
tab3,
main = "班级、性别与是否优秀的马赛克图",
color = TRUE
)解释:
- 该图展示班级、性别和是否优秀三个分类变量的联合分布;
- 每个矩形区域对应一个类别组合;
- 矩形面积越大,表示该组合中的学生人数越多。
9.5 使用 vcd 包画马赛克图,代码展示,不自动执行
vcd 包中的 mosaic() 函数可以绘制功能更丰富的马赛克图。
例如:
- 可以设置
shade = TRUE根据残差着色; - 可以设置
legend = TRUE显示残差图例; - 可以用于分析分类变量组合是否明显偏离独立性假设。
但是在某些中文标签或多维列联表场景下,vcd::mosaic() 在 Knit 时可能出现如下报错:
missing value where TRUE/FALSE needed
为了保证本文顺利 Knit,这里只展示 vcd::mosaic() 代码,不自动执行。
library(vcd)Loading required package: grid
tab3_vcd <- xtabs(~ class + gender + excellent, data = student)
vcd::mosaic(
tab3_vcd,
shade = TRUE,
legend = TRUE,
direction = c("v", "h", "v"),
main = "班级、性别与是否优秀的马赛克图"
)解释:
| 参数 | 含义 |
|---|---|
shade = TRUE |
根据残差着色 |
legend = TRUE |
显示残差图例 |
direction |
指定切分方向 |
main |
图形标题 |
注意:
mosaicplot(color = TRUE)的颜色主要是区分类别区域;vcd::mosaic(shade = TRUE)的颜色表示残差方向和大小;- 两者统计含义不完全一样。
10. 图形修改与美化
下面集中讲一些常见修改方法。
10.1 修改标题和坐标轴名称
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue") +
labs(
title = "语文成绩与数学成绩的关系",
subtitle = "示例数据:120名学生",
caption = "数据来源:模拟数据",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()10.2 修改颜色
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
scale_color_manual(
values = c(
"一班" = "#E64B35",
"二班" = "#4DBBD5",
"三班" = "#00A087"
)
) +
labs(
title = "手动修改颜色",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()10.3 修改填充色
柱形图、盒形图、小提琴图通常用 fill。
ggplot(student, aes(x = class, y = average, fill = class)) +
geom_boxplot(alpha = 0.7) +
scale_fill_manual(
values = c(
"一班" = "#F8766D",
"二班" = "#7CAE00",
"三班" = "#00BFC4"
)
) +
labs(
title = "手动修改填充颜色",
x = "班级",
y = "平均分"
) +
theme_minimal()10.4 修改点的形状和大小
ggplot(student, aes(x = chinese, y = math, color = class, shape = gender)) +
geom_point(size = 3, alpha = 0.8) +
labs(
title = "修改点的形状和大小",
x = "语文成绩",
y = "数学成绩",
color = "班级",
shape = "性别"
) +
theme_minimal()10.5 修改坐标轴范围
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue") +
scale_x_continuous(limits = c(50, 110)) +
scale_y_continuous(limits = c(50, 110)) +
labs(
title = "修改坐标轴范围",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()也可以用:
ggplot(student, aes(x = chinese, y = math)) +
geom_point(color = "steelblue") +
coord_cartesian(
xlim = c(50, 110),
ylim = c(50, 110)
) +
labs(
title = "使用 coord_cartesian() 修改显示范围",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal()区别:
| 方法 | 特点 |
|---|---|
scale_x_continuous(limits = ...) |
超出范围的数据会被删除 |
coord_cartesian(xlim = ...) |
只是缩放显示区域,不删除数据 |
一般推荐用:
coord_cartesian()10.6 修改主题
p <- ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "不同主题效果",
x = "语文成绩",
y = "数学成绩",
color = "班级"
)
p + theme_minimal()p + theme_classic()p + theme_bw()p + theme_light()常见主题:
| 主题 | 特点 |
|---|---|
theme_minimal() |
简洁 |
theme_classic() |
经典坐标轴 |
theme_bw() |
黑白主题 |
theme_light() |
浅色网格 |
theme_void() |
去掉坐标轴和背景 |
10.7 修改图例位置
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
labs(
title = "图例放到底部",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal() +
theme(
legend.position = "bottom"
)去掉图例:
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
labs(
title = "去掉图例",
x = "语文成绩",
y = "数学成绩"
) +
theme_minimal() +
theme(
legend.position = "none"
)10.8 修改文字大小
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
labs(
title = "修改文字大小",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal(base_size = 16)更精细地修改:
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
labs(
title = "精细修改文字大小",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal() +
theme(
plot.title = element_text(size = 18, face = "bold"),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12),
legend.title = element_text(size = 13),
legend.text = element_text(size = 11)
)10.9 旋转横轴文字
ggplot(student, aes(x = class, y = average, fill = class)) +
geom_boxplot() +
labs(
title = "旋转横轴文字",
x = "班级",
y = "平均分"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1)
)解释:
| 参数 | 含义 |
|---|---|
angle = 45 |
旋转 45 度 |
hjust = 1 |
右对齐 |
10.10 修改图形背景和网格线
ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2) +
labs(
title = "修改背景和网格线",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal() +
theme(
panel.grid.major = element_line(color = "grey80"),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "white", color = NA),
plot.background = element_rect(fill = "white", color = NA)
)11. 保存图片
推荐先把图保存成对象。
p_scatter <- ggplot(student, aes(x = chinese, y = math, color = class)) +
geom_point(size = 2, alpha = 0.7) +
labs(
title = "语文成绩与数学成绩的关系",
x = "语文成绩",
y = "数学成绩",
color = "班级"
) +
theme_minimal()
p_scatter保存图片:
ggsave(
filename = "scatter_plot.png",
plot = p_scatter,
width = 6,
height = 4,
dpi = 300
)保存为 PDF:
ggsave(
filename = "scatter_plot.pdf",
plot = p_scatter,
width = 6,
height = 4
)12. 常见错误
12.1 报错:could not find function “ggplot”
原因:没有加载 ggplot2。
解决:
library(ggplot2)12.2 报错:could not find function “ggpairs”
原因:没有安装或没有加载 GGally。
解决:
install.packages("GGally")
library(GGally)或者使用:
GGally::ggpairs(data)12.3 报错:could not find function “corrplot”
原因:没有安装或没有加载 corrplot。
解决:
install.packages("corrplot")
library(corrplot)或者使用:
corrplot::corrplot(cor_matrix)12.4 报错:object ‘x’ not found
原因:代码里用了不存在的变量名。
例如:
ggplot(student, aes(x = x, y = y)) +
geom_point()但 student 里面没有 x 和 y 这两个变量。
解决:
names(student)先查看真实变量名,然后改成真实变量:
ggplot(student, aes(x = chinese, y = math)) +
geom_point()12.5 报错:Discrete value supplied to continuous scale
意思是:
你把分类变量传给了连续型坐标轴或连续型颜色刻度。
例如:
ggplot(student, aes(x = class, y = average)) +
geom_point() +
scale_x_continuous()class 是分类变量,不能用 scale_x_continuous()。
应该用:
scale_x_discrete()或者直接不写。
12.6 vcd::mosaic() 报错:missing value where TRUE/FALSE needed
原因通常是 vcd::mosaic() 在处理多维列联表、中文标签或切分方向时出现兼容性问题。
可能报错:
Error in if (split_vertical[i]) ...:
missing value where TRUE/FALSE needed
解决方法:
- 使用基础 R 的
mosaicplot(); - 或者在
vcd::mosaic()中明确设置direction; - 如果是在 R Markdown 中 Knit,建议先把
vcd::mosaic()设置为eval=FALSE; - 等确认控制台能正常运行后,再考虑打开执行。
示例:
vcd::mosaic(
tab,
shade = TRUE,
legend = TRUE,
direction = c("v", "h")
)13. 小练习
创建一份销售数据:
set.seed(456)
sales <- data.frame(
id = 1:150,
region = sample(c("华东", "华北", "华南"), 150, replace = TRUE),
channel = sample(c("线上", "线下"), 150, replace = TRUE),
category = sample(c("食品", "服装", "电子"), 150, replace = TRUE),
price = round(rnorm(150, mean = 100, sd = 20), 1),
quantity = sample(1:10, 150, replace = TRUE)
)
sales$amount <- round(sales$price * sales$quantity, 1)
sales id region channel category price quantity amount
1 1 华东 线上 电子 108.1 4 432.4
2 2 华东 线下 服装 134.8 8 1078.4
3 3 华南 线上 服装 101.2 3 303.6
4 4 华北 线下 电子 112.1 7 784.7
5 5 华东 线下 服装 96.8 6 580.8
6 6 华南 线上 服装 88.7 7 620.9
7 7 华东 线上 食品 86.0 9 774.0
8 8 华北 线上 食品 92.7 1 92.7
9 9 华南 线上 电子 96.2 9 865.8
10 10 华北 线上 服装 73.5 7 514.5
11 11 华东 线上 电子 109.3 2 218.6
12 12 华南 线上 食品 133.7 7 935.9
13 13 华北 线下 服装 116.0 7 812.0
14 14 华南 线下 电子 118.1 2 236.2
15 15 华南 线上 食品 120.2 2 240.4
16 16 华南 线下 食品 120.1 4 480.4
17 17 华北 线上 服装 123.6 3 370.8
18 18 华北 线上 电子 105.9 7 741.3
19 19 华东 线下 服装 117.3 3 351.9
20 20 华东 线上 服装 74.8 1 74.8
21 21 华北 线上 电子 77.7 3 233.1
22 22 华南 线上 电子 133.5 2 267.0
23 23 华东 线上 电子 80.7 8 645.6
24 24 华东 线上 电子 127.6 2 255.2
25 25 华北 线下 食品 138.1 3 414.3
26 26 华东 线下 服装 118.7 3 356.1
27 27 华东 线下 食品 96.1 8 768.8
28 28 华北 线下 电子 119.9 3 359.7
29 29 华北 线下 服装 134.8 4 539.2
30 30 华南 线下 服装 128.4 9 1155.6
31 31 华北 线上 食品 90.2 3 270.6
32 32 华南 线下 食品 120.0 9 1080.0
33 33 华东 线下 电子 94.3 7 660.1
34 34 华北 线上 电子 98.2 6 589.2
35 35 华东 线上 电子 133.5 4 534.0
36 36 华南 线下 食品 123.1 2 246.2
37 37 华北 线下 服装 116.7 6 700.2
38 38 华南 线上 电子 128.6 4 514.4
39 39 华北 线下 服装 107.9 10 1079.0
40 40 华北 线下 电子 84.2 8 673.6
41 41 华南 线下 电子 116.6 4 466.4
42 42 华北 线上 电子 94.0 5 470.0
43 43 华南 线上 服装 101.1 7 707.7
44 44 华南 线上 服装 115.0 3 345.0
45 45 华东 线下 服装 84.2 2 168.4
46 46 华东 线上 电子 130.1 5 650.5
47 47 华东 线上 电子 89.4 6 536.4
48 48 华北 线上 服装 104.9 6 629.4
49 49 华北 线上 电子 103.7 1 103.7
50 50 华南 线下 食品 125.9 3 377.7
51 51 华南 线上 服装 127.0 1 127.0
52 52 华北 线下 食品 63.6 2 127.2
53 53 华北 线上 食品 79.7 7 557.9
54 54 华东 线上 电子 115.5 3 346.5
55 55 华南 线上 食品 95.1 8 760.8
56 56 华南 线下 服装 84.7 5 423.5
57 57 华北 线上 食品 123.7 2 247.4
58 58 华南 线下 服装 111.4 8 891.2
59 59 华南 线下 服装 105.0 7 735.0
60 60 华东 线上 食品 73.3 5 366.5
61 61 华南 线上 服装 77.0 10 770.0
62 62 华东 线上 服装 149.1 7 1043.7
63 63 华北 线上 电子 103.7 9 933.3
64 64 华东 线下 电子 91.2 3 273.6
65 65 华东 线下 服装 98.8 3 296.4
66 66 华北 线下 食品 146.4 6 878.4
67 67 华南 线下 食品 112.9 10 1129.0
68 68 华南 线下 服装 106.4 4 425.6
69 69 华东 线下 食品 78.8 6 472.8
70 70 华东 线下 服装 62.8 1 62.8
71 71 华北 线下 食品 105.6 8 844.8
72 72 华北 线上 电子 94.6 5 473.0
73 73 华南 线上 食品 112.6 10 1126.0
74 74 华东 线下 电子 59.0 2 118.0
75 75 华北 线上 电子 107.7 9 969.3
76 76 华南 线上 食品 118.8 7 831.6
77 77 华东 线上 服装 119.2 10 1192.0
78 78 华南 线上 服装 74.1 8 592.8
79 79 华北 线上 服装 104.0 4 416.0
80 80 华东 线下 服装 127.9 10 1279.0
81 81 华北 线下 食品 91.1 8 728.8
82 82 华北 线上 食品 93.1 4 372.4
83 83 华南 线上 食品 73.2 10 732.0
84 84 华东 线上 食品 106.5 2 213.0
85 85 华北 线上 电子 106.9 7 748.3
86 86 华南 线上 电子 121.8 7 852.6
87 87 华南 线下 食品 78.3 4 313.2
88 88 华北 线下 食品 123.0 2 246.0
89 89 华东 线下 服装 75.4 10 754.0
90 90 华东 线上 电子 126.9 1 126.9
91 91 华东 线下 服装 80.6 6 483.6
92 92 华东 线下 服装 138.1 10 1381.0
93 93 华东 线下 电子 106.7 5 533.5
94 94 华东 线上 食品 72.2 5 361.0
95 95 华东 线上 服装 91.4 3 274.2
96 96 华南 线上 电子 99.1 10 991.0
97 97 华北 线下 食品 94.3 4 377.2
98 98 华南 线上 服装 99.0 9 891.0
99 99 华北 线上 服装 78.2 2 156.4
100 100 华南 线上 食品 88.6 8 708.8
101 101 华南 线下 电子 122.1 8 976.8
102 102 华东 线上 食品 125.1 4 500.4
103 103 华东 线上 服装 70.2 9 631.8
104 104 华南 线上 服装 126.9 5 634.5
105 105 华东 线上 食品 101.5 5 507.5
106 106 华南 线下 电子 67.8 3 203.4
107 107 华东 线上 服装 109.8 7 768.6
108 108 华东 线下 服装 103.0 3 309.0
109 109 华东 线下 电子 110.4 6 662.4
110 110 华东 线下 食品 90.5 1 90.5
111 111 华北 线上 服装 102.7 9 924.3
112 112 华东 线下 电子 102.8 7 719.6
113 113 华东 线下 食品 113.0 1 113.0
114 114 华北 线下 电子 105.6 5 528.0
115 115 华北 线下 食品 100.0 6 600.0
116 116 华北 线下 服装 82.4 10 824.0
117 117 华东 线上 服装 53.5 2 107.0
118 118 华北 线上 服装 124.0 3 372.0
119 119 华北 线上 食品 90.3 3 270.9
120 120 华南 线上 食品 110.2 9 991.8
121 121 华东 线下 服装 105.1 3 315.3
122 122 华东 线上 食品 74.1 8 592.8
123 123 华东 线下 食品 110.0 3 330.0
124 124 华北 线下 食品 121.0 6 726.0
125 125 华南 线下 服装 95.1 3 285.3
126 126 华东 线下 电子 71.2 10 712.0
127 127 华东 线上 电子 81.9 4 327.6
128 128 华东 线下 食品 117.2 5 586.0
129 129 华东 线下 食品 83.6 3 250.8
130 130 华东 线下 服装 70.6 10 706.0
131 131 华北 线上 电子 103.6 9 932.4
132 132 华东 线下 食品 102.9 7 720.3
133 133 华南 线下 服装 78.9 2 157.8
134 134 华北 线上 电子 75.5 5 377.5
135 135 华东 线上 电子 87.2 7 610.4
136 136 华南 线下 电子 104.5 5 522.5
137 137 华北 线下 食品 106.3 4 425.2
138 138 华东 线下 电子 94.1 9 846.9
139 139 华北 线上 服装 66.7 5 333.5
140 140 华南 线上 食品 136.2 3 408.6
141 141 华东 线上 电子 119.1 4 476.4
142 142 华东 线上 电子 82.1 7 574.7
143 143 华南 线下 食品 75.7 9 681.3
144 144 华东 线上 电子 110.1 9 990.9
145 145 华北 线下 电子 117.8 5 589.0
146 146 华南 线上 电子 90.9 4 363.6
147 147 华东 线下 电子 105.8 2 211.6
148 148 华北 线上 食品 94.8 3 284.4
149 149 华东 线下 服装 109.5 7 766.5
150 150 华北 线下 电子 95.7 4 382.8
请完成:
- 画价格和销售额的散点图,并标注销售额最高的 5 个订单;
- 画气泡图:横轴价格,纵轴销售额,气泡大小为数量,颜色为地区;
- 画价格、数量、销售额的散点图矩阵;
- 画分组散点图:颜色为地区,形状为渠道;
- 计算价格、数量、销售额的相关矩阵并画相关图;
- 画地区和渠道的马赛克图;
- 修改图形标题、颜色、主题和图例位置。
14. 小练习参考答案
14.1 标注销售额最高的 5 个订单
top5_sales <- sales %>%
arrange(desc(amount)) %>%
slice(1:5)
top5_sales id region channel category price quantity amount
1 92 华东 线下 服装 138.1 10 1381.0
2 80 华东 线下 服装 127.9 10 1279.0
3 77 华东 线上 服装 119.2 10 1192.0
4 30 华南 线下 服装 128.4 9 1155.6
5 67 华南 线下 食品 112.9 10 1129.0
ggplot(sales, aes(x = price, y = amount)) +
geom_point(color = "grey50", alpha = 0.7) +
geom_point(
data = top5_sales,
color = "red",
size = 3
) +
geom_label(
data = top5_sales,
aes(label = paste0("ID=", id)),
fill = "yellow",
color = "red",
size = 3
) +
labs(
title = "价格与销售额散点图:标注最高销售额订单",
x = "价格",
y = "销售额"
) +
theme_minimal()14.2 气泡图
ggplot(sales, aes(x = price, y = amount, size = quantity, color = region)) +
geom_point(alpha = 0.6) +
scale_size_continuous(range = c(2, 10)) +
labs(
title = "气泡图:价格、销售额与购买数量",
x = "价格",
y = "销售额",
size = "数量",
color = "地区"
) +
theme_minimal()14.3 散点图矩阵
if (requireNamespace("GGally", quietly = TRUE)) {
GGally::ggpairs(
sales,
columns = c("price", "quantity", "amount")
)
} else {
message("未安装 GGally,因此不绘制销售数据散点图矩阵。")
}分组散点图矩阵:
if (requireNamespace("GGally", quietly = TRUE)) {
GGally::ggpairs(
sales,
columns = c("price", "quantity", "amount"),
aes(color = region, alpha = 0.6)
)
} else {
message("未安装 GGally,因此不绘制销售数据分组散点图矩阵。")
}14.4 分组散点图
ggplot(sales, aes(x = price, y = amount, color = region, shape = channel)) +
geom_point(size = 2.5, alpha = 0.8) +
labs(
title = "价格与销售额分组散点图",
x = "价格",
y = "销售额",
color = "地区",
shape = "渠道"
) +
theme_minimal()14.5 相关图
sales_num <- sales %>%
select(price, quantity, amount)
sales_cor <- cor(sales_num)
sales_cor price quantity amount
price 1.00000000 -0.06722087 0.2881969
quantity -0.06722087 1.00000000 0.9157241
amount 0.28819690 0.91572410 1.0000000
if (requireNamespace("corrplot", quietly = TRUE)) {
corrplot::corrplot(
sales_cor,
method = "color",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.srt = 45
)
} else {
message("未安装 corrplot,因此不绘制销售数据相关图。")
}14.6 马赛克图
基础 R 写法:
tab_region_channel <- table(sales$region, sales$channel)
mosaicplot(
tab_region_channel,
main = "地区与渠道的马赛克图",
xlab = "地区",
ylab = "渠道",
color = TRUE
)解释:
- 该图展示地区和渠道两个分类变量的联合分布;
- 矩形面积越大,表示该地区与该渠道组合下的订单数越多。
14.7 使用 vcd 绘制马赛克图,代码展示,不自动执行
如果想使用 vcd::mosaic(),可以参考下面代码。
为避免 Knit 报错,这里设置为 eval=FALSE。
library(vcd)
vcd::mosaic(
tab_region_channel,
shade = TRUE,
legend = TRUE,
direction = c("v", "h"),
main = "地区与渠道的马赛克图"
)说明:
shade = TRUE表示根据残差着色;legend = TRUE表示显示残差图例;direction = c("v", "h")指定二维表的切分方向;- 如果控制台运行正常,可以再考虑让 R Markdown 执行该代码。
14.8 图形修改示例
ggplot(sales, aes(x = price, y = amount, color = region, shape = channel)) +
geom_point(size = 3, alpha = 0.75) +
scale_color_manual(
values = c(
"华东" = "#E64B35",
"华北" = "#4DBBD5",
"华南" = "#00A087"
)
) +
labs(
title = "价格与销售额关系",
subtitle = "颜色表示地区,形状表示渠道",
caption = "数据来源:模拟销售数据",
x = "商品价格",
y = "销售额",
color = "地区",
shape = "渠道"
) +
theme_classic(base_size = 14) +
theme(
legend.position = "bottom",
plot.title = element_text(face = "bold", size = 18),
plot.subtitle = element_text(size = 13),
axis.title = element_text(size = 14)
)15. 本节核心代码总结
下面是模板代码,只展示,不运行。
# 加载包
library(ggplot2)
library(dplyr)
# 1. 散点图 + 标注
ggplot(df, aes(x = x_var, y = y_var)) +
geom_point() +
geom_text(aes(label = label_var))
# 2. 只标注部分点
label_df <- df %>%
filter(condition)
ggplot(df, aes(x = x_var, y = y_var)) +
geom_point() +
geom_point(data = label_df, color = "red") +
geom_label(data = label_df, aes(label = label_var))
# 3. 添加参考线
ggplot(df, aes(x = x_var, y = y_var)) +
geom_point() +
geom_hline(yintercept = 80, linetype = "dashed") +
geom_vline(xintercept = 80, linetype = "dashed")
# 4. 添加说明文字
ggplot(df, aes(x = x_var, y = y_var)) +
geom_point() +
annotate("text", x = 10, y = 20, label = "说明文字")
# 5. 气泡图
ggplot(df, aes(x = x_var, y = y_var, size = size_var, color = group_var)) +
geom_point(alpha = 0.6) +
scale_size_continuous(range = c(2, 10))
# 6. 分组散点图
ggplot(df, aes(x = x_var, y = y_var, color = group_var, shape = type_var)) +
geom_point()
# 7. 分组散点图 + 趋势线
ggplot(df, aes(x = x_var, y = y_var, color = group_var)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE)
# 8. 分面散点图
ggplot(df, aes(x = x_var, y = y_var, color = group_var)) +
geom_point() +
facet_wrap(~ facet_var)
# 9. 散点图矩阵
GGally::ggpairs(
df,
columns = c("x1", "x2", "x3")
)
# 10. 分组散点图矩阵
GGally::ggpairs(
df,
columns = c("x1", "x2", "x3"),
aes(color = group_var, alpha = 0.6)
)
# 11. 相关矩阵
num_df <- df %>%
select(x1, x2, x3)
cor_matrix <- cor(num_df, use = "complete.obs")
# 12. 相关图
corrplot::corrplot(
cor_matrix,
method = "color",
type = "upper",
addCoef.col = "black"
)
# 13. 基础马赛克图
tab <- table(df$group1, df$group2)
mosaicplot(
tab,
main = "马赛克图",
color = TRUE
)
# 14. vcd 马赛克图
# 注意:在某些中文标签或多维列联表场景下可能需要额外设置。
# 建议先在控制台单独测试,再放入 R Markdown 中执行。
library(vcd)
vcd::mosaic(
tab,
shade = TRUE,
legend = TRUE,
direction = c("v", "h"),
main = "vcd 马赛克图"
)
# 15. 修改标题
ggplot(df, aes(x = x_var, y = y_var)) +
geom_point() +
labs(
title = "标题",
subtitle = "副标题",
caption = "注释",
x = "横轴名称",
y = "纵轴名称"
)
# 16. 修改颜色
ggplot(df, aes(x = x_var, y = y_var, color = group_var)) +
geom_point() +
scale_color_manual(values = c("A" = "red", "B" = "blue"))
# 17. 修改主题和图例
ggplot(df, aes(x = x_var, y = y_var, color = group_var)) +
geom_point() +
theme_minimal() +
theme(
legend.position = "bottom",
plot.title = element_text(size = 18, face = "bold")
)
# 18. 保存图片
ggsave(
filename = "plot.png",
plot = p,
width = 6,
height = 4,
dpi = 300
)16. 一句话总结
本节最常用代码如下:
geom_text()
geom_label()
annotate()用于给图添加文字标注。
ggplot(df, aes(x, y, size = z)) +
geom_point()用于画气泡图。
GGally::ggpairs()用于画散点图矩阵。
corrplot::corrplot()用于画相关图。
mosaicplot()用于绘制基础马赛克图。
vcd::mosaic()也可以绘制更丰富的马赛克图,并支持残差着色;但在某些中文标签或多维表情况下可能需要额外设置。为了保证本文 Knit 稳定,正文中 vcd::mosaic() 只作为代码示例展示,不自动执行。
图形修改最常用的是:
labs()
theme()
scale_color_manual()
scale_fill_manual()
theme_minimal()
theme_classic()