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

R语言径向图标签连接优化:避免标签重叠的解决方案求助

问题

作为R语言新手,绘制带不同大小、颜色数据点的径向图时遇到标签重叠问题。尝试用线段连接标签和数据点,但线段仅水平/垂直,标签位置不准,效果差。优先用base R解决,也接受其他方案。

数据(前6行)
study year  c p      mc     mp     sc     sp     yi     vi 
1     1 2015 54 6  68.130 26.500 34.861 24.450 1.2053 0.1973 
2     2 2007 26 8  23.000 18.400 13.000  8.200 0.3708 0.1655 
3     3 2023 78 9  60.010 48.670 25.480 31.220 0.4311 0.1250 
4     4 2013 69 9  53.400 24.700 37.700 25.700 0.7759 0.1295 
5     5 2008  4 1  17.500  1.200 12.010  1.000 0.9821 1.3464 
6     6 2015 40 8 132.075 25.875 38.697 23.648 2.8381 0.2339
  • c/p:两组样本量
  • mc/mp:两组均值
  • sc/sp:两组标准差
  • yi/vi:效应量及方差
数据结构
Classes ‘escalc’ and 'data.frame':  18 obs. of  10 variables:
 $ study: num  1 2 3 4 5 6 7 8 9 10 ...
 $ year : num  2015 2007 2023 2013 2008 ...
 $ c    : num  54 26 78 69 4 40 38 88 7 24 ...
 $ p    : num  6 8 9 9 1 8 8 5 3 2 ...
 $ mc   : num  68.1 23 60 53.4 17.5 ...
 $ mp   : num  26.5 18.4 48.7 24.7 1.2 ...
 $ sc   : num  34.9 13 25.5 37.7 12 ...
 $ sp   : num  24.4 8.2 31.2 25.7 1 ...
 $ yi   : num  1.205 0.371 0.431 0.776 0.982 ...
  ..- attr(*, "ni")= num [1:18] 60 34 87 78 5 48 46 93 10 26 ...
  ..- attr(*, "slab")= chr [1:18] "1 2015" "2 2007" "3 2023" "4 2013" ...
  ..- attr(*, "measure")= chr "SMD"
 $ vi   : num  0.197 0.165 0.125 0.129 1.346 ...
 - attr(*, "digits")= Named num [1:9] 4 4 4 4 4 4 4 4 4
  ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ...
 - attr(*, "yi.names")= chr "yi"
 - attr(*, "vi.names")= chr "vi"
已尝试的代码

数据准备与模型拟合

seeds_p <- escalc(measure = "SMD", m1i= mc , m2i= mp, sd1i= sc, sd2i= sp, n1i= c, n2i= p, data = seeds, slab = paste(study, year), drop00 = TRUE) 

# Fit random-effects model using the DL estimator 
res_p <- rma(yi, vi, data = seeds_p, method = "DL")

绘图及标签尝试(基础版)

radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16,
       cex = seeds_p$yi * 8 / max(seed_p$yi, na.rm = TRUE),
       col = seeds$Col, cex.axis = 2, cex.lab = 1.8)

par(mar = c(7, 7, 7, 7) + 0.2) # Adjust the values as needed

# Extract only the study names without the date
study_labels <- gsub("\s\d{4}$", "", seeds$study)

# Add labels with basic text and segments
text_labels <- data.frame( x = res_p$yi * 4 / max(res_p$yi, na.rm = TRUE),
                           y = sqrt(1 / res_p$vi),
                           label = study_labels)

# Add labels with basic text
text(text_labels$x, text_labels$y, labels = text_labels$label, pos = 3, col = "black", cex = 0.8)
# Add segments connecting points to labels
segments(
  x0 = text_labels$x,
  y0 = text_labels$y,
  x1 = res_p$yi * 15 / max(res_p$yi, na.rm = TRUE),
  y1 = sqrt(1 / res_p$vi),
  col = "black"
)

