Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix the geom_text label position so it is always on the middle of the plot?

Tags:

r

ggplot2

I would like to create a function that produce a ggplot graph.

data1 <- data.table(x=1:5, y=1:5, z=c(1,2,1,2,1))
data2 <- data.table(x=1:5, y=11:15, z=c(1,2,1,2,1))

myfun <- function(data){
    ggplot(data, aes(x=x, y=y)) +
        geom_point() +
        geom_text(aes(label=y), y=3) +
        facet_grid(z~.)
}

myfun(data2)

It is supposed to label some text on the graph. However, without knowing the data in advance I am unable to adjust the positions of text vertically manually. Especially I don't want the label to move positions with data: I want it always stays at about 1/4 vertically of the plots. (top-mid)

How can I do that?

Is there a function that returns the y.limit.up and y.limit.bottom then I can assign y = (y.limit.up + y.limit.bottm) / 2 or something.

like image 702
colinfang Avatar asked Nov 22 '13 18:11

colinfang


1 Answers

Setting either x or y position in geom_text(...) relative to the plot scale in a facet is actually a pretty big problem. @agstudy's solution works if the y scale is the same for all facets. This is because, in calculating range (or max, or min, etc), ggplot uses the unsubsetted data, not the data subsetted for the appropriate facet (see this question).

You can achieve what you want using auxiliary tables, though.

data1 <- data.table(x=1:5, y=1:5, z=c(1,2,1,2,1))
data2 <- data.table(x=1:5, y=11:15, z=c(1,2,1,2,1))

myfun <- function(data){
    label.pos <- data[,ypos:=min(y)+0.75*diff(range(y)),by=z] # 75% to the top...

    ggplot(data, aes(x=x, y=y)) +
        geom_point() +
    #   geom_text(aes(label=y), y=3) +
        geom_text(data=label.pos, aes(y=ypos, label=y)) +
        facet_grid(z~., scales="free")     # note scales = "free"
}

myfun(data2)

Produces this.

enter image description here

If you want scales="fixed", then @agstudy's solution is the way to go.

like image 132
jlhoward Avatar answered Oct 02 '22 09:10

jlhoward