解决ggplot2中scale_shape_manual导致geom_point填充消失的问题
问题描述
我正在绘制河流浓度-流量格局与农业、城市用地占比的关系图,示例数据如下:
df.tri<-structure(list(site_no = c("01312000", "01349150", "01349840", "01349950", "01356190", "01357500", "013621955", "01362200", "0136230002", "01362370", "01362497", "01362500", "01413088", "01415460", "01421618", "01422738", "01422747", "0143400680", "01434021", "01434025", "01435000", "04213500", "04214500", "04215000", "04215500", "04218000", "04218518", "0422026250", "04229500", "04230500", "04231000", "04231600", "04232034", "04232050", "0423205010", "04232100", "04240180", "04249000", "04250200", "04250750", "04260500", "04269000"), Slope = c(0.19, 0.1, -0.01, 0.42, 0.11, 0.19, 0.61, 0.48, 0.69, 0.69, 0.43, 1.08, -0.14, 0.24, 0.29, 0.26, 0.52, 0.24, 0.17, 0.28, 0.46, 1.31, 0.87, 0.64, 0.81, 0.26, 0.58, 0.3, 0.11, 0.37, 0.07, 0.68, 0.24, 0.21, 0.5, 0.1, 0.2, -0.01, 0.06, -0.09, 0.27, 0.27), Type = c("Mobilization", "Mobilization", "Stationary", "Mobilization", "Stationary", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Dilution", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Mobilization", "Stationary", "Stationary", "Stationary", "Stationary", "Stationary", "Mobilization", "Mobilization"), DEVNLCD06 = c(0.68, 6.16, 0, 4.72, 55.42, 7.65, 6.07, 2.18, 0.71, 1.23, 2.16, 2.03, 2.32, 1.54, 1.93, 3.35, 2.97, 0, 0.08, 0, 0.6, 4.06, 7.15, 5.48, 10.27, 6.75, 17.32, 22.77, 4.92, 6.51, 8.57, 6.17, 10.47, 63.05, 38.18, 4, 4.48, 8.06, 0.34, 2.98, 1.34, 1.19), PLANTNLCD06 = c(0.01, 59.75, 0, 5.34, 3.22, 24.25, 0.23, 0.19, 0.03, 0.07, 1.51, 0.5, 9.48, 19.08, 32.62, 26.9, 31.24, 0, 0, 0, 0.23, 34.57, 45.19, 46.45, 25.32, 49.94, 33.19, 33.73, 34.8, 62.4, 64.81, 45.91, 50.93, 18.72, 32.62, 40.93, 42.55, 39.55, 1.87, 33.51, 11.05, 2.65)), row.names = c(NA, -42L), class = "data.frame")
将城市用地占比(DEVNLCD06)设为X轴,农业用地占比(PLANTNLCD06)设为Y轴,通过Type列的不同水平区分点形状,用Slope列的绝对值设置点颜色,初始代码可实现该效果:
ggplot(df.tri, aes(x=DEVNLCD06, y=PLANTNLCD06)) + geom_point(aes(shape=as.factor(Type), color=abs(Slope)), size = 4)
但使用scale_shape_manual将Mobilization设为上箭头(形状码2)、Dilution设为下箭头(形状码6)、Stationary设为空心圆(形状码1)后,点的填充效果消失:
ggplot(df.tri, aes(x=DEVNLCD06, y=PLANTNLCD06)) + geom_point(aes(shape=as.factor(Type), color=abs(Slope)), size = 4)+ scale_shape_manual(values = c("Mobilization" = 2, "Dilution" = 6, "Stationary" = 1))
尝试了scale_color_manual、scale_fill_manual等多种scale函数组合均未解决问题,如何在使用scale_shape_manual时保留点的填充效果?
解决方案
问题核心在于你选择的形状属性:形状2(上箭头)、6(下箭头)、1(空心圆)属于仅支持边框着色的形状,这类形状没有填充区域,无法通过fill参数实现填充效果,只能用color控制边框颜色。
你可以根据需求选择以下两种方案:
方案1:改用带填充属性的形状
替换为支持填充的形状码,比如实心上箭头(形状码24)、实心下箭头(形状码25)、实心圆(形状码16),通过fill绑定abs(Slope)实现渐变填充,同时可设置统一边框颜色增强区分度:
ggplot(df.tri, aes(x=DEVNLCD06, y=PLANTNLCD06)) + geom_point(aes(shape=as.factor(Type), fill=abs(Slope)), color="black", # 可选:统一边框颜色 size = 4)+ scale_shape_manual(values = c("Mobilization" = 24, "Dilution" = 25, "Stationary" = 16))+ scale_fill_viridis_c() # 用渐变颜色映射Slope绝对值
方案2:保留空心形状,强化颜色渐变效果
如果坚持使用空心箭头和空心圆,直接用color绑定abs(Slope)实现边框颜色渐变,可通过stroke参数增加边框粗细,让渐变效果更明显:
ggplot(df.tri, aes(x=DEVNLCD06, y=PLANTNLCD06)) + geom_point(aes(shape=as.factor(Type), color=abs(Slope)), size = 4, stroke=2) # 可选:增加边框粗细 + scale_shape_manual(values = c("Mobilization" = 2, "Dilution" = 6, "Stationary" = 1))+ scale_color_viridis_c() # 用渐变颜色映射Slope绝对值
内容的提问来源于Stack Exchange,提问作者Ryan
相关产品推荐
相关产品推荐

