如何水平对齐重叠点的排斥标签

How to horizontally align repelled labels for overlapping points

数据:

df <- structure(list(interval = c("1990-1994", "1995-1999", "2000-2004", 
"2005-2009", "2010-2014"), G = c(82.2047540759008, 66.8830947511929, 
60.8452885555918, 60.815015015015, 56.9713761985336), I = c(0.0816584033395321, 
0.0878634449241925, 0.0880830474237161, 0.0808069481620484, 0.0871282403928035
)), row.names = c(NA, -5L), class = "data.frame")

代码:

library(ggplot2)
library(ggrepel)

#Set label text size
ts=6

#Define theme
pt <- theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_blank(), 
            panel.background=element_blank(), panel.border=element_rect(fill=NA, colour="black"), 
            axis.line=element_line(colour="black"), axis.title=element_blank(), axis.ticks = element_blank(), 
            axis.text=element_blank(), aspect.ratio=1)

#Generate plot
ggplot(df, aes(x=I, y=G/100, label=interval)) + geom_point() + 
  geom_text_repel(aes(label=interval), size=ts, direction="both", min.segment.length=Inf, nudge_x=.06, hjust=0) + 
  scale_x_continuous(limits=c(-1,1), breaks=c(-1,0,1), labels=c("", 0, ""), expand=c(0,0)) + 
  scale_y_continuous(limits=c(0,1), breaks=c(0,.5,1), expand=c(0,0)) + 
  geom_hline(yintercept=0.5) + geom_vline(xintercept=0) + 
  annotate("text", size=ts, x=0.02, y=0.03, label="0", hjust=0) + 
  annotate("text", size=ts, x=0.97, y=0.03, label="I", hjust=1, fontface="italic") + 
  annotate("text", size=ts, x=0.02, y=0.47, label="0.5", hjust=0) + 
  annotate("text", size=ts, x=0.02, y=0.97, label="G", hjust=0, fontface="italic") + pt

结果:

ggrepel 标签的默认放置会导致外观混乱,即使这些点在垂直方向上非常规则地对齐,所以我尝试在右侧以更有序的方式排列标签 -边。标记为“2005-2009”和“2000-2004”的点几乎完全重叠,所以我在 geom_text_repel 中设置了 direction="both" 以避免右侧标签过度拥挤。我还设置了 min.segment.length=Inf,因为绘图段只为 5 个数据点添加了不必要的混乱。 我希望将“2005-2009”与其数据点水平对齐[=29​​=],但调整 nudge_xhjustvjust 值无法做到这一点。

对于这些数据,geom_text_repel 可能有些矫枉过正。您可以使用 geom_label 实现类似的间距。只有“2005-2009”数据点需要与其他数据点不同的水平对齐方式,这可以通过 hjust 参数来实现:

ggplot(df, aes(x=I, y=G/100, label=interval)) + geom_point() + 
  geom_label(aes(label=interval, hjust = ifelse(interval == '2005-2009', 1, 0)), size=ts, label.padding = unit(0.3, "lines"), fill = NA, label.size = NA) +
  scale_x_continuous(limits=c(-1,1), breaks=c(-1,0,1), labels=c("", 0, ""), expand=c(0,0)) + 
  scale_y_continuous(limits=c(0,1), breaks=c(0,.5,1), expand=c(0,0)) + 
  geom_hline(yintercept=0.5) + geom_vline(xintercept=0) + 
  annotate("text", size=ts, x=0.02, y=0.03, label="0", hjust=0) + 
  annotate("text", size=ts, x=0.97, y=0.03, label="I", hjust=1, fontface="italic") + 
  annotate("text", size=ts, x=0.02, y=0.47, label="0.5", hjust=0) + 
  annotate("text", size=ts, x=0.02, y=0.97, label="G", hjust=0, fontface="italic") + pt