You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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--

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:09:47