使用Patchwork拼接地图时图例位置调整失败求助
Patchwork图例与地图对齐问题解决方案
我用Patchwork绘制3张地图,其中前两张共用名为“SIF anomalies”的图例,第三张有独立图例。当前遇到的问题是:第一个图例无法和前两张地图很好对齐,第二个图例也需要与第三张地图对齐。尝试过移除单图的图例设置、使用guide_area()、调整Patchwork参数,但要么无效果,要么出现报错提示:"Manual legend position not possible for collected guides. Defaulting to 'right'"。

以下是我当前的绘图代码:
#MAP1: SIF/SM map1=ggplot(data = sif_min_sm2) + geom_tile(aes(x = lon, y = lat, fill = cut(SIF_SM, breaks = my_breaks, include.lowest = TRUE))) + coord_equal() + labs(x = "Longitude", y = "Latitude") + scale_fill_manual( values = my_colors, labels = levels(break_labels), na.value = "white", name = "SIF anomalies", limits = levels(break_labels) ) + ggtitle("SIF anomalies for driest SM month") + theme_minimal() + theme( panel.background = element_blank(), plot.title = element_text(size = 14, face = "bold"), legend.position = "right", legend.key.size = unit(1, "lines"), legend.text = element_text(size = 8), legend.key.height = unit(1, "cm"), legend.margin = margin(t = 0, r = 5, b = 0, l = 0) ) #Map 2: SIF/VPD map2=ggplot(data = sif_min_vpd2) + geom_tile(aes(x = lon, y = lat, fill = cut(SIF_VPD, breaks = my_breaks, include.lowest = TRUE))) + coord_equal() + labs(x = "Longitude", y = "Latitude") + scale_fill_manual( values = my_colors, labels = levels(break_labels), na.value = "white", name = "SIF anomalies", limits = levels(break_labels) ) + ggtitle("SIF anomalies for driest VPD month") + theme_minimal() + theme( panel.background = element_blank(), plot.title = element_text(size = 14, face = "bold") ) #Map 3: VPD vs SM for lowest SIF anomalie map3=ggplot(data = test) + geom_tile(aes(x = lon, y = lat, fill = min_column)) + coord_equal() + labs(x = "Longitude", y = "Latitude") + scale_fill_brewer(palette="Set1", direction=1 )+ ggtitle("SIF anomalies for driest SM/VPD month") + theme_minimal()+ theme(panel.background = element_blank(), plot.title = element_text(size = 14, face = "bold"), legend.title = element_blank()) #common legend combined <- (map1 / map2) & theme(legend.position = "right", legend.key.size = unit(1, "lines"), # Increase the size of the legend keys legend.text = element_text(size = 8), legend.key.height = unit(0.9, "cm"),# Reduce the size of the legend text legend.margin = margin(t = 0, r = 5, b = 2, l = 0), legend.box.spacing = unit(2, "cm")) # Add some margin to the legend (combined /map3) + plot_layout(guides = "collect")
解决方法:分组控制图例布局
核心思路是分开处理两组图例,避免一次性收集所有guides导致的对齐问题,通过嵌套布局和图例提取来精准控制位置:
方案1:提取图例后嵌入对应区域
# 1. 隐藏所有单图的图例,避免重复显示 map1_noleg <- map1 + theme(legend.position = "none") map2_noleg <- map2 + theme(legend.position = "none") map3_noleg <- map3 + theme(legend.position = "none") # 2. 提取前两张图的共用图例(从map1提取即可,参数一致) legend_sif <- get_legend(map1) # 提取第三张图的独立图例 legend_vpd_sm <- get_legend(map3) # 3. 组合前两张图,并将图例嵌入到右侧对齐 top_section <- (map1_noleg / map2_noleg) + inset_element(legend_sif, left = 0.82, right = 1, top = 1, bottom = 0, align_to = "panel") # 对齐到面板区域 # 4. 组合第三张图和它的图例 bottom_section <- map3_noleg + inset_element(legend_vpd_sm, left = 0.82, right = 1, top = 1, bottom = 0, align_to = "panel") # 5. 最终组合上下区域,可调整高度比例适配你的图 final_plot <- top_section / bottom_section + plot_layout(heights = c(2, 1)) final_plot
方案2:嵌套布局分组收集guides
# 1. 先隐藏每张图的图例 map1 <- map1 + theme(legend.position = "none") map2 <- map2 + theme(legend.position = "none") map3 <- map3 + theme(legend.position = "none") # 2. 前两张图组合,单独收集它们的guides并设置位置 top_combined <- (map1 / map2) + plot_layout(guides = "collect") & theme(legend.position = "right", legend.key.size = unit(1, "lines"), legend.text = element_text(size = 8), legend.key.height = unit(0.9, "cm")) # 3. 第三张图单独添加图例 bottom_combined <- map3 + theme(legend.position = "right", legend.text = element_text(size = 8)) # 4. 最终组合,保留各自的guides布局 final_plot <- top_combined / bottom_combined + plot_layout(guides = "keep", heights = c(2, 1)) final_plot
关键说明
- 不要用
plot_layout(guides = "collect")一次性收集所有图例,会导致不同组的图例挤在一起,无法分别对齐。 - 使用
get_legend()提取图例后,inset_element()可以精准控制图例在对应地图组的位置,保证对齐。 - 调整
left/right参数或plot_layout()的widths/heights,可以适配你的地图尺寸和图例大小。
内容的提问来源于stack exchange,提问作者herakles_1950
相关产品推荐
相关产品推荐

