Home > Software engineering >  How to horizontally align repelled labels for overlapping points
How to horizontally align repelled labels for overlapping points

Time:04-13

Data:

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")

Code:

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

Result: enter image description here

The default placement of the labels by ggrepel results in a messy look even though the points are quite regularly aligned vertically, so I've tried to arrange the labels in more orderly fashion on the right hand-side. The points labelled "2005-2009" and "2000-2004" overlap almost completely so I've set direction="both" in geom_text_repel to avoid overcrowding labels on the right hand-side. I've also set min.segment.length=Inf because drawing segments adds unnecessary clutter for only 5 data points. I wish to align "2005-2009" horizontally with its data point, but tweaking nudge_x, hjust and vjust values fails to do that.

CodePudding user response:

For these data, geom_text_repel might be overkill. You can achieve similar spacing with geom_label. Only the "2005-2009" data point needs a different horizontal alignment from the rest, which can be be accomplished through the hjust parameter:

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

enter image description here

  • Related