David Hewitt
2009-Jan-27 21:47 UTC
[R] Plotmath and line breaks in long annotations for plots
I'm trying to combine multi-line text and math annotations on a plot
and am not having much luck. I looked at various suggestions in the
archives, but I cannot coerce any of them to do what I want. I'm
beginning (finally?!) to think that there is an entirely better
approach than the one I have tried.
The essential problem is that line breaks (\n) don't seem to behave
the way I expected when combined with text strings and plotmath in a
call to text(). My vision for the annotation, which may be a little
beyond the norm, is to have a series of centered lines of text
somewhere on the plot that includes various object values and symbols.
I'd like to wrap it all up in one call to text() so that it has a
common anchor. Here is an example:
a <- c(1, 10)
b <- c(1, 10)
amean <- mean(a)
bmean <- mean(b)
plot(a, b)
# Annotation with paste()
text(amean, bmean,
bquote(paste("Here are the values\nI want to write on the
plot\n\n",
amean==.(amean), "\nand\n", bmean==.(bmean))))
# Annotation without paste()
text(amean, bmean,
bquote('Here are the values\nI want to write on the
plot\n\n'~amean==.(amean)~'\nand\n'~bmean==.(bmean)))
Another suggestion in the archives involved creating a list with the
strings that were then passed through parse(), but that did not work
either.
Corrections, suggestions, or redirections greatly appreciated.
--
Dave Hewitt
Research Fishery Biologist
US Geological Survey, Klamath Falls, OR, USA
Marc Schwartz
2009-Jan-27 22:49 UTC
[R] Plotmath and line breaks in long annotations for plots
on 01/27/2009 03:47 PM David Hewitt wrote:> I'm trying to combine multi-line text and math annotations on a plot > and am not having much luck. I looked at various suggestions in the > archives, but I cannot coerce any of them to do what I want. I'm > beginning (finally?!) to think that there is an entirely better > approach than the one I have tried. > > The essential problem is that line breaks (\n) don't seem to behave > the way I expected when combined with text strings and plotmath in a > call to text(). My vision for the annotation, which may be a little > beyond the norm, is to have a series of centered lines of text > somewhere on the plot that includes various object values and symbols. > I'd like to wrap it all up in one call to text() so that it has a > common anchor. Here is an example: > > a <- c(1, 10) > b <- c(1, 10) > amean <- mean(a) > bmean <- mean(b) > > plot(a, b) > > # Annotation with paste() > text(amean, bmean, > bquote(paste("Here are the values\nI want to write on the plot\n\n", > amean==.(amean), "\nand\n", bmean==.(bmean)))) > > # Annotation without paste() > text(amean, bmean, > bquote('Here are the values\nI want to write on the > plot\n\n'~amean==.(amean)~'\nand\n'~bmean==.(bmean))) > > Another suggestion in the archives involved creating a list with the > strings that were then passed through parse(), but that did not work > either. > > Corrections, suggestions, or redirections greatly appreciated.The root issue is that plotmath does not support newlines within the expressions to be output. You really need to create and output each line separately. As you will see below, it is possible to do it with a single call to text(). One can use the function strheight() to get a sense (in plot region user coordinates) as to how high a line of text would be. Then you can adjust the subsequent lines based upon this value. For example: a <- c(1, 10) b <- c(1, 10) amean <- mean(a) bmean <- mean(b) plot(a, b) # See ?strheight hght <- strheight("Here") # How high is a line of text?> hght[1] 0.2264324 Lines <- list("Here are the values", "I want to write on the plot", "", bquote(amean == .(amean)), "and", bquote(bmean == .(bmean))) # Now output each line # The text in the list is converted to expressions # using do.call(expression, Lines) # Adjust the y position value based upon multiplying 'hght' # by 1:4 and a scale adjustment (1.5) for spacing # subtract that from 'bmean' to place each line below # the prior one text(amean, bmean - (hght * 1.5 * seq(length(Lines))), do.call(expression, Lines)) HTH, Marc Schwartz