第8讲:数据可视化 ~ Part 2
2026年04月22日
plot()、hist()、barplot()、boxplot() 快速探索,无需加载包aes() 映射 + geom_*() = 一张图;图层用 + 叠加geom_bar()(自动计数)/ geom_col()(已有计数);reorder() 排序;position 控制分组方式geom_histogram()(分布)、geom_density()(平滑曲线)、geom_boxplot()(五数概括)geom_jitter() 处理重叠、小提琴图叠加箱线图facet_wrap() 单变量分面、facet_grid() 双变量矩阵分面scale_x/y_continuous()
facet_wrap()
patchwork
scale_color_*() / scale_fill_*()
ggsave()
你什么也看不见,但你已经创建了一个空白画布
告诉它对哪个或哪些数据绘图,该参数始终在aes()函数中定义
还是没有图,但我们已经生成了相应的刻度。
geom_
这里我们绘制最基本最常用的散点图
我们可以按类型给散点上色
geom_smooth: na.rm = FALSE, orientation = NA, se = TRUE
stat_smooth: na.rm = FALSE, orientation = NA, se = TRUE, method = function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, ...)
{
ret.x <- x
ret.y <- y
cl <- match.call()
mf <- match.call(expand.dots = FALSE)
m <- match(c("formula", "data", "subset", "weights", "na.action", "offset"), names(mf), 0)
mf <- mf[c(1, m)]
mf$drop.unused.levels <- TRUE
mf[[1]] <- quote(stats::model.frame)
mf <- eval(mf, parent.frame())
if (method == "model.frame")
return(mf)
else if (method != "qr")
warning(gettextf("method = '%s' is not supported. Using 'qr'", method), domain = NA)
mt <- attr(mf, "terms")
y <- model.response(mf, "numeric")
w <- as.vector(model.weights(mf))
if (!is.null(w) && !is.numeric(w))
stop("'weights' must be a numeric vector")
offset <- model.offset(mf)
mlm <- is.matrix(y)
ny <- if (mlm)
nrow(y)
else length(y)
if (!is.null(offset)) {
if (!mlm)
offset <- as.vector(offset)
if (NROW(offset) != ny)
stop(gettextf("number of offsets is %d, should equal %d (number of observations)", NROW(offset), ny), domain = NA)
}
if (is.empty.model(mt)) {
x <- NULL
z <- list(coefficients = if (mlm) matrix(NA, 0, ncol(y)) else numeric(), residuals = y, fitted.values = 0 * y, weights = w, rank = 0, df.residual = if (!is.null(w)) sum(w != 0) else ny)
if (!is.null(offset)) {
z$fitted.values <- offset
z$residuals <- y - offset
}
}
else {
x <- model.matrix(mt, mf, contrasts)
z <- if (is.null(w))
lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...)
else lm.wfit(x, y, w, offset = offset, singular.ok = singular.ok, ...)
}
class(z) <- c(if (mlm) "mlm", "lm")
z$na.action <- attr(mf, "na.action")
z$offset <- offset
z$contrasts <- attr(x, "contrasts")
z$xlevels <- .getXlevels(mt, mf)
z$call <- cl
z$terms <- mt
if (model)
z$model <- mf
if (ret.x)
z$x <- x
if (ret.y)
z$y <- y
if (!qr)
z$qr <- NULL
z
}
position_identity
penguins |>
ggplot(aes(x = flipper_len,
y = body_mass
)) +
geom_point(aes(
color = species,
shape = species
)) +
geom_smooth(method = lm) +
labs(
title = "Body mass and flipper length",
subtitle = "Dimensions for Adelie, Chinstrap, and Gentoo Penguins",
x = "Flipper length (mm)", y = "Body mass (g)",
color = "Species", shape = "Species"
)penguins |>
ggplot(aes(x = flipper_len,
y = body_mass
)) +
geom_point(aes(
color = species,
shape = species
)) +
geom_smooth(method = lm) +
labs(
title = "Body mass and flipper length",
subtitle = "Dimensions for Adelie, Chinstrap, and Gentoo Penguins",
x = "Flipper length (mm)", y = "Body mass (g)",
color = "Species", shape = "Species"
) +
xlim(170, 230) +
ylim(2000, 7000)scale_color_*() / scale_fill_*() 体系
ggplot2 有两套颜色通道,使用时要选对:
| 通道 | 参数 | 控制的是 |
|---|---|---|
color |
scale_color_*() |
点、线、箱线图边框的颜色 |
fill |
scale_fill_*() |
柱状图、箱线图、小提琴图的填充色 |
patchwork 拼图
分面(facet)是同一张图内按变量分组——所有子图使用相同的几何对象和映射。
当你需要把完全不同类型的图放在一起时(比如左边条形图、右边散点图),就需要多图并列工具。
提示
patchwork 包让多图拼接变得极为简洁——核心操作符就是 +、/、|。
patchwork:安装与基本语法三个核心操作符:
| 操作符 | 含义 |
|---|---|
p1 + p2 |
并排(左右) |
p1 / p2 |
上下堆叠 |
p1 | p2 |
并排(等价于 +,语义更清晰) |
+ 或 |
p1 <- ggplot(mpg, aes(x = hwy)) +
geom_histogram(bins = 20, fill = "#1a3a5c", color = "white") +
labs(title = "高速油耗分布", x = "油耗(mpg)", y = "数量") +
theme_minimal(base_size = 11)
p2 <- ggplot(mpg, aes(x = class, y = hwy, fill = class)) +
geom_boxplot(show.legend = FALSE) +
labs(title = "各车型油耗分布", x = "车型", y = "油耗(mpg)") +
theme_minimal(base_size = 11)
p1 + p2 # 或 p1 | p2/
括号用来控制优先级,实现"上两下一"或"左一右两"等布局:
ggsave() 与分辨率控制
ggsave():保存图形提示
ggsave() 根据文件扩展名自动选择格式:.png、.pdf、.svg、.jpg、.tiff 均支持。
分面进阶:facet_wrap() 的 nrow/ncol 控制布局、scales 参数放开坐标轴、labeller 自定义标签;facet_grid() 适合行列意义明确的矩阵分面
多图并列(patchwork):+ 左右并排、/ 上下堆叠、(p1 + p2) / p3 复杂布局;plot_annotation() 统一标题与自动编号;plot_layout() 控制宽高比例
配色系统:scale_*_manual() 手动指定;scale_*_brewer() 预设调色板(分类用 Set2/Dark2,有序用序列色板);scale_*_viridis_c() 连续变量首选(色盲友好)
坐标轴精调:coord_cartesian() 缩放视图(不删除数据);scales::percent/dollar/comma 格式化标签;scale_x_log10() 对数轴处理跨数量级数据
图形保存:ggsave() 指定 width/height/dpi;学术投稿用 .tiff(300 dpi)或 .pdf(矢量);中文字体用 showtext 包解决
mpg 数据,绘制 cty(城市油耗)的直方图,用 facet_wrap() 按 drv 分面,要求:(a)每组使用独立的 y 轴范围;(b)将 "4"/"f"/"r" 替换为中文标签diamonds 数据,用 patchwork 并列展示:左图为各 cut 的计数条形图,右图为 price 的密度图(按 cut 上色),整体添加标题和 A/B 编号mpg 散点图(displ vs hwy),要求:(a)y 轴添加单位"英里/加仑";(b)用 geom_hline() 标注整体均值;(c)用 annotate() 在图中标注均值数值mtcars 数据,绘制所有车型的散点图(wt vs mpg),用 ggrepel::geom_text_repel() 给每个点标注车名,用 color 映射 cyl(气缸数),并用 scale_color_viridis_d() 配色diamonds 数据,绘制价格(price)对克拉数(carat)的散点图:x/y 轴均用 log10 对数坐标轴,按 cut 分面,并为每个分面添加线性趋势线。思考:对数坐标下线性趋势意味着什么?第9讲:线性回归
第8讲:数据可视化(下)
「好的图形不是画出来的,而是选出来的——从数十种可能的呈现方式中,选出那个最能说明问题的那一种。」
数据挖掘与R语言 | 第8讲:数据可视化 ~ 2