如何叠加含离散与连续Y轴的散点图和柱状图?
问题描述
我已创建两个图表:
- 散点图:X轴为时间,Y轴是Tom、Jerry这类离散值
- 柱状图:X轴同样为时间,Y轴是身高这类连续值
尝试将两图叠加到同一画布时,现有实现代码过于繁琐,求更简便的方法。
原图表代码
散点图
data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom")) ggplot(data.scatter, aes(x = x, y = y)) + geom_point()
柱状图
data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50)) ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity")
原尝试代码(繁琐版)
library(tidyverse) data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom")) p1 <- ggplot(data.scatter, aes(x = x, y = y)) + geom_point() p1_data <- ggplot_build(p1)$data[[1]] data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50)) p2 <- ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity") p2_data <- ggplot_build(p2)$data[[1]] p3 <- p2_data %>% ggplot() + geom_rect(aes(ymin=ymin,ymax = ymax,xmin = xmin,xmax = xmax)) + geom_text(aes(x=xmin+.45,y=ymax+1,label=ymax)) + geom_point(data = p1_data, aes(x = x, y = y*20),inherit.aes = F) + scale_y_continuous(breaks = c(20,40),labels = c("Tom","Jerry")) + labs(x=NULL,y=NULL) p3
简便解决方案
无需提取绘图数据重构,直接在同一ggplot对象中叠加图层,把离散Y值映射为连续数值后自定义刻度标签即可:
代码实现
library(ggplot2) # 准备数据 data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y_height = c(10, 20, 30, 40, 50)) data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y_name = c("Tom", "Jerry", "Tom", "Jerry", "Tom")) # 将离散名称映射为连续数值(和你原代码的映射逻辑一致) data.scatter$y_num <- ifelse(data.scatter$y_name == "Tom", 20, 40) # 绘制叠加图 ggplot() + # 添加柱状图层 geom_bar(data = data.bar, aes(x = x, y = y_height), stat = "identity", fill = "steelblue") + # 添加散点图层 geom_point(data = data.scatter, aes(x = x, y = y_num), color = "red", size = 3) + # 自定义Y轴刻度与标签 scale_y_continuous( breaks = c(10, 20, 30, 40, 50), labels = c("10", "Tom", "30", "Jerry", "50") ) + labs(x = "时间", y = "")
关键逻辑
- 直接在同一画布上调用多个
geom_*函数,分别指定对应的数据框,避免复杂的数据提取 - 把离散的人物名称转换为对应的连续数值,匹配柱状图的Y轴范围
- 通过
scale_y_continuous自定义刻度标签,让Y轴同时展示身高数值和人物名称,实现和你需求一致的效果
内容的提问来源于stack exchange,提问作者tenjyo syu
相关产品推荐
相关产品推荐

