ggplot2 facet_wrap分面时保留背景geom并高亮对应分组的方法
问题核心原因
facet_wrap()默认会对图中所有图层的数据集按分面变量做子集过滤:每个面板仅保留数据集中分面变量和当前面板取值一致的行。
你初始绘图代码里的灰色背景点、灰色路径用的是全量分组数据,但分面时每个面板只会保留当前food对应的单组数据,其余分组的灰色线条会被直接过滤,因此无法显示全量背景线。
修正方案
无需依赖额外扩展包,只需要为背景图层构造专用数据集:让每个分面面板的取值下都包含全部分组的线条坐标,即可让灰色背景线在所有分面中完整显示,同时修正原代码中的笔误(原代码计算极坐标时引用了未生成的y变量,应改为引用sense)。
修正后完整可运行代码
library(tidyverse) # 构造基础数据 food <- rep(c("apple", "pear", "orange"),3) sense <- as.factor(rep(c("taste", "texture", "appearance"),each = 3)) score <- sample(0:10, 9) df <- data.frame(food,sense,score) %>% # 修正原笔误:n_distinct(y)改为n_distinct(sense) mutate(theta = (as.integer(sense)-1)*(360/n_distinct(sense)*pi/180)+pi/2) %>% mutate(x = cos(theta)*score, y = sin(theta)*score)%>% rbind(filter(., sense == "taste")) # 闭合雷达图路径 # 定义需要分面展示的分组 facet_foods <- c("apple", "orange") # 构造背景层专用数据:每个分面组下都包含全部分组的线条数据 bg_data <- df %>% rename(line_group = food) %>% # 重命名字段,避免和分面变量重名 merge(data.frame(food = facet_foods), by = NULL) # 笛卡尔积交叉连接 # 绘图 final_plot <- ggplot(mapping = aes(x = x, y = y))+ # 背景灰色点,用专用背景数据,按原线条分组 geom_point(data = bg_data, aes(group = line_group), colour = "gray", size = 3)+ # 背景灰色虚线,用专用背景数据,按原线条分组 geom_path(data = bg_data, aes(group = line_group), colour = "gray", size = 1, linetype = "longdash")+ # 极坐标轴线 geom_spoke(data = data.frame( x = 0, y = 0, angle =seq(from = 0, to = 2*pi, length.out = 4)+pi/2, radius = 10), aes(x = x, y = y, angle = angle, radius = radius, group = NULL), colour = "darkgray", size = 0.8)+ # 高亮当前分面对应的彩色线条 geom_path(data = filter(df, food %in% facet_foods), aes(color = food), size = 2)+ facet_wrap(~food)+ coord_equal()+ theme_void() # 输出图片 final_plot
效果说明
运行代码后将生成2个分面,每个分面内都包含全部3种水果的灰色虚线背景,同时高亮显示当前分面对应水果的彩色实线,完全匹配需求效果。
内容的提问来源于stack exchange,提问作者Teppishc
相关产品推荐
相关产品推荐

