2012-04-02 5 views
8

Nehmen Sie ein sehr einfaches Beispiel, mfrow=c(1,3); jede Figur ist ein anderes Histogramm; Wie würde ich eine horizontale Linie zeichnen (ähnlich abline(h=10)), die über alle 3 Zahlen ging? (Das heißt, sogar die Ränder zwischen ihnen.) Natürlich könnte ich jeder Figur eine Abline hinzufügen, aber das ist nicht was ich will. Ich kann an eine sehr komplizierte Möglichkeit denken, dies zu tun wirklich nur mit 1 Figur, und zeichnen jede 'Figur' innerhalb es mit polygon usw. Das wäre lächerlich. Gibt es nicht einen einfachen Weg, dies zu tun?Wie zeichnen Sie eine Linie über eine mehrfigurige Umgebung in R?

Antwort

13

Wie @joran erwähnt, das Gitter Graphical System bietet flexibleren Kontrolle über die Anordnung mehrerer Plots auf einem einzelnen Gerät.

hier verwende ich grconvertY() zuerst die Lage von einer Höhe von 50 auf der y-Achse in Einheiten von „normalisieren Vorrichtungskoordinaten“ abzufragen. (d. h. als ein Anteil der Gesamthöhe der Zeichenvorrichtung mit 0 = unten und 1 = oben). Ich verwende dann Gitter Funktionen zu: (1) drücken Sie eine viewport, die das Gerät füllt; und (2) zeichne eine Linie auf der Höhe auf, die von grconvertY() zurückgegeben wird.

## 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 gefragt, wie eine Linie zu zeichnen, die von der y-Achse der ersten Parzelle zum Rande des letzten Balkens in der 3. Parzelle erstreckt. Hier sind ein paar Alternativen:

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

Schließlich ist hier ein fast Äquivalent und allgemeiner nützlicher Ansatz.Es beschäftigt die Funktionen grid.move.to() und grid.line.to() demo'd von Paul Murrell in dem Artikel verknüpft in @ mdsumner Antwort:

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 Schön! Kennen Sie die Masseinheiten/Koordinaten/Clipping so, dass die Linie von der linken y-Achse bis zur rechten Kante der grünen Balken reicht? – joran

+0

Ich habe eine Idee, und ich werde es hinzufügen, wenn es klappt. Gerade jetzt, ich bin dran, den Rasen zu mähen, bevor die Sonne untergeht ... –

+0

Danke, das ist wirklich hilfreich! Ich schätze Ihre Bereitschaft, Rasen mähen auf meinem Konto zu verschieben ;-) – gung

6

Dies ist das Beste, was ich härter, ohne darüber nachzudenken, es zu tun:

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

Ich bin nicht sicher, wie die Linie endet an der richtigen Stelle, um sicherzustellen, ohne Bastelei. Das Aufzeichnen eines Segments in jeder Region würde das lösen, aber das Problem einführen, dass die Höhen richtig ausgerichtet sind. Aber das könnte zumindest ein guter Ausgangspunkt sein.

Ich denke, das ist einfacher in Raster Grafiken, aber ich müsste einige Nachforschungen zu verifizieren.

+0

Vielen Dank für Ihre Hilfe. – gung

4

Dieser Artikel von Paul Murrell zeigt die Verwendung von grid Grafiklinien zwischen zwei verschiedenen Koordinatensystemen, in diesem Fall Linien, die in der nativen Raum von zwei separaten Teil Plots definiert Endpunkte zu zeichnen:

Paul Murrell . Das Grid-Grafikpaket. R News, 2 (2): 14-19, Juni 2002

Es auf Seite ist 17 des PDF Artikel:

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

+0

Danke, ich lese den Artikel. – gung

+0

Ja, danke für diesen tollen Link. Ich habe gerade einen dritten Code-Block zu meiner Antwort hinzugefügt, der einige der Funktionen ('grid.move.to()' und 'grid.line.to()') benutzt, die in Murrells Artikel demonstriert wurden. –

Verwandte Themen