4

Possible Duplicate:
finding the bounding box of plotted text

I've got a simple plot to which I've added some text to the plotting region; I'd like to put a border around this text. Is there a way to get the boundaries of the actual text so that I can use these for the plotting of the rectangle, or do I just need to use trial and error to make the rectangle look about right?!

At the moment, my code is:

plot(dep, eqt[,1], type="l")
text(12,200,"A notes about this plot!", font=2, cex=2)
rect(10,140,14,260)
Community
  • 1
  • 1
ChrisW
  • 4,970
  • 7
  • 55
  • 92

3 Answers3

6

You can use strheight and strwidht to estimate that height and width of text.

Health warning: strheight and strwidth estimates text size in the current plot device. If you subsequently resize the plot, the R may resize the text automatically, but the rectangle will not resize. This is fine for interactive plots, but may cause problems when you save the plot to disk using png(); plot(...); dev.off()

x <- 1:300
y <- 1:300
plot(x, y, type="l")

txt <- "A note about this plot!"
rwidth <- strwidth(txt, font=2, cex=2)
rheight <- strheight(txt, font=2, cex=2)

tx <- 150
ty <- 100

text(tx, ty,txt, font=2, cex=2, col="blue", offset=1)

rect(tx-0.5*rwidth, ty-0.5*rheight, tx+0.5*rwidth, ty+0.5*rheight)

enter image description here

Andrie
  • 176,377
  • 47
  • 447
  • 496
2

The plotrix package has a function textbox() that might be useful to you. Try something like this:

require(plotrix)
txt <- "Some notes about this plot"
plot(1:5)
textbox(x = c(1, 1 + 1.1*strwidth(txt)),
        y = 4,
        textlist = txt)
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • This also looks like an interesting solution.. does it overcome the problem that Andrie warned about when using strwidth / strheight? – ChrisW Oct 11 '11 at 18:16
  • It seems to work fine, and I don't see why it wouldn't. I didn't quite follow why an issue that affects **interactive** resizing would be a problem when you plot to one of the **non-interactive** plot devices. (But I'd be interested to hear why it would). – Josh O'Brien Oct 11 '11 at 18:26
  • This does indeed have the same issue. The issue I highlight is not about interactive use per se. It's that the textbox sizing is calculated using the current plot device. If you subsequently print to a plot device and specify height and width that happens to be different from your current plot device, the box will no longer be the correct size. – Andrie Oct 11 '11 at 19:53
  • 1
    But it shouldn't be a problem if you do: `png("eg.png"); plot(...); dev.off()`, where "`plot(...)`" is all of the commands in my code box above, right? Because in that case, the device that's active when the widths etc are calculated will be the appropriate one (i.e. the one opened by `png()`). I guess the kind of issue you're referring to is why I long ago banished `dev.copy()` from my R lexicon! – Josh O'Brien Oct 11 '11 at 20:02
0

For maximum control, the grid package could also be used. In particular, grobs can be drawn at the time of rendering on the device, ensuring that resizing of the device is taken into account. The gridBase package provides functions to mix base and grid graphics.

An example with grid.table which has a drawDetails method,

 library(gridBase)
 library(gridExtra)

 par(oma=rep(1, 4), mfrow=c(1, 2), xpd=NA)
 plot(1:10, 1:10)
 vps <- baseViewports()
 pushViewport(vps$inner)
 pushViewport(vps$figure)
 pushViewport(vps$plot)
 ## grid.rect(gp=gpar(lwd=3, col="blue"))
 grid.table(expression("this is an expression"*integral(f(x)*dx, alpha, beta)),
            parse=TRUE, theme=theme.white(show.box=TRUE, separator = "red",
                          show.rownames = FALSE, show.colnames = FALSE))
 upViewport(0)
baptiste
  • 75,767
  • 19
  • 198
  • 294