2012-04-02 27 views
8

Weź bardzo prosty przykład: mfrow=c(1,3); każda figura jest innym histogramem; jak narysować linię poziomą (podobną do abline(h=10)), która przechodziła przez wszystkie liczby? (To znaczy, nawet margines między nimi.) Oczywiście, mogę dodać abline do każdej figury, ale to nie jest to, czego chcę. Mogę wymyślić bardzo skomplikowany sposób zrobienia tego przez naprawdę tylko o 1 figurze i rysowaniu każdej "figury" w niej przy użyciu polygon itd. To byłoby śmieszne. Czy nie ma łatwego sposobu na zrobienie tego?Jak narysować linię w środowisku wielowymiarowym w R?

Odpowiedz

13

Jak @joran zauważono, siatki układ graficzny oferuje bardziej elastyczne kontrola nad wieloma działkami na jednym urządzeniu.

Tutaj, po raz pierwszy używam grconvertY() do sprawdzenia lokalizacji o wysokości 50 na osi Y w jednostkach "znormalizowane współrzędne urządzenia". (tj. w stosunku do całkowitej wysokości urządzenia kreślarskiego, gdzie 0 = dół, a 1 = góra). Następnie używam funkcji grid, aby: (1) wcisnąć viewport, który zapełnia urządzenie; i (2) wykreślić linię na wysokości zwróconej przez 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 zapytał, jak wykreślić linię, która rozciąga się od osi y 1. działki do krawędzi ostatniego baru w 3 działki. Oto kilka alternatyw:

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

Wreszcie, oto prawie odpowiednik, a bardziej ogólnie użyteczne podejście.Zatrudnia ona funkcje grid.move.to() i grid.line.to() demo'd Paul Murrell w artykule związanej w odpowiedzi @ mdsumner za:

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")) 
+0

+1 Nice! Czy znasz sposób masażu jednostek/współrzędnych/przycinania tak, że linia rozciąga się od lewej najbardziej osi y do prawej krawędzi zielonych pasków? – joran

+0

Mam pomysł, a dodam go, jeśli się uda. W tej chwili mam zamiar skoszczyć trawnik przed zachodem słońca ... –

+0

Dzięki, to jest naprawdę pomocne! Doceniam twoją chęć odroczenia koszenia trawnika na moim koncie ;-) – gung

6

To jest najlepsze, co mogę zrobić, nie myśląc o tym trudniej:

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

Nie jestem pewien, jak upewnić się, że linia kończy się w odpowiednim miejscu, bez majsterkowania. Wykreślenie segmentu w każdym regionie rozwiązałoby to, ale wprowadziłoby kwestię odpowiedniego wyrównania wysokości. Ale to może być dobry punkt wyjścia.

Domyślam się, że jest to łatwiejsze w grafice siatka, ale musiałbym zrobić kilka badań, aby zweryfikować.

+0

Dzięki za pomoc. – gung

4

Ten artykuł Paula Murrell pokazuje użycie grid graficznych do rysowania linii między dwoma różnymi układami współrzędnych, w tym przypadku linii, które mają punkty końcowe określone w rodzimej przestrzeni dwóch oddzielnych sub-działek:

Pawła Murrell . Pakiet grafiki siatki. R Wiadomości, 2 (2): 14-19, czerwiec 2002

Jest na stronie 17 artykułu PDF:

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

+0

Dzięki, czytam artykuł. – gung

+0

Tak, dziękuję za ten świetny link. Właśnie dodałem trzeci blok kodu do mojej odpowiedzi, który wykorzystuje kilka funkcji ('grid.move.to()' i 'grid.line.to()') zademonstrowanych w artykule Murrell. –

Powiązane problemy