循环添加标签与线段

# Add labels and connecting lines
for (i in 1:nrow(seeds_p)) {
  x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE)
  y <- sqrt(1 / res_p$vi[i])
  
  # Add label with offset
  text(x, y, study_labels[i], pos = ifelse(x > 0, 4, 2), col = "black", offset = 1.5)
  
  # Add connecting line
  lines(c(x, x), c(y, 0), col = "black")
}

另一版循环写法

# Create radial plot
radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16,
       cex = seeds_p$yi * 3 / max(platelets_p$yi, na.rm = TRUE),
       col = seeds$Col, cex.axis = 2, cex.lab = 1.8)
par(mar = c(7, 7, 7, 7) + 0.2)  # Adjust the values as needed

# Extract only the study names without the date
study_labels <- gsub("\s\d{4}$", "", seeds_p$study)

# Add labels and connecting lines
for (i in 1:nrow(seeds_p)) {
  x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE)
  y <- sqrt(1 / res_p$vi[i])
  
  # Add label
  text(x, y, study_labels[i], pos = 3, col = "black")
  
  # Add connecting line
  lines(c(x, x), c(y, 0), col = "black")
}

同时试过ggrepel和directlabels包,但效果不佳。

解决方案

方案1:Base R + calibrate包自动调整标签

calibrate包的textxy函数可自动计算标签最佳位置,避免重叠,同时支持绘制连接线。

# 安装包(首次使用)
install.packages("calibrate")
library(calibrate)
library(metafor)

# 绘制径向图
radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16,
       cex = seeds_p$yi * 8 / max(seeds_p$yi, na.rm = TRUE), # 修正变量名错误
       col = seeds$Col, cex.axis = 2, cex.lab = 1.8)
par(mar = c(7,7,7,7)+0.2)

# 提取标签和坐标
study_labels <- gsub("\\s\\d{4}$", "", seeds_p$slab) # 直接从slab提取更准确
x_coords <- res_p$yi
y_coords <- sqrt(1/res_p$vi)

# 添加自动调整的标签和连接线
textxy(x_coords, y_coords, labs = study_labels, 
       cx = 0.8, col = "black", 
       offset = 0.5,
       box = FALSE,
       lines = TRUE,
       col.lines = "black")

方案2:ggplot2 + ggrepel(更灵活)

若base R方案仍不理想,用ggplot2重绘径向图,结合ggrepel自动处理标签重叠,效果更稳定。

# 安装包(首次使用)
install.packages(c("ggplot2", "ggrepel"))
library(ggplot2)
library(ggrepel)
library(metafor)

# 整理绘图数据
plot_data <- data.frame(
  yi = res_p$yi,
  precision = sqrt(1/res_p$vi),
  study_label = gsub("\\s\\d{4}$", "", seeds_p$slab),
  size = seeds_p$yi / max(seeds_p$yi, na.rm = TRUE) * 8,
  color = seeds$Col
)

# 绘制径向图
ggplot(plot_data, aes(x = yi, y = precision)) +
  # 模拟背景置信区间
  geom_ribbon(aes(ymin = 0, ymax = Inf), fill = alpha("lightgreen", 0.05)) +
  # 添加数据点
  geom_point(aes(size = size, color = color), shape = 16) +
  # 添加自动调整的标签和连接线
  geom_text_repel(aes(label = study_label),
                  size = 3,
                  color = "black",
                  segment.color = "black",
                  segment.size = 0.5,
                  box.padding = 0.5,
                  max.overlaps = Inf) +
  # x轴指数转换
  scale_x_continuous(trans = "exp") +
  # 设置轴标签和主题
  labs(x = "Exponential of SMD", y = "Precision (1/sqrt(vi))") +
  theme_bw() +
  theme(axis.text = element_text(size = 14),
        axis.title = element_text(size = 16),
        plot.margin = margin(20,20,20,20))

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:47:05