I often add text in plots. This text can be a legend or labeling certain points, in which case assigning it x and y coordinates are easy. Often times, the text is descriptive, e.g. the slope of a line or the number of observations in a sample. Customizing (x,y) coordinates in that case is simple for only one graph. It becomes complicated, however, when automatically creating many graphs with different sets of data, as the range of the coordinates will vary.
For the longest time, I’ve used custom calculations based on the maximum values of x and y, but this process if fragile. Instead, I recently discovered that R will tell you the coordinates of the plot window, using par(‘usr’). You can save these coordinates and then call them when you want to place the text. Sample code is below:
pdf(paste0('Figures/', fileOut, '.pdf')) par(mar=c(5,4,.5,2), cex=1.5) plot(population, protestors, ylab='Protesters', xlab='City Population', pch=20, col='grey70', yaxt='n', xaxt='n') window_coords <- par('usr') # Will give plot margin coordinates as x_min, x_max, y_min, y_max axis(2, at=yticks, labels=ylabels) axis(1, at=xticks, labels=xlabels) abline(a=model$coefficients[1], b=model$coefficients[2], col='black', lwd=3) text(x=window_coords[1], y = window_coords[4]*.9, paste('Slope: ', round(model$coefficients[2], 2)), pos=4) text(x=window_coords[1], y = window_coords[4]*.85, bquote(R^2 == .(round(summary(model)$r.squared, 2))), pos=4) text(x=window_coords[1], y = window_coords[4]*.8, paste('Protests: ', length(protestors)), pos=4) dev.off()
par(‘usr’) doesn’t solve all of my problems. If plotting multiple lines of text, I need to decide on a vertical offset, and the appropriateness of that offset will vary by the range of x and y. But it is much simpler to write than something like
max(x, na.rm)*[some factor]
because it is the maximum boundaries of the window, not the range of each dimension.