I have a framed plot with a title. I was wondering if there is a quick and easy way to put also a frame around the (main) title of plot.
The frame should have the same width as the frame around the plot. Is there also a way to adjust the height of the frame?
I would like to stick to the generic plot function.
# Some example data
x <- rnorm(10)
y <- rnorm(10)
# Plot data and add title
plot(x,y,
xlab = "",
ylab = "",
frame = TRUE
)
title( main = "This should be framed")
Many thanks and a nice weekend to everybody!
One possibility is to use rect
.
First use par("usr")
to get "the extremes of the user coordinates of the plotting region".
Because you want that the "frame should have the same width as the frame around the plot", the x-positions are straightforward: use the first and second values of the 'user coordinates' as xleft
and xright
.
The bottom and top positions of the rect
require some more work. The y position of the title
"defaults to being vertically centered in (outer) margin 3" (?title
). Use par("mai")
to get the margins in inches. Calculate the midpoint of the top y margin by dividing margin 3 by 2 (par("mai")[3] / 2
). Define a height of the frame to e.g. 0.5, which corresponds to halfway between the center of the title and the border of the figure region and the plot region respectively.
To convert from inches to user coordinates, use grconvertY
. That is, we multiply the value in inches by diff(grconvertY(y = 0:1, from = "inches", to = "user"))
(see e.g. here). This value is then added to the upper user coordinate of y (coord[4]
).
coord <- par("usr")
y_mid <- par("mai")[3] / 2
height <- 0.5
conv <- diff(grconvertY(y = 0:1, from = "inches", to = "user"))
rect(xleft = coord[1],
xright = coord[2],
ybottom = coord[4] + (y_mid * (1 - height) * conv),
ytop = coord[4] + (y_mid * (1 + height) * conv),
xpd = TRUE)
The grid graphical system has much better facilities for handling units, so I'd be tempted to use the gridBase package to "step into" a graphical system in which the rectangle's shape and position can be more directly named. Here's what that might look like:
library(grid)
library(gridBase)
## Standard idiom for setting your frame of reference to be that of the base R plot's frame
lapply(baseViewports(), pushViewport)
## Draw a rectangle centered 2 lines above frame and 1.5 lines of text in height
grid.rect(y = unit(1,"npc") + unit(2, "lines"),
height = unit(1.5, "lines"), just = "center")
Unlike Henrik's base R solution, this won't require you to fiddle around by hand for each plot, experimenting until you get the rectangle's y-coordinates just right.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With