使用 geom_text 避免标签重叠

Avoid overlapping labels using geom_text

我正在使用 geom_line 来显示不同国家/地区的比率。有没有办法避免国家/地区标签相互重叠,或者稍微移动水平重叠的国家/地区标签。

ggplot(df,aes(x=year, y = value, group = country, colour=country) ) +
  geom_line(size=1.3) +
  geom_text(data = df %>% filter(year == last(year)), aes(label = country, 
                                                                        x = year + 0.5, 
                                                                        y = value, 
                                                                        color = country), size=3) +
  guides(color = FALSE) + theme_bw()

这是数据:

   df<- structure(list(year = c(2015, 2020, 2025, 2030, 2035, 2015, 2020, 
2025, 2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 
2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 2030, 
2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 2030, 2035, 
2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 
2020, 2025, 2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 
2025, 2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 
2030, 2035, 2015, 2020, 2025, 2030, 2035, 2015, 2020, 2025, 2030, 
2035, 2015, 2020, 2025, 2030, 2035), country = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 
7L, 7L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 
10L, 10L, 11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 13L, 
13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 
15L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 
18L, 18L, 18L), .Label = c("USA", "CAN", "MEX", "JPN", "ANZ", 
"EUR", "ROE", "RUS", "ASI", "CHN", "IND", "BRA", "AFR", "MES", 
"LAM", "REA", "KOR", "IDZ"), class = "factor"), value = c(19.35, 
17.77, 16.19, 15.07, 13.7, 17.91, 16.3, 14.7, 13.58, 12.58, 17.91, 
16.3, 14.7, 13.58, 12.58, 0.91, 5.9, 10.88, 17.41, 16.93, NA, 
NA, NA, NA, NA, 26.79, 24, 21.22, 19.15, 17.24, 11.11, 11.16, 
11.2, 10.93, 11.16, 18.53, 17.41, 16.29, 16.63, 19.26, 4.05, 
4.78, 5.51, 6.42, 6.95, 2.9, 3.97, 5.04, 6.32, 7.67, 2.71, 2.69, 
2.68, 3.34, 4.09, 2.53, 2.34, 2.14, 3.23, 4.25, 1.54, 1.42, 1.3, 
2.13, 2.1, 0.26, 1.83, 3.4, 3.05, 3.99, 0.8, 0.76, 0.72, 0.91, 
1.38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA)), row.names = c(NA, -90L), class = c("tbl_df", "tbl", "data.frame"
))

如果您在对 geom_text 的调用中使用参数 check_overlap = TRUE,那么您将丢失重叠,但也会丢失重叠标签之一;我想这不是您想要的,但以防万一:这是代码和结果图:

ggplot(df,aes(x = year, y = value, group = country, colour = country) ) +
  geom_line(size = 1.3) +
  geom_text(data = df %>% filter(year == last(year)), 
            aes(label = country, x = year+0.5, y = value, color = country), 
            size = 3,
            check_overlap = TRUE) +    ###### Here is the change #######
    guides(color = FALSE) + 
  theme_bw() 

你可以看到,例如在最上面的 3 行中,缺少 EUR 的标签(由于 check_overlap,已设置为 'TRUE')。

作为替代方案,您可以使用以下代码。此处,geom_text()geom_text_repel 替换,参数保持不变。后一个函数根据小插图执行以下操作:

文本标签相互排斥并远离数据点。

以下代码...:

ggplot(df,aes(x = year, y = value, group = country, colour = country) ) +
geom_line(size = 1.3) +
geom_text_repel(data = df %>% filter(year == last(year)),  #### here ####
                aes(label = country, x = year+0.5, y = value, color = country), size = 3) +
guides(color = FALSE) + 
theme_bw()

... 生成以下图:

您可以通过稍微调整一下 hjustvjust 来调整结果,正如小插图所说:

  • 支持参数 hjust 和 vjust,但它们仅控制初始定位,因此排斥力可能会破坏对齐。如果标签仅通过使用 direction = "y" 上下移动,则将保留与 hjust 的对齐。对于 vjust,使用 direction = "x".

请告诉我这是否是您想要的。