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

ggplot2中geom_segments尺寸不同导致图例重叠的解决方法

解决ggplot2中不同size线段图例重叠的问题

问题根源

你的代码中为不同国家分别调用了多组geom_segment,且size是作为固定参数而非美学映射(aes)传入的,这导致ggplot会将所有线段的图例元素叠加显示,最终出现不同尺寸的虚线/点线重叠的问题。

两种解决方案

方案1:通过override.aes修正图例(无需重构数据)

直接在图例设置中强制指定每个国家对应的线条尺寸,同时合并颜色和线型图例,避免重叠:

dataframe = data.frame(country = c("Burundi", "Kenya"),
                       rate1 = c(10, 3),
                       threshold1 = c(180, 72.2),
                       rate2 = c(25, 20),
                       threshold2 = c(242, 144),
                       rate3 = c(30,30))
xstart_limit <- 0
xend_limit <- 10000
linetypes <- c("dotted", "dashed")
my_colors <- c("blue","red")
sizes <- c(1, 0.6) # 对应Burundi和Kenya的线条尺寸

pit_comparison2 <- ggplot() +
  # 保留原有geom_segment代码
  geom_segment(aes(x = xstart_limit, y = rate1, xend = threshold1, yend = rate1, colour = country, linetype = country), size = 0.6, data = dataframe[dataframe$country == "Kenya",]) +
  geom_segment(aes(x = threshold1, y = rate1, xend = threshold1, yend = rate2, colour = country, linetype = country), size = 0.6, data = dataframe[dataframe$country == "Kenya",]) +
  geom_segment(aes(x = threshold1, y = rate2, xend = threshold2, yend = rate2, colour = country, linetype = country), size = 0.6, data = dataframe[dataframe$country == "Kenya",]) +
  geom_segment(aes(x = threshold2, y = rate2, xend = threshold2, yend = rate3, colour = country, linetype = country), size = 0.6, data = dataframe[dataframe$country == "Kenya",]) +
  geom_segment(aes(x = threshold2, y = rate3, xend = xend_limit, yend = rate3, colour = country, linetype = country), size = 0.6, data = dataframe[dataframe$country == "Kenya",]) +
  
  geom_segment(aes(x = xstart_limit, y = rate1, xend = threshold1, yend = rate1, colour = country, linetype = country), size = 1, data = dataframe[dataframe$country == "Burundi",]) +
  geom_segment(aes(x = threshold1, y = rate1, xend = threshold1, yend = rate2, colour = country, linetype = country), size = 1, data = dataframe[dataframe$country == "Burundi",]) +
  geom_segment(aes(x = threshold1, y = rate2, xend = threshold2, yend = rate2, colour = country, linetype = country), size = 1, data = dataframe[dataframe$country == "Burundi",]) +
  geom_segment(aes(x = threshold2, y = rate2, xend = threshold2, yend = rate3, colour = country, linetype = country), size = 1, data = dataframe[dataframe$country == "Burundi",]) +
  geom_segment(aes(x = threshold2, y = rate3, xend = xend_limit, yend = rate3, colour = country, linetype = country), size = 1, data = dataframe[dataframe$country == "Burundi",]) +
  
  scale_linetype_manual(values = linetypes, breaks=c("Burundi", "Kenya")) +
  scale_color_manual(values = my_colors, breaks=c("Burundi", "Kenya")) +
  # 关键:强制指定图例中每个项的尺寸,合并图例避免重叠
  guides(
    colour = guide_legend(override.aes = list(size = sizes)),
    linetype = guide_legend(override.aes = list(size = sizes))
  )

pit_comparison2

方案2:重构数据(更简洁易维护)

将所有线段的起点、终点整理成长格式数据框,把size映射到美学属性中,让ggplot自动生成正确的图例:

library(tidyr)
library(dplyr)

dataframe = data.frame(country = c("Burundi", "Kenya"),
                       rate1 = c(10, 3),
                       threshold1 = c(180, 72.2),
                       rate2 = c(25, 20),
                       threshold2 = c(242, 144),
                       rate3 = c(30,30))
xstart_limit <- 0
xend_limit <- 10000
linetypes <- c("dotted", "dashed")
my_colors <- c("blue","red")

# 重构数据:拆分每个国家的所有线段为单独行
seg_data <- dataframe %>%
  rowwise() %>%
  summarise(
    country = country,
    x = c(xstart_limit, threshold1, threshold1, threshold2, threshold2),
    y = c(rate1, rate1, rate2, rate2, rate3),
    xend = c(threshold1, threshold1, threshold2, threshold2, xend_limit),
    yend = c(rate1, rate2, rate2, rate3, rate3),
    .groups = "drop"
  ) %>%
  mutate(size = ifelse(country == "Burundi", 1, 0.6))

# 绘制图形,size作为美学映射
pit_comparison3 <- ggplot(seg_data) +
  geom_segment(aes(x = x, y = y, xend = xend, yend = yend, 
                   colour = country, linetype = country, size = country)) +
  scale_linetype_manual(values = linetypes) +
  scale_color_manual(values = my_colors) +
  scale_size_manual(values = c("Burundi" = 1, "Kenya" = 0.6)) +
  # 合并所有图例为一个,更整洁
  guides(color = guide_legend(), linetype = guide_legend(), size = guide_legend()) +
  theme(legend.box = "vertical")

pit_comparison3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:12:48