1

If you don't know how to put text (using the text function so it can be more freely edited, not the legend function) at the top of each subplot in R when the coordinates vary and you don't know the y max or x max (e.g. for a histogram where you don't know the frequency in advance) how do you do it?

Addendum: Also, mtext uses margins, I am speaking of coordinate space here, not margin space.

jimh
  • 1,651
  • 2
  • 15
  • 28
  • Re: your addendum: But if you give pass `mtext` a negative value in the `line` argument, it goes inside the coordinate space. Is this a problem? If so, why? – Gregor Thomas Jan 21 '15 at 23:11
  • Because you need to know in advance where the subplots will lie in regards to the margins. I want this process to be automated, not something I have to play around with. Mtext refers to the device margins not the plot coordinate space. – jimh Jan 21 '15 at 23:17
  • [possible dup](http://stackoverflow.com/questions/7322301/get-plot-bounding-box-values) – rawr Jan 21 '15 at 23:26
  • @rawr didn't notice that. didn't turn up in my searches of the site. I found it searching the R manual instead. – jimh Jan 21 '15 at 23:29

2 Answers2

3

You can use par ('usr'). It gives you the current coordinates of the plot. Really useful if you want text in a certain area of each subplot and you don't know the coordinates in advance (e.g. a histogram). The output looks like:

par('usr')
[1] -0.28  7.28 -3.00 78.00

wherein the x min is the first member of the list, the x max is the second, the y min is the third, and the y max is the fourth. You can treat par('usr') like a vector in R and if you want it to be in the top left you can do, say:

text(par('usr')[1]+2,.9*par('usr')[4],labels="blahblah")

From this it will be plotted in the upper 10% of the plot and +2 from the leftmost coordinate of the plot space. Of course you can adjust this, but that would be top left more or less.

Using this code for my data:

y <- rnorm(100)
z <- rnorm(100)
par(mfrow = c(1,2))
hist(y, breaks = 30)
text(.8 * par('usr')[2], .9 * par('usr')[4], labels = paste("mean:", round(mean(y), 2)))
text(.8 * par('usr')[2], .86 * par('usr')[4], labels = paste("median:", round(median(y), 2)))
hist(z, breaks = 30)
text(.8 * par('usr')[2], .9 * par('usr')[4], labels = paste("mean:", round(mean(z), 2)))
text(.8 * par('usr')[2], .86 * par('usr')[4], labels = paste("median:", round(median(z), 2)))
mtext("distributions", side = 3, line = -2, outer = TRUE, col = 2) # added mtext to show how I would use it to create a title

I got this image:

myplot

jimh
  • 1,651
  • 2
  • 15
  • 28
  • @rawr can you be a little more specific? – jimh Jan 21 '15 at 23:27
  • It's a much better answer! But reproducible would be nice. It's not reproducible because no one else has your data file. It would be a friendlier answer if you used a built-in data set or some simulated data. For whitespace, it'seasiertoreadcodeifyouuseyourspacebar ;) – Gregor Thomas Jan 21 '15 at 23:49
  • For more reproducibility tips, you can [see here](http://stackoverflow.com/q/5963269/903061). The ideal way to ask a question is to put data *in the question*, that way anyone who tries to answer has something to test on. – Gregor Thomas Jan 21 '15 at 23:51
  • @Gregor ah, fair enough, I will use like rnorm(100) or something. – jimh Jan 22 '15 at 07:24
1

Assuming you want the text inside the plot region, you can use legend, and specify the position by keyword (see details in ?legend):

par(mfrow=c(2, 2))
sapply(1:4, function(i) {
  plot(runif(10))
  legend('top', paste('Plot', i), bty='n', text.font=2)
})

enter image description here

You could also use mtext:

mtext(paste('Plot', i), 3, line = -1.5)
jbaums
  • 27,115
  • 5
  • 79
  • 119
  • Yes the way to paste text was not the problem as much as posting it in coordinate space while being able to freely edit it - and mtext and legend have some limitations in that regard. But thanks. That is still another way to do that. – jimh Jan 21 '15 at 22:51
  • @Gregor sure thing I will try to make it more specific...maybe specifying that i want to do it with text not legend. – jimh Jan 21 '15 at 22:56
  • @Gregor in the past there were certain pch characters I found I could add to a text box in R that could not be easily added to a legend the same way and so I prefer using the baser functions that can be more freely edited in my case just in case I want to add more things later. There are limitations - though not many to what can be placed in a legend versus a text box. Also, is that edit to the answer better? – jimh Jan 21 '15 at 23:16
  • 1
    @semjaavria No problem - I agree that using `text` with `par('usr')` is generally a more flexible approach. I just posted this to provide alternatives. :) – jbaums Jan 22 '15 at 01:11
  • hey man thanks for the answer, it is a different way to look at it that is useful with the legend. just not what I specifically was looking for. however, I bet most people who come to this question will prefer your answer. – jimh Jan 22 '15 at 07:26