How to annotate plots with placement independent of the x and y mappings?

798 views
Skip to first unread message

momeara

unread,
Mar 23, 2010, 11:48:51 AM3/23/10
to ggplot2
Hello,

Thank you all for creating a wonderful piece of software!

I would like to add text annotations to a plot. I believe geom_text
geom is close to what I want, however I would like the annotations to
be consistently located in the plot window regardless of the x and y
scales used to plot the data. I would like the annotation to work
something like an in-set legend rather then an aesthetic.

Is it possible to apply the inverse x and y scaling maps to get back
to the plot coordinates? Is there a way to access the x and y scaling
maps directly from a plot object? I could set the scales manually and
work out the transformation as a pre-processing, but I was hoping I
didn't have to.

I feel like there ought to be a more straight forward way do this.
- I've thought about trying to add subplots and then stripping
out everything but the legends however I couldn't figure out how to
make this approach work with facet_grid/facet_wrap.
- The annotate(text,...) layer also is transformed with the x and
y scaling maps so the coordinates are in the data space. And plus I
like the consistent association of the other aesthetics between the
data being plotted and the annotations (like the way the legends and
geom_text work by default).
- I don't know where to begin in adding true sub-legends by
digging into the ggplot2 code.
- I suppose I could overlay plot containing only the labeling by
using grid explicitly but this violates much of the beauty of ggplot2

This is extending an example from a response by Hadley back in
November: I would like the placement of the geom_text to end up in
exactly the same part of the window for both of these two plots--like
it was floating above the data. Instead they move around because the
limits and scale depend upon the data and the geom_text is anchored to
the data space coordinates:

##### geom_text puts correlation in upper right corner of window
examp1 <- data.frame(
X=rnorm(20)-4,
Y=rnorm(20)-4,
fact=rep(c("a","b"),each=10)
)
corr1 <- ddply(examp1, "fact", summarise, cor = cor(X, Y))
ggplot(examp1,aes(X,Y)) +
geom_point() +
geom_smooth(method="lm") +
geom_text(aes(1, 1, label = format(cor)), data = corr1) +
facet_grid(fact~.)


#### geom_text puts correlation in lower left corner of window
examp2 <- data.frame(
X=rnorm(20) + 4,
Y=rnorm(20) + 4,
fact=rep(c("a","b"),each=10)
)
corr2 <- ddply(examp2, "fact", summarise, cor = cor(X, Y))
ggplot(examp2,aes(X,Y)) +
geom_point() +
geom_smooth(method="lm") +
geom_text(aes(1, 1, label = format(cor)), data = corr2) +
facet_grid(fact~.)


Any insight will be appreciated,

Best,
Matt

baptiste auguie

unread,
Mar 23, 2010, 12:13:50 PM3/23/10
to momeara, ggplot2
Hi,

If you only aim at the corners of the plot, I think you can use Inf
(which automatically knows the limit of each panel),

ggplot(examp1,aes(X,Y)) +
geom_point() +
geom_smooth(method="lm") +

geom_text(aes(Inf, Inf, label = format(cor)), data = corr1, vjust=1,hjust=1) +
facet_grid(fact~.)


ggplot(examp2,aes(X,Y)) +
geom_point() +
geom_smooth(method="lm") +

geom_text(aes(-Inf, -Inf, label = format(cor)), data = corr2,
vjust=-1,hjust=0) +
facet_grid(fact~.)


HTH,

baptiste

> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> To post to this group, send email to ggp...@googlegroups.com
> To unsubscribe from this group, send email to
> ggplot2+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/ggplot2
>
> To unsubscribe from this group, send email to ggplot2+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>

Reply all
Reply to author
Forward
0 new messages