如何在ggplot图例中合并形状与颜色属性?
解决方案
要让图例中每个ID的符号匹配其对应的性别形状,核心是从数据中动态提取每个ID对应的性别形状映射,再在图例中覆盖形状设置,这个方法能自动适配不同数据集(只要每个ID对应唯一性别)。
步骤说明:
- 从目标数据集中提取每个
ID对应的Sex,并映射到指定的形状代码(比如用16代表Female实心圆,17代表Male实心三角) - 在
guides(colour = guide_legend())的override.aes参数中,将每个ID的图例形状设置为对应的形状值,确保和图表中实际的点形状一致
修改后的完整代码:
library(tidyverse) library(ggforce) idL12 <- structure(list(date = structure(c(13371, 13371, 13371, 13371, 13715, 13715, 13715, 14825, 14825, 16323, 16323, 16674, 16674, 16997, 17065, 17065, 17065), class = "Date"), year = c(2006L, 2006L, 2006L, 2006L, 2007L, 2007L, 2007L, 2010L, 2010L, 2014L, 2014L, 2015L, 2015L, 2016L, 2016L, 2016L, 2016L), event.id = c(33L, 33L, 33L, 33L, 35L, 35L, 35L, 47L, 47L, 58L, 58L, 61L, 61L, 65L, 69L, 69L, 69L), ID = structure(c(44L, 49L, 60L, 66L, 49L, 60L, 66L, 66L, 41L, 66L, 41L, 60L, 43L, 43L, 60L, 43L, 41L), levels = c("J11", "J16", "J17", "J2", "J22", "J26", "J27", "J30", "J31", "J35", "J36", "J37", "J38", "J39", "J40", "J41", "J42", "J46", "J47", "J49", "J56", "K16", "K21", "K22", "K25", "K26", "K33", "K35", "K36", "K37", "K40", "K42", "L100", "L101", "L103", "L105", "L106", "L109", "L110", "L111", "L113", "L115", "L119", "L12", "L123", "L21", "L22", "L26", "L41", "L47", "L5", "L54", "L55", "L57", "L58", "L67", "L7", "L72", "L73", "L77", "L82", "L83", "L86", "L87", "L91", "L94", "L95", "LU"), class = "factor"), Sex = structure(c(1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L ), levels = c("Female", "Male"), class = "factor"), age = c(73L, 29L, 19L, 11L, 30L, 20L, 12L, 15L, 1L, 19L, 5L, 28L, 3L, 4L, 29L, 4L, 7L), matr = structure(c(9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L), levels = c("J2", "J4", "J7", "J9", "K11", "K18", "K4", "K8", "L12", "L2", "L21", "L26", "L32", "L35", "L37", "L4", "L4 ", "L66", "L9"), class = "factor"), matralive = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("0", "1"), class = "factor"), pod = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), levels = c("J", "K", "L"), class = "factor")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -17L)) cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7") # 动态提取每个ID对应的形状:Female用16(实心圆),Male用17(实心三角) id_shape <- idL12 %>% distinct(ID, Sex) %>% mutate(shape = case_when( Sex == "Female" ~ 16, Sex == "Male" ~ 17 )) %>% arrange(ID) %>% # 按ID排序,确保和图例顺序一致 pull(shape) L12 <- ggplot(idL12,aes(x = date, y = age)) + geom_point(size=7, aes( shape = Sex, color = ID ), show.legend = c( shape = FALSE, color = TRUE, size = FALSE ) ) + scale_x_date(expand = c(0.1, 0.1)) + scale_y_continuous(expand = c(0.1, 0.1)) + theme_classic() + labs(x = "Year", y = "") + ggtitle("Matriline L12") + theme(plot.title = element_text(hjust = 0.5)) + scale_colour_manual(values=cbPalette)+ scale_shape_manual(values = c(Female=16, Male=17)) + # 明确形状映射,确保图表与图例一致 theme(text=element_text(size=27))+ guides(colour = guide_legend(override.aes = list(size=6, shape=id_shape))) + # 覆盖图例形状 geom_mark_rect(aes(group=interaction(date))) + labs(color = "Individual") print(L12)
多图适配说明:
如果要生成其他数据集的图表,只需将代码中的idL12替换为目标数据集,重新运行id_shape的生成代码即可。id_shape会自动从当前数据集中提取每个ID的性别对应形状,无论数据集中ID数量、性别分布如何,都能自动匹配图例形状。
内容的提问来源于stack exchange,提问作者burphound
相关产品推荐
相关产品推荐

