0

Code example
Let me take this little example:

example.data <- data.frame(
  x = seq(1,5),
  y = c(seq(1,3), 4.1, 4.11),
  y.label = letters[1:5]
)


library(ggplot2)
ggplot(example.data, aes(x=x, y = y)) + 
  geom_point() +
  scale_y_continuous(breaks = example.data$y, labels = example.data$y.label)

Since 4.1 and 4.11 are extremely close to one another the labels will overlap:

enter image description here

Info
I plot a very similar graph for a publication and do not want to increase the size of the figure just to make the labels fit (which would require the plot to be very large). I'm familiar with ggrepel, but as far as I know this only works for text annotation within the plot itself and not for axis.

Question
How can I make sure that the labels do not overlap without having to increase the size of the whole plot?

jay.sf
  • 60,139
  • 8
  • 53
  • 110
CodeNoob
  • 1,988
  • 1
  • 11
  • 33
  • Is the y-axis really a categorial variable? In the case of this example, I would switch the two axis, which would also be a more natural way of displaying the data. Like this `ggplot(example.data, aes(x=y.label, y = y)) + geom_point()` – hannes101 Feb 14 '19 at 13:11

2 Answers2

1

I'd rather do it this way. Draw one normal plot and a second magnified version. Then overlay them using this solution.

p1 <- ggplot(example.data, aes(x=x, y = y)) + 
  geom_point() + 
  scale_y_continuous(breaks = example.data$y[1:4], labels = example.data$y.label[1:4])

p2 <- ggplot(example.data, aes(x=x, y = y)) + 
  geom_point() + 
  xlim(3.9, 5.1) + 
  scale_y_continuous(breaks=seq(4.100, 4.111, .002), labels=c("d", rep("", 4), "e"),
                     limits=c(4.1, 4.111))

vp <- grid::viewport(width=0.4, height=0.15, x=.8, y=.4)

png("plot.png")
print(p1)
print(p2, vp=vp)
dev.off()

Result

enter image description here

It becomes even clearer with a reader's guide:

library("ggforce")
p1 <- p1 + geom_circle(aes(x0=4.5, y0=4.2, r=.7), 
                       inherit.aes=FALSE, linetype=2) +
  geom_segment(aes(x=4.5, y=2.5, xend=4.5, yend=3.5),
               size=1, arrow=arrow(length=unit(0.5, "cm")))

Refined result

enter image description here

Note: Of course you can still refine that, just to get you the idea.

jay.sf
  • 60,139
  • 8
  • 53
  • 110
1

I would suggest a different plot for this problem:

ggplot(example.data, aes(x=y.label, y = y)) + 
    geom_point() +
    geom_hline(yintercept = 4.1) +
    geom_text(aes(0,4.1,label = 4.1,hjust=-1,  vjust = -0.5))

Changed axis plot

hannes101
  • 2,410
  • 1
  • 17
  • 40