How do you draw a line in a multi-valued environment in R?

Take a very simple example, mfrow=c(1,3) ; each figure represents a different histogram; how would I draw a horizontal line (akin to abline(h=10) ) that intersected all 3 digits? (That is, even the margins between them.) Obviously, I could add an abline for each shape, but that’s not what I want. I can come up with a very complicated way to do this, actually having only one shape and drawing each shape inside it with polygon , etc. That would be funny. Is there an easy way to do this?

+8
r graph
Apr 02 2018-12-12T00:
source share
3 answers

As @joran noted, the grid graphical system offers more flexible control over the location of multiple graphs on a single device.

Here I first use grconvertY() to query the location of a height of 50 along the y axis in units of "normalized device coordinates". (i.e., as a percentage of the total height of the plotter, with 0 = bottom and 1 = top). Then I use the grid functions to: (1) click the viewport that populates the device; and (2) draw a line at the height returned by grconvertY() .

 ## Create three example plots par(mfrow=c(1,3)) barplot(VADeaths, border = "dark blue") barplot(VADeaths, border = "yellow") barplot(VADeaths, border = "green") ## From third plot, get the "normalized device coordinates" of ## a point at a height of 50 on the y-axis. (Y <- grconvertY(50, "user", "ndc")) # [1] 0.314248 ## Add the horizontal line using grid library(grid) pushViewport(viewport()) grid.lines(x = c(0,1), y = Y, gp = gpar(col = "red")) popViewport() 

enter image description here

EDIT : @joran asked how to build a line that extends from the Y axis of the 1st section to the edge of the last strip in the 3rd section. Here are a few alternatives:

 library(grid) library(gridBase) par(mfrow=c(1,3)) # barplot #1 barplot(VADeaths, border = "dark blue") X1 <- grconvertX(0, "user", "ndc") # barplot #2 barplot(VADeaths, border = "yellow") # barplot #3 m <- barplot(VADeaths, border = "green") X2 <- grconvertX(tail(m, 1) + 0.5, "user", "ndc") # default width of bars = 1 Y <- grconvertY(50, "user", "ndc") ## Horizontal line pushViewport(viewport()) grid.lines(x = c(X1, X2), y = Y, gp = gpar(col = "red")) popViewport() 

enter image description here

Finally, here is an almost equivalent and more accessible approach. It uses the functions grid.move.to() and grid.line.to() demo'd by Paul Murrell in an article related to @mdsumner's answer:

 library(grid) library(gridBase) par(mfrow=c(1,3)) barplot(VADeaths); vps1 <- do.call(vpStack, baseViewports()) barplot(VADeaths) barplot(VADeaths); vps3 <- do.call(vpStack, baseViewports()) pushViewport(vps1) Y <- convertY(unit(50,"native"), "npc") popViewport(3) grid.move.to(x = unit(0, "npc"), y = Y, vp = vps1) grid.line.to(x = unit(1, "npc"), y = Y, vp = vps3, gp = gpar(col = "red")) 
+13
Apr 03 '12 at 1:17
source share

This is the best I can do without thinking more complicated:

 par(mfrow = c(1,3),xpd = NA) for (i in 1:3){ x <- rnorm(200,i) hist(x) if (i == 1) segments(par("usr")[1],10,30,10) } 

enter image description here

I'm not sure how to make sure the line ends in the right place without messing around. Calculation of a segment in each region would solve this problem, but we introduce the problem of proper leveling. But that could be a good starting point, at least.

I would suggest that this is easier on the grid graph, but I would have to do some research to verify.

+6
Apr 02 '12 at 23:23
source share

This article by Paul Merrell shows the use of grid graphics to draw lines between two different coordinate systems, in this case lines that have endpoints indicated in the source space of two separate subheadings:

Paul Murrell. Graphic mesh package. R News, 2 (2): 14-19, June 2002

This is on page 17 of the article in PDF format:

http://cran.r-project.org/doc/Rnews/Rnews_2002-2.pdf

+4
Apr 2 2018-12-12T00:
source share



All Articles