ggplot2分面图无法正常显示注解的技术求助
ggplot2分面与注解共存的解决方法
问题原因
你当前用annotate()添加的注解是全局图层,不会根据分面自动匹配面板参数。加上代码里用了ggnewscale多组图层,导致分面后的面板刻度参数和注解的数值不兼容,出现匹配错误。
解决方案
放弃annotate(),改用geom_text(),并创建一个包含所有分面名称的注解数据框,让每个分面都加载对应的注解内容,确保注解和分面的参数完全匹配。
关键修改点:
- 生成包含所有
TestName的注解数据框,每个分面对应一组注解文本 - 用
geom_text()替代annotate(),绑定注解数据框并映射分面变量
修改后完整代码
library(ggplot2) library(ggnewscale) library(dplyr) # 构建测试数据 comparison = c(rep(c("a", "b", "c", "d", "e", "f"), each = 3)) mids = c(-2.87535598803134, 0, -0.638967997340297, -0.212989332446766,2.23638799069104, 0.851957329787062, 2.98185065425472, -2.23638799069104, -1.06494666223383, 1.81040932579751, 0.958451996010445, -0.212989332446766, -2.4493773231378, 0.638967997340297, 2.02339865824427, -2.87535598803134, 0.745462663563679, 2.34288265691442) counts.stdzd = c(0.25, 0.67, 0.89, 0.45, 0.00298953662182362, 0, 0.686907020872865, 0.67, 0.89, 0.45, 0.00089126559714795, 0.00445632798573975, 0.181937172774869, 0.909685863874346, 0.0916230366492147, 0.00138985406532314, 0.980542043085476, 0.00138985406532314) TestName = c(rep("Test1",3), rep("Test2",6), rep("Test1",3), rep("Test3",3), rep("Test4",3)) df <- data.frame(comparison,mids,counts.stdzd,TestName) # 定义颜色 palette cols <- c("a" = "#0570b0", "b" = "#8c96c6", "c" ="#74a9cf", "d" = "#8856a7", "e" = "#d7b5d8", "f" = "#b3cde3") # 获取注解用的y轴刻度 p1 <- ggplot(df, aes(x = mids, y = counts.stdzd, color = comparison)) brk <- ggplot_build(p1)$layout$panel_params[[1]]$y$breaks brk <- brk[2:5] # 生成注解数据框:每个分面对应一组注解 anno_df <- expand.grid( TestName = unique(df$TestName), x = rep(-2.89, length(brk)), y = brk, label = as.character(brk) ) # 分面图层函数 Names <- unique(df$TestName) make_layers <- function(x) { plot_frame <- filter(df, TestName == Names[[x]]) list( if (x != 1) new_scale_fill(), if (x != 1) new_scale_color(), geom_bar(data = plot_frame, aes(x = mids, y = counts.stdzd, fill = comparison, color = comparison), stat = "identity", alpha = .7, position = "identity"), scale_x_continuous( limits = c(-pi,pi), breaks = c(-pi, -pi/2, 0, pi/2, pi), labels = c("","-π/2","0","π/2", "π")), scale_y_continuous( limits = c(0,1)), coord_polar(start = pi/2, direction = -1), scale_fill_manual( values = cols, guide = guide_legend( order = x, title = Names[x], title.position = "top"), aesthetics = c("fill","color")) ) } # 绘制完整图形 all.roses <- ggplot() + geom_hline(yintercept = seq(0, 1, by = 0.25), colour = "grey90", linewidth = 0.2) + geom_vline(xintercept = seq(0, pi, by = pi/2), colour = "grey90", linewidth = 0.2) + geom_vline(xintercept = seq(0, -pi, by = -pi/2), colour = "grey90", linewidth = 0.2) + lapply(seq_along(Names), make_layers) + # 替换annotate为geom_text,绑定注解数据框 geom_text(data = anno_df, aes(x = x, y = y, label = label)) + facet_wrap(~TestName) + labs(y = "Counts (standardized by the proportion of maximum count)", x = expression("Angle between ellipse centroids (rads)")) + theme( panel.border = element_blank(), panel.grid = element_blank(), axis.ticks.y = element_blank(), axis.text.y = element_blank()) all.roses
内容的提问来源于stack exchange,提问作者ElizaBeso000
相关产品推荐
相关产品推荐

