ggplot中设置shape美学映射但形状图例未显示的技术问题
问题:ggplot中形状图例未显示
使用ggplot创建包含color和shape两种美学映射的图表时,颜色图例正常显示,但形状图例未出现。
原绘图代码
sav %>% ggplot(aes(x = Subject, y = Percentage, color = Subject, shape = Location)) + geom_point(data = filter(sav, Location == "IRELAND"), shape = "square", size = 3) + geom_point(data = filter(sav, Location == "OECD"), shape = "diamond", size = 3) + geom_point(data = filter(sav, !Location %in% c("OECD", "IRELAND")), shape = "circle", size = 2, position = "jitter") + coord_flip() + theme(legend.position = "top")+ theme_light()
数据dput输出
structure(list(Location = c("CANADA", "CANADA", "FRANCE", "FRANCE", "GERMANY", "GERMANY", "IRELAND", "IRELAND", "ITALY", "ITALY", "NETHERLANDS", "NETHERLANDS", "SPAIN", "SPAIN", "UNITED STATES", "UNITED STATES", "OECD", "OECD", "CANADA", "ITALY", "SPAIN", "FRANCE", "IRELAND", "UNITED STATES", "NETHERLANDS", "OECD", "GERMANY"), Subject = c("Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", "Total", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy"), Frequency = c("Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly"), Time = c("2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12" ), Percentage = c(11.02015, 6.319445, 12.86678, 5.850718, 19.75631, 8.550855, 11.74636, 8.224299, 13.14815, 11.63227, 16.7983, 9.586879, 15.68565, 5.70769, 11.88275, 6.454401, 15.60381, 9.438622, 5.58275, 4.469475, 4.442303, 3.36004, 4.999758, 5.707835, 6.034873, 7.221961, 5.05511)), class = "data.frame", row.names = c(NA, -27L))
图表截图

原因分析
你在每个geom_point()中手动指定了shape参数(比如shape = "square"),这属于直接设置图形属性,而非基于数据的美学映射。这种操作会覆盖全局aes()中shape = Location的映射规则,导致ggplot无法识别需要为Location生成对应的形状图例。
解决方案
推荐采用符合ggplot语法的方式:保留全局的shape = Location映射,通过scale_shape_manual()来指定每个Location对应的形状,同时可以通过size的映射或手动调整来区分不同组的点大小。
修改后的代码
library(dplyr) library(ggplot2) sav %>% ggplot(aes(x = Subject, y = Percentage, color = Subject, shape = Location, size = Location)) + geom_point(position = position_jitter(height = 0)) + # 指定每个Location对应的形状 scale_shape_manual(values = c( CANADA = 16, FRANCE = 16, GERMANY = 16, ITALY = 16, NETHERLANDS = 16, SPAIN = 16, `UNITED STATES` = 16, IRELAND = 15, OECD = 18 )) + # 指定每个Location对应的点大小 scale_size_manual(values = c( CANADA = 2, FRANCE = 2, GERMANY = 2, ITALY = 2, NETHERLANDS = 2, SPAIN = 2, `UNITED STATES` = 2, IRELAND = 3, OECD = 3 )) + coord_flip() + theme(legend.position = "top") + theme_light()
简化方案(如果不需要单独设置每个国家的形状)
如果只需要区分IRELAND/OECD和其他国家,也可以先对Location进行分组,再映射:
sav %>% mutate(Location_group = case_when( Location == "IRELAND" ~ "IRELAND", Location == "OECD" ~ "OECD", TRUE ~ "Other Countries" )) %>% ggplot(aes(x = Subject, y = Percentage, color = Subject, shape = Location_group, size = Location_group)) + geom_point(position = position_jitter(height = 0)) + scale_shape_manual(values = c("Other Countries" = 16, IRELAND = 15, OECD = 18)) + scale_size_manual(values = c("Other Countries" = 2, IRELAND = 3, OECD = 3)) + coord_flip() + theme(legend.position = "top") + theme_light()
这两种方法都能让ggplot自动生成形状图例,同时保持你需要的点样式区分。
内容的提问来源于stack exchange,提问作者Smitesh Patil
相关产品推荐
相关产品推荐

