使用scale_fill_manual绘制地图时因子层级/颜色/排序失效求助
问题解决思路
你的核心问题出在merge操作后有序因子的层级被打乱,以及drop=F需要配合limits参数才能强制显示所有因子水平。以下是具体修复步骤:
1. 修复因子层级
merge空间对象时,原始的有序因子属性可能会丢失或被重排,需要在merge后重新指定Mu的因子水平为你定义的有序层级:
# 在sp_map创建后添加这行代码 sp_map$Mu <- factor(sp_map$Mu, levels = levels(properties$Mu), ordered = TRUE)
2. 强制图例显示所有层级并保持顺序
在scale_fill_manual中添加limits = levels(properties$Mu),配合drop=F就能强制显示所有你定义的因子水平,同时保持正确顺序。
修改后的完整代码(普通values向量写法)
library(terra) library(tidyterra) library(tidyverse) map_file <- vect("~/Downloads/BCR_Terrestrial/BCR_Terrestrial_master.shp") %>% project("+proj=lcc +lat_0=49 +lon_0=-95 +lat_1=49 +lat_2=77 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs") %>% subset(., !(.$OBJECTID %in% c(1, 354, 371, 372)) & .$COUNTRY != "MEXICO") set.seed(123) properties <- tibble( Mean = rnorm(9, mean = 0, sd = 0.25), BCR = rep(c(6,11,17),3), Process = c(1,1,1,2,2,2,3,3,3)) %>% mutate( Mu = cut(Mean, breaks = c(-Inf, -0.4, -0.3, -0.2, -0.1, -0.05, 0.05, 0.1, 0.2, 0.3, 0.4, Inf), labels = c("< 0.4", "-0.4 : -0.3", "-0.3 : -0.2", "-0.2 : -0.1", "-0.1 : -0.05", "-0.05 : 0.05", "0.05 : 0.1", "0.1 : 0.2", "0.2 : 0.3", "0.3 : 0.4", "> 0.4"), ordered_result = T)) sp_map <- merge(subset(map_file, map_file$BCR %in% properties[["BCR"]]), properties) # 修复因子层级 sp_map$Mu <- factor(sp_map$Mu, levels = levels(properties$Mu), ordered = TRUE) ggplot(sp_map)+ geom_spatvector(aes(fill = Mu))+ facet_wrap(~Process)+ geom_spatvector(data = subset(map_file, !map_file$BCR %in% sp_map$BCR), fill = "white", size = 0.1)+ scale_fill_manual( values = c("#a50026", "#d73027", "#f46d43", "#fdae61", "#fee090", "#ffffbf", "#e0f3f8", "#abd9e9", "#74add1", "#4575b4", "#313695"), name = "Spice", drop = F, limits = levels(properties$Mu) # 强制按定义的顺序显示所有层级 )+ theme_minimal()+ theme(axis.title = element_blank())
修改后的命名values向量写法
如果用命名向量,同样需要添加limits参数来锁定顺序:
ggplot(sp_map)+ geom_spatvector(aes(fill = Mu))+ facet_wrap(~Process)+ geom_spatvector(data = subset(map_file, !map_file$BCR %in% sp_map$BCR), fill = "white", size = 0.1)+ scale_fill_manual( values = c("< 0.4"="#a50026", "-0.4 : -0.3"="#d73027", "-0.3 : -0.2"="#f46d43", "-0.2 : -0.1"="#fdae61", "-0.1 : -0.05"="#fee090", "-0.05 : 0.05"="#ffffbf", "0.05 : 0.1"="#e0f3f8", "0.1 : 0.2"="#abd9e9", "0.2 : 0.3"="#74add1", "0.3 : 0.4"="#4575b4", "> 0.4"="#313695"), name = "Spice", drop = F, limits = levels(properties$Mu) # 确保图例顺序与定义的因子层级一致 )+ theme_minimal()+ theme(axis.title = element_blank())
关键说明
merge操作会将空间对象的属性转换为普通数据框格式,可能丢失有序因子的属性,因此需要手动重新指定层级。drop=F本身不会强制显示所有未出现的因子水平,必须配合limits参数指定完整的因子水平列表,才能让ggplot显示所有你定义的图例项。
内容的提问来源于stack exchange,提问作者SGE
相关产品推荐
相关产品推荐

