user1424739
user1424739

Reputation: 13735

How to put text with respect to plot/figure/device region in terms of coordinate from 0 to 1?

https://bootstrappers.umassmed.edu/bootstrappers-courses/pastCourses/rCourse_2014-09/resources/helpfulGuides/Rfigurelayout.pdf

The above doc shows plot region, figure region, and device region.

Suppose these regions are mentally mapped to coordinates from 0 (the bottom or the left) to 1 (the top or the right). How to put text in this definition of coordinates on these three regions in basic R, respectively?

Upvotes: 2

Views: 394

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174278

I think what you are asking is how to place text anywhere in the plotting window, using proportional device co-ordinates. This is actually how text works in the grid graphic system:

library(grid)

grid.newpage()

grid.draw(rectGrob(gp = gpar(lwd = 2)))
grid.draw(textGrob("(0.1, 0.1)", 0.1, 0.1, gp = gpar(cex = 2, col = "red2")))
grid.draw(textGrob("(0.5, 0.5)", 0.5, 0.5, gp = gpar(cex = 2, col = "blue")))
grid.draw(textGrob("(0.9, 0.9)", 0.9, 0.9, gp = gpar(cex = 2, col = "green2")))

However, if you want to do the same thing in base R graphics, I think you would need to write a wrapper around text that queries the graphics device and converts your device space co:ordinates to user co-ordinates, then draws the text with clipping off.

Here is such a function (called dtext to denote "device text")

dtext <- function(x = 0.5, y = 0.5, label, ...) {
  margins <- par("omi") + par("mai")
  plotsize <- par("pin")
  devsize  <- dev.size()
  usr_space <- par("usr")
  usr_y <- devsize[2] / plotsize[2] * (diff(usr_space[3:4]))
  y_min <- usr_space[3] - usr_y * margins[1]/devsize[2]
  
  usr_x <- devsize[1] / plotsize[1] * (diff(usr_space[1:2]))
  x_min <- usr_space[1] - usr_x * margins[2]/devsize[1]
  
  text(x = x * usr_x + x_min,
       y = y * usr_y + y_min,
       label = label,
       xpd = NA,
       ...)
}

This allows:

plot(1:10, 1:10)

dtext(x = 0.1, y = 0.1, label = "(0.1, 0.1)", cex = 2, col = "red2")
dtext(x = 0.5, y = 0.5, label = "(0.5, 0.5)", cex = 2, col = "blue2")
dtext(x = 0.9, y = 0.9, label = "(0.9, 0.9)", cex = 2, col = "green2")

This seems like a pretty useful function, and I'm surprised it doesn't exist already, so thanks for the OP.

Created on 2022-04-02 by the reprex package (v2.0.1)

Upvotes: 2

Related Questions