如何在geom_label_repel中结合plotmath实现标签下标效果
问题:在ggplot的geom_label_repel中添加带数据值的下标
我希望在geom_label_repel生成的标签里添加下标,比如:
Maine
Apo (km/h) = 9
Qt (m/s) = 90
我知道可以用[x]语法实现下标,但不知道怎么结合数据列中的动态值来实现。尝试用tidyeval的!!没成功,甚至把parse = TRUE打开就报错。可能忽略了基础内容,但查了相关线程后还是不确定问题出在哪。
当前代码
加载依赖包
library(tidyverse) library(stringr) library(usmap) library(ggrepel) library(rlang)
构造数据集
read.table(text = "State Apo Qt NJ 1 10 MO 2 20 SD 3 30 NY 4 40 FL 5 50 OK 6 60 NE 7 70 KY 8 80 ME 9 90 CA 10 100 NC 11 110 MA 12 120 CT 13 140", header = T, stringsAsFactor = F) -> ex1
数据预处理
# 获取州的全名 region <- state.name[match(ex1$State,state.abb)] region <- str_to_title(region) # 美国地图数据(50个州) us1 <- usmap::us_map() # 将州全名加入数据集 ex_df <- cbind(region = region, ex1) # 给地图数据添加对应州的数值(仅包含有数据的州) us_val1 <- left_join(ex_df, us1, by = c("region" = "full")) # 合并完整地图数据与ex1,用于绘制地图 us_map1 <- left_join(us1, ex_df, by = c("full" ="region")) %>% mutate(qQt = replace_na(Qt, 0)) # 创建包含目标州质心的数据集 us_centroids1 <- us_val1 %>% group_by(region) %>% summarise(centroid.x = mean(range(x)), centroid.y = mean(range(y)), label = unique(State), `Apo` = unique(Apo), `Qt` = unique(Qt))
绘图代码
## 绘制地图 ggplot() + geom_polygon(data = us_map1, aes(x,y, group = group, fill = Qt), color = "black", size = .1) + geom_label_repel(data = us_centroids1, aes(centroid.x, centroid.y, label = paste(region, " Apo (km/h) = ", `Apo`, " Qt (m/s) =", `Qt`)), size = 5/14*8, box.padding = 1, parse = F) + scale_fill_gradientn(name = expression(Q[t]~(m/s)), breaks = c(0, seq(10,130,20)), labels = c("", seq(10,130,20)), limits = c(0, 130), colors = c("#DCDCDC", "lightblue", "green"), guide = guide_colorbar(barwidth = 0.8, barheight = 18)) + theme_void()
当前效果

解决方案
要实现带动态数据的下标标签,核心是构造符合plotmath语法的标签字符串,再通过parse=TRUE让ggplot解析。具体步骤如下:
1. 构造解析用的标签字符串
在us_centroids1数据集中新增一列,生成包含下标和动态数值的plotmath格式字符串:
us_centroids1 <- us_centroids1 %>% mutate( label_text = paste0( "'", region, "'~'\\n'~", # 州名用单引号包裹避免空格解析问题,添加换行 "A[po]~'(km/h)'~'='~", Apo, "~'\\n'~", # Aₚₒ + 单位 + 对应数值,添加换行 "Q[t]~'(m/s)'~'='~", Qt # Qₜ + 单位 + 对应数值 ) )
语法说明:
A[po]:plotmath中表示A的下标为po~:用于分隔元素,相当于空格'\\n':表示换行(字符串中需转义反斜杠)- 单引号包裹普通文本(如州名、单位),避免被plotmath当作语法解析
2. 修改绘图代码
将geom_label_repel的label替换为新生成的label_text,并开启parse=TRUE:
ggplot() + geom_polygon(data = us_map1, aes(x,y, group = group, fill = Qt), color = "black", size = .1) + geom_label_repel(data = us_centroids1, aes(centroid.x, centroid.y, label = label_text), size = 5/14*8, box.padding = 1, parse = TRUE) + # 关键:开启plotmath解析 scale_fill_gradientn(name = expression(Q[t]~(m/s)), breaks = c(0, seq(10,130,20)), labels = c("", seq(10,130,20)), limits = c(0, 130), colors = c("#DCDCDC", "lightblue", "green"), guide = guide_colorbar(barwidth = 0.8, barheight = 18)) + theme_void()
这样就能生成带下标且动态显示数据的标签了。
内容的提问来源于stack exchange,提问作者M--
相关产品推荐
相关产品推荐

