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

如何用{ggrepel}调整环形图标签位置,避免与图重叠

解决环形图标签与图形重叠问题

问题背景

使用R的ggplot2和ggrepel制作环形图时,标签容易与环形区域重叠,希望将四个标签分别固定在图的左上、右上、左下、右下外侧位置,与环形保持足够间距。

解决方案

核心思路是手动计算标签的锚点位置,避免ggrepel自动布局的不确定性,同时调整绘图范围和标签参数确保布局符合预期。

修改后的完整代码

library(tidyverse)
library(ggrepel)

# 创建示例数据框
data <- data.frame(Column = c("v1", "v2", "v3", "v4"),
                   Value = c(86.5, 12.9, 0.0, 0.6),
                   Color = c("#007bc9", "#a50021", "#5ad5ff", "#002f80"),
                   Category = c("A", "B", "C", "D"),
                   Title = c("Variable 1", "Variable 2", "Variable 3", "Variable 4"))

# 自定义环形内孔大小
hsize <- 2

# 计算每个类别的角度中间位置(用于标签锚点)
data <- data %>%
  arrange(desc(Value)) %>%
  mutate(
    end = cumsum(Value),
    start = lag(end, default = 0),
    mid = (start + end)/2
  )

# 创建环形图
donut <- data %>%
  ggplot(aes(x = hsize, y = Value, fill = Category)) +
  geom_col() +
  coord_polar(theta = "y") +
  scale_fill_manual(values = data$Color) +
  # 扩大x轴范围,给外侧标签留出足够空间
  xlim(c(0.1, hsize + 1.8)) +
  labs(x = "", y = "") +
  ggtitle("Title") +
  theme(
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(
      color = "#002f80",
      face = "bold",
      hjust = 0.5,
      size = 16
    ),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank()
  ) +
  guides(fill = "none") +
  scale_y_reverse()

# 添加外侧标签,手动指定锚点位置
donut <- donut +
  geom_label_repel(
    aes(x = hsize + 1.2, y = mid, 
        label = paste0(Title, "\n", if_else(Value == 0, "0%", paste0(Value, "%")))),
    color = "#002f80",
    size = 4,
    fill = "white",
    box.padding = 0.8,
    force = 2,
    force_pull = 0,  # 关闭向内拉力,防止标签靠近环形
    nudge_x = 0.2,   # 稍微向外推标签,增加间距
    segment.size = 0.7,
    direction = "y"  # 限制标签仅在垂直半径方向调整,保证布局符合预期
  )

print(donut)

关键修改说明

  1. 手动计算锚点位置
    通过累计Value得到每个类别的角度范围,取中间值mid作为标签在极坐标y轴(角度轴)的锚点;同时将标签的x坐标设为hsize+1.2,确保锚点位于环形图外侧。

  2. 扩大绘图范围
    将xlim的上限从hsize+0.5调整为hsize+1.8,给外侧标签留出足够的显示空间,避免被截断。

  3. 优化ggrepel参数

    • force_pull=0:关闭标签向内的拉力,彻底避免标签被拉回环形区域
    • nudge_x=0.2:将标签稍微向外推,进一步增加与环形的间距
    • direction="y":限制标签仅在垂直于半径的方向调整,确保四个标签分别落在左上、右上、左下、右下的预期位置
  4. 兼容0值类别
    即使类别Value为0,通过累计计算的mid值仍能准确定位,标签会出现在对应角度的外侧,不会出现重叠或丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:54:54