ggplot2离散轴设置次刻度及连接geom_point分组点的方法求解
ggplot2 双需求实现方案
无需额外安装第三方扩展包,仅用tidyverse核心功能即可实现:
- 散点连线:将车型转为数值型坐标后统一设置年份偏移量,新增
geom_line层时以「车型+指标」为分组键,即可自动连接每个车型下不同年份的同指标散点 - 双层X轴:将X轴设为连续刻度,上层(靠近绘图区,即车型标签上方)刻度对齐散点位置标注年份;通过文本注释在轴外侧添加车型标签,拉长车型对应中心位置的刻度线做视觉分组,调整边距避免标签裁切。
完整可运行代码
library(tidyverse) # 原示例数据构造逻辑保持不变 data <- mtcars%>% as_tibble(rownames = "model")%>% mutate(jahr = 2019)%>% bind_rows(mtcars%>% as_tibble(rownames = "model")%>% mutate_if(is.numeric, ~.*0.9)%>% mutate(jahr = 2020))%>% bind_rows(mtcars%>% as_tibble(rownames = "model")%>% mutate_if(is.numeric, ~.*0.7)%>% mutate(jahr = 2021)) # 固定车型展示顺序 model_levels <- c("Datsun 710", "Honda Civic", "Valiant") # 预处理绘图数据,生成点位坐标 plot_data <- data%>% filter(model %in% model_levels)%>% gather(variable, wert, -c(model, jahr))%>% mutate( model_num = as.numeric(factor(model, levels = model_levels)), # 年份偏移量和原代码点位完全对齐 x_pos = case_when( jahr == 2019 ~ model_num - 0.2, jahr == 2020 ~ model_num, jahr == 2021 ~ model_num + 0.2 ) ) ggplot(plot_data, aes(x = x_pos, y = wert, col = model))+ # 折线层放在散点下层,避免遮挡点位 geom_line(aes(group = interaction(model, variable)), linewidth = 0.8) + geom_point(size = 2.5) + facet_wrap(~variable, scales = "free_y") + # X轴配置:上层刻度标注年份 scale_x_continuous( breaks = c(0.8, 1, 1.2, 1.8, 2, 2.2, 2.8, 3, 3.2), labels = rep(c("2019", "2020", "2021"), 3), name = NULL, expand = expansion(add = 0.5) ) + # 添加下层车型标签 geom_text( data = distinct(plot_data, model, model_num), aes(x = model_num, y = -Inf, label = model), vjust = 2.2, hjust = 0.5, color = "black", size = 3.5 ) + theme( # 底部预留足够空间放置两层标签 plot.margin = margin(b = 25, t = 10, l = 10, r = 10), # 车型中心位置刻度线拉长,强化分组视觉效果 axis.ticks.length.x = unit(c(2, 8, 2, 2, 8, 2, 2, 8, 2), "pt"), legend.position = "top" )
实现效果
- 同车型、同指标的三个年份散点由同色折线连接,数值变化趋势直观
- X轴为双层结构:紧邻绘图区的标签为年份,位于车型标签的上方,完全符合轴配置需求。
内容的提问来源于stack exchange,提问作者Waschi Waschoi
相关产品推荐
相关产品推荐

