ggplot自定义图例符号:旋转key_glyph实现贸易流图图例样式
自定义图例符号解决贸易流图样式问题
问题背景
我想要复刻Chris Canipe的贸易流图样式,已完成基础地图绘制,但图例样式无法匹配需求:
- 使用
draw_key_vline效果接近,但需要将线条旋转90度 - 使用
draw_key_rect时,图例符号大小无法随trade_val(贸易额)缩放
解决方案
核心思路是自定义图例符号绘制函数,修改默认draw_key_vline的线条方向,同时保留linewidth与trade_val的缩放关联。
完整修改代码
library(tidyverse) library(ggarrow) library(rnaturalearth) # 自定义横向线条图例函数:替换竖线为横线 draw_key_hline <- function(data, params, size) { grid::segmentsGrob( x0 = 0.1, x1 = 0.9, y0 = 0.5, y1 = 0.5, gp = grid::gpar( col = alpha(data$colour %||% params$colour %||% "black", data$alpha %||% params$alpha), lwd = (data$linewidth %||% params$linewidth %||% 1) * .pt, lty = data$linetype %||% params$linetype %||% 1, lineend = "butt" ) ) } countries <- ne_countries(scale = "medium", returnclass = "sf") data <- data.frame( From = c("Australia", "Belize", "China", "Cook Islands", "Fiji"), from_x = c(133.77514, -88.49765, 104.19540, -159.77767, 179.41441), from_y = c(-25.274398, 17.189877, 35.861660, -21.236736, -16.578193), to_y = c(40.67778, 40.67778, 40.67778, 40.67778, 40.67778), to_x = c(-74.04425, -74.04425, -74.04425, -74.04425, -74.04425), trade_val = c(275, 66, 126755, 700, 19000) ) ggplot(data = data)+ geom_sf(data = countries)+ geom_arrow_curve( data = data, show.legend = T, aes(x = from_x, y = from_y, xend = to_x, yend = to_y, linewidth = trade_val, alpha = trade_val), angle = 90, lineend = "butt", length = unit(0.5, "cm"), colour = "#08519B", key_glyph = draw_key_hline # 指定自定义图例函数 )+ theme( legend.position = "top", legend.text.position = "bottom", legend.key.spacing.x = unit(-1.5, "cm"), legend.text = element_text(margin = margin(r = 0, unit = "pt")), panel.background = element_rect(fill = 'white', colour = 'white'), plot.background = element_rect(fill = 'white', colour = 'white'), legend.title = element_text(hjust = 0.5) )+ guides( alpha = guide_legend(title = "Trade flow", label.position = "bottom"), linewidth = guide_legend( title = "Trade flow", title.position = "top", label.position = "bottom", keywidth = 6 ), # 合并alpha与linewidth图例,避免重复 override.aes = list(alpha = 1) )
关键说明
自定义
draw_key_hline函数:- 基于
draw_key_vline改造,将竖线逻辑改为横向线段(x从0.1到0.9,y固定为0.5),实现目标图例的横向线条样式 - 保留了
linewidth的参数映射,确保图例线条宽度随trade_val同步缩放
- 基于
图例合并优化:
- 通过
override.aes = list(alpha = 1)固定透明度,让alpha和linewidth共享同一组图例,避免重复显示 - 保留原有主题配置,维持图例的布局和视觉风格
- 通过
内容的提问来源于stack exchange,提问作者Rupert Stacy
相关产品推荐
相关产品推荐

