Introduction
折线图读的是沿一个有序轴的变化:时间、年龄、剂量、距离或步骤。横轴必须有真实顺序——如果 x 只是几个没有先后的类别,把点连起来会凭空制造出一个"过程"。
单条线看变化的方向和速度;多条线则看各组是否一起动、哪一组更快、何时开始分离,以及轨迹有没有交叉。
读的时候按这个顺序:
- 先沿横轴追方向。 上升、下降、平台或拐点出现在哪里。
- 再比较斜率。 同一段时间内哪条线变化更快。
- 看间距。 线之间逐渐拉开说明组间差异随时间扩大,逐渐靠拢则相反。
- 找交叉。 两条线交换高低顺序时,单独比较起点或终点都会漏掉信息。
- 确认点的位置。 线段之间没有真实观测;折线只是连接相邻点,不代表中间过程真的线性。
Example Data
折线图要的输入是:时间或有序位置 + 连续数值,多序列时再加 1 个分组变量。x 必须能排序——Date、数值或有序 factor 都行,字符串不行。
orange 是五棵橘树在同样的七个年龄点测得的树干周长,标准的多序列纵向数据。
library(ggplot2)
library(ggpubr)
library(biopalette)
# 公开地址,和数据集页上「下载 CSV」给的是同一个 —— 不写仓库相对路径:
# 那个目录不进仓库,读者 clone 下来也没有这个文件,这段代码就跑不了
d <- read.csv("https://assets.evanzhou.org/tessera/csv/orange.csv")
# Tree 是分组不是数值,转成 factor 才不会被当成连续量做渐变色标
d$Tree <- factor(d$Tree, levels = sort(unique(d$Tree)))
Palettes
五棵树是五个无序类别,完整分组版用五色定性色板 walter_white2。颜色沿整条线保持不变,读者才能从左到右持续追踪同一棵树。
色板少于五色时,不插值、不循环,也不删掉其余轨迹:所有线先用浅灰画成上下文,再把与色板容量相同的重点序列覆盖在上面。浅灰表示"仍在图中,但当前不由色板编码",不是第六个类别。
一条线只用颜色区分就够。颜色、点形、虚实一起变化会让图例和图面同时过载——常规彩色图先只用颜色,黑白输出再考虑加第二个通道。
tree_colors <- setNames(
get_palette("walter_white2", type = "qualitative"),
levels(d$Tree)
)
# 四张图共用同一套坐标范围和版式:轴范围一致,四张图才能横着比
line_scales <- list(
scale_x_continuous(
breaks = c(0, 400, 800, 1200, 1600),
limits = c(0, 1650),
expand = expansion(mult = c(0, 0.01))
),
scale_y_continuous(
breaks = seq(25, 225, 50),
limits = c(20, 225),
expand = expansion(mult = c(0, 0))
)
)
line_theme <- theme_pubr(base_size = 13, legend = "right") +
theme(
panel.grid.major = element_line(color = "#E5E3DC", linewidth = 0.35),
panel.grid.minor = element_blank(),
axis.line = element_line(color = "#333330", linewidth = 0.45),
axis.ticks = element_line(color = "#333330", linewidth = 0.4),
plot.title = element_text(face = "bold", size = 15, hjust = 0),
plot.subtitle = element_text(color = "grey35", hjust = 0),
legend.title = element_text(face = "bold"),
legend.key.height = grid::unit(5, "mm"),
plot.margin = margin(14, 16, 12, 12)
)
Recipe
| No. | Method | Input Data | Palettes |
|---|---|---|---|
| 1 | ggplot2 |
one_tree |
— |
| 2 | ggplot2 |
d |
tree_colors |
| 3 | ggplot2 |
d |
focus_colors |
| 4 | ggplot2 |
d |
tree_colors |
1 · 单条序列
线负责连接相邻年龄,点负责标出七次真实测量。
只画线的话,读者会把整条线当成连续测量。观测点不密时叠一层小圆点,才算诚实地告诉人数据在哪里。
#| fig: single
#| fig-width: 7.4
#| fig-height: 5.1
one_tree <- subset(d, Tree == "4")
ggplot(one_tree, aes(age, circumference)) +
geom_line(linewidth = 1.05, color = "#5A5A56") +
# 点比散点图小,也和线同色 —— 它只负责标位置,太抢会把线切成一串珠子
geom_point(size = 2.4, color = "#5A5A56") +
line_scales +
labs(
title = "One tree, seven observations",
x = "Age (days)",
y = "Trunk circumference (mm)"
) +
line_theme


