Position ggplot text in each corner

2020-02-26 05:22发布

问题:

I've got a scatter plot with a horizontal and a vertical line, which depict thresholds values, and therefore they divide the plot into four quadrants. I'd like to label the quadrants. I think the best way to do this would be a number in each of the four corners of the graph (alternative suggestions are welcome!).

I've managed to put a text into the corner of each quadrant, but the positions are not perfect. I assume that the problem has to do with the fact that the scaling of the axes is different (the range of values is about the same, but the width of my figure is about three times the height).

Currently I proceed the following way. First I create the graph with the points and the two lines, then I build it in order to get the range of the two axes, which I use in order to adjust the position of the texts.

plot.build = ggplot_build(plot)

xpos = numeric(4)
xpos[2] = xpos[3] = plot.build$panel$ranges[[1]]$x.range[1]
xpos[1] = xpos[4] = plot.build$panel$ranges[[1]]$x.range[2]

ypos = numeric(4)
ypos[1] = ypos[2] = plot.build$panel$ranges[[1]]$y.range[2]
ypos[3] = ypos[4] = plot.build$panel$ranges[[1]]$y.range[1]


plot = plot + geom_text(aes(x2,y2,label = texthere), 
                    data.frame(x2=xpos, y2=ypos, texthere=c("1", "2", "3", "4")),
                    color="#4daf4a", size=4)

Basically this works, but due to the scaling the space between the numbers and the borders of the plot are not the same for both axes. I've tried to adjust the x position of the text, but then ggplot just expands the range of values, the positions (relative to the borders) stay the same. Is there a way to move the text without changing the range of values?

Thanks in advance!

回答1:

This example uses the Inf & -Inf values to position the text at the corners and then hjust and vjust arguments in the geom_text to position the text inside the plot. Use the hjustvar and vjustvar to position them further into or outside the plot.

As mentioned by @baptiste it's best to use a new data set for the annotations

df <- data.frame(x2=rnorm(100),y2=rnorm(100));library(ggplot2)

annotations <- data.frame(
        xpos = c(-Inf,-Inf,Inf,Inf),
        ypos =  c(-Inf, Inf,-Inf,Inf),
        annotateText = c("Bottom Left (h0,v0)","Top Left (h0,v1)"
                        ,"Bottom Right h1,v0","Top Right h1,v1"),
        hjustvar = c(0,0,1,1) ,
        vjustvar = c(0,1,0,1)) #<- adjust


  ggplot(df, aes(x2, y2)) + geom_point()+
            geom_text(data=annotations,aes(x=xpos,y=ypos,hjust=hjustvar,vjust=vjustvar,label=annotateText))

If we wanted to change any of the text positions, we would adjust the horizontal positions with hjustvar and the vertical positions with vjustvar.

# How To Adjust positions (away from corners)
annotations$hjustvar<-c(0,  -1.5,  1,  2.5)  # higher values = right, lower values = left 
annotations$vjustvar<-c(0,1,0,1) # higher values = up, lower values = down 

ggplot(df, aes(x2, y2)) + geom_point()+
        geom_text(data = annotations, aes(x=xpos,y=ypos,hjust=hjustvar,
                                          vjust=vjustvar,label=annotateText))

Hope this works!



回答2:

when adding annotations, make sure to give a new data set, or to use annotate, otherwise multiple labels will be superimposed giving a jagged look. Here's a minimal change from the other answer,

df <- data.frame(x2=rnorm(100),y2=rnorm(100))
library(ggplot2)

annotations <- data.frame(
   xpos = c(-Inf,-Inf,Inf,Inf),
   ypos =  c(-Inf, Inf,-Inf,Inf),
   annotateText = c("Text","tExt","teXt","texT"),
   hjustvar = c(0,0,1,1) ,
   vjustvar = c(0,1.0,0,1))


  ggplot(df, aes(x2, y2)) + geom_point()+
  geom_text(data = annotations, aes(x=xpos,y=ypos,hjust=hjustvar,
                vjust=vjustvar,label=annotateText))



标签: r ggplot2