2 farklı y ekseniyle nasıl grafik çizebilirim?


122

R'de iki dağılım grafiğini üst üste koymak istiyorum, böylece her nokta kümesinin kendi (farklı) y ekseni vardır (yani şekildeki 2. ve 4. konumlarda), ancak noktalar aynı şekilde üst üste bindirilmiş olarak görünür.

Bunu yapmak mümkün mü plot?

Düzenleme sorunu gösteren örnek kod

# example code for SO question
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)
x <- 1:10
# in this plot y2 is plotted on what is clearly an inappropriate scale
plot(y1 ~ x, ylim = c(-1, 150))
points(y2 ~ x, pch = 2)

Lütfen örnek veriler sağlayın. Bu genellikle estetik açıdan kötü bir fikirdir.
Chase

3
özel durumdaki cevaplar ve tartışma ggplot2: stackoverflow.com/questions/3099219/… ( [r] two y-axesveya için SO arama [r] twoord.plot) - ilgili birkaç yanıt daha var, ancak (bu bir R SSS olduğu için şaşırtıcı bir şekilde) aynı hiçbir şey
Ben Bolker

@chase - Sorunun çalışan bir örneğini ekledim. Estetik konulardaki uyarı için teşekkürler.
DQdlM

Yanıtlar:


126

güncelleme : http://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxes adresindeki R wiki'de bulunan kopyalanmış materyal , bağlantı artık bozuk: geri dönüş makinesinden de edinilebilir

Aynı arsa üzerinde iki farklı y ekseni

(orijinal olarak Daniel Rajdl 2006/03/31 15:26 tarafından yazılmış bazı materyaller)

Lütfen aynı arsa üzerinde iki farklı ölçek kullanmanın uygun olduğu çok az durum olduğunu unutmayın. İzleyiciyi grafiği yanıltmak çok kolaydır. Aşağıdaki iki örnek ve yorum bu konuda (Kontrol example1 , example2 gelen Önemsiz Charts ), hem de bu makaleyi Birkaç Stephen çift ölçekli eksenli grafikleri asla olduklarını, kesinlikle, sonuçlandırmak ve son kez edemez”sonucuna ( yararlı; sadece diğer, daha iyi çözümlerin ışığında onları garanti eden bir durum düşünemediğim için. ”) Ayrıca bu karikatürdeki 4. noktaya bakın ...

Eğer belli ise temel tarifi, set ilk arsa yaratmaktır par(new=TRUE), grafik cihazı takas ikinci arsa oluşturmasını R önlemek için axes=FALSE(ve ayar xlabve ylab- boş olması ann=FALSEkullanarak sonra ve gerektiği zamanda iş) axis(side=4)yeni bir eksen eklemek için sağ tarafa ve sağ tarafa mtext(...,side=4)bir eksen etiketi eklemek için. İşte biraz uydurma veri kullanan bir örnek:

set.seed(101)
x <- 1:10
y <- rnorm(10)
## second data set on a very different scale
z <- runif(10, min=1000, max=10000) 
par(mar = c(5, 4, 4, 4) + 0.3)  # Leave space for z axis
plot(x, y) # first plot
par(new = TRUE)
plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=4, at = pretty(range(z)))
mtext("z", side=4, line=3)

twoord.plot()içinde plotrixolduğu gibi paketin, bu işlemini otomatik doubleYScale()yılında latticeExtrapaketin.

Başka bir örnek (Robert W. Baer tarafından yazılan R posta listesi gönderisinden uyarlanmıştır):

## set up some fake test data
time <- seq(0,72,12)
betagal.abs <- c(0.05,0.18,0.25,0.31,0.32,0.34,0.35)
cell.density <- c(0,1000,2000,3000,4000,5000,6000)

## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)

## Plot first set of data and draw its axis
plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="", 
   type="b",col="black", main="Mike's test data")
axis(2, ylim=c(0,1),col="black",las=1)  ## las=1 makes horizontal labels
mtext("Beta Gal Absorbance",side=2,line=2.5)
box()

## Allow a second plot on the same graph
par(new=TRUE)

## Plot the second plot and put axis scale on right
plot(time, cell.density, pch=15,  xlab="", ylab="", ylim=c(0,7000), 
    axes=FALSE, type="b", col="red")
## a little farther out (line=4) to make room for labels
mtext("Cell Density",side=4,col="red",line=4) 
axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1)

## Draw the time axis
axis(1,pretty(range(time),10))
mtext("Time (Hours)",side=1,col="black",line=2.5)  

## Add Legend
legend("topleft",legend=c("Beta Gal","Cell Density"),
  text.col=c("black","red"),pch=c(16,15),col=c("black","red"))

görüntü açıklamasını buraya girin

Benzer tarifler, farklı tipteki grafikleri üst üste koymak için kullanılabilir - çubuk grafikleri, histogramlar, vb.


bu yüzden yalnızca bağlantı yanıtları kötü bir fikirdir ... wiki.r-project.org geçersiz görünüyor, r-devel@r-project.org adresinden soruyorum.
Ben Bolker

@BenBolker çözümünüz dahice! ancak bir sorum var. Her iki tarafta birden fazla satır varsa, bu yöntemi yine de kullanabilirim, ancak yalnızca sembollerle. Line = plot kullanmaya çalıştığımda, onları sürekli olarak çizmeye çalışıyor. Bunu düzeltmek için bir numara önerir misiniz?
wthimdh

1
@BenBolker Ya Saat "2019-01-01" türünde bir tarih biçimiyse. axis(1,pretty(range(time),10))Çizgiyi nasıl değiştireceksiniz ?
k.dkhk

35

Adından da anlaşılacağı gibi, twoord.plot()içinde plotrix iki ordinat eksenleri ile paket araziler.

library(plotrix)
example(twoord.plot)

görüntü açıklamasını buraya girin

görüntü açıklamasını buraya girin

görüntü açıklamasını buraya girin

görüntü açıklamasını buraya girin

görüntü açıklamasını buraya girin


3
kaygan. örneklerin kamyon yükü için teşekkürler. Negatif değerler içeren bu çizgi ve çubuk örneklerinden birini de görmeyi çok isterim. Ayrıca istifleme de iyi olurdu.
Matt Bannert

5

Bir seçenek yan yana iki parsel yapmaktır. ggplot2bunun için güzel bir seçenek sunar facet_wrap():

dat <- data.frame(x = c(rnorm(100), rnorm(100, 10, 2))
  , y = c(rnorm(100), rlnorm(100, 9, 2))
  , index = rep(1:2, each = 100)
  )

require(ggplot2)
ggplot(dat, aes(x,y)) + 
geom_point() + 
facet_wrap(~ index, scales = "free_y")

4

Ölçekler / eksen etiketlerinden vazgeçebilirseniz, verileri (0, 1) aralığına yeniden ölçeklendirebilirsiniz. Bu, örneğin, izler arasındaki yerel korelasyonlarla ilgilendiğinizde ve farklı ölçeklere sahip olduklarında (binlerce, Fst 0-1) kromozomlar üzerindeki farklı 'kıpırdatma' izleri için işe yarar.

# rescale numeric vector into (0, 1) interval
# clip everything outside the range 
rescale <- function(vec, lims=range(vec), clip=c(0, 1)) {
  # find the coeficients of transforming linear equation
  # that maps the lims range to (0, 1)
  slope <- (1 - 0) / (lims[2] - lims[1])
  intercept <- - slope * lims[1]

  xformed <- slope * vec + intercept

  # do the clipping
  xformed[xformed < 0] <- clip[1]
  xformed[xformed > 1] <- clip[2]

  xformed
}

Sonra, bir veri çerçevesi olan chrom, position, coverageve fstsütunlar, bir şeyler gibi yapabilirsiniz:

ggplot(d, aes(position)) + 
  geom_line(aes(y = rescale(fst))) + 
  geom_line(aes(y = rescale(coverage))) +
  facet_wrap(~chrom)

Bunun avantajı, iki trakc ile sınırlı olmamanızdır.


4

Ben de anlaşılacağı twoord.stackplot()içinde plotrixdaha iki ordinat eksenleri ile paket araziler.

data<-read.table(text=
"e0AL fxAL e0CO fxCO e0BR fxBR anos
 51.8  5.9 50.6  6.8 51.0  6.2 1955
 54.7  5.9 55.2  6.8 53.5  6.2 1960
 57.1  6.0 57.9  6.8 55.9  6.2 1965
 59.1  5.6 60.1  6.2 57.9  5.4 1970
 61.2  5.1 61.8  5.0 59.8  4.7 1975
 63.4  4.5 64.0  4.3 61.8  4.3 1980
 65.4  3.9 66.9  3.7 63.5  3.8 1985
 67.3  3.4 68.0  3.2 65.5  3.1 1990
 69.1  3.0 68.7  3.0 67.5  2.6 1995
 70.9  2.8 70.3  2.8 69.5  2.5 2000
 72.4  2.5 71.7  2.6 71.1  2.3 2005
 73.3  2.3 72.9  2.5 72.1  1.9 2010
 74.3  2.2 73.8  2.4 73.2  1.8 2015
 75.2  2.0 74.6  2.3 74.2  1.7 2020
 76.0  2.0 75.4  2.2 75.2  1.6 2025
 76.8  1.9 76.2  2.1 76.1  1.6 2030
 77.6  1.9 76.9  2.1 77.1  1.6 2035
 78.4  1.9 77.6  2.0 77.9  1.7 2040
 79.1  1.8 78.3  1.9 78.7  1.7 2045
 79.8  1.8 79.0  1.9 79.5  1.7 2050
 80.5  1.8 79.7  1.9 80.3  1.7 2055
 81.1  1.8 80.3  1.8 80.9  1.8 2060
 81.7  1.8 80.9  1.8 81.6  1.8 2065
 82.3  1.8 81.4  1.8 82.2  1.8 2070
 82.8  1.8 82.0  1.7 82.8  1.8 2075
 83.3  1.8 82.5  1.7 83.4  1.9 2080
 83.8  1.8 83.0  1.7 83.9  1.9 2085
 84.3  1.9 83.5  1.8 84.4  1.9 2090
 84.7  1.9 83.9  1.8 84.9  1.9 2095
 85.1  1.9 84.3  1.8 85.4  1.9 2100", header=T)

require(plotrix)
twoord.stackplot(lx=data$anos, rx=data$anos, 
                 ldata=cbind(data$e0AL, data$e0BR, data$e0CO),
                 rdata=cbind(data$fxAL, data$fxBR, data$fxCO),
                 lcol=c("black","red", "blue"),
                 rcol=c("black","red", "blue"), 
                 ltype=c("l","o","b"),
                 rtype=c("l","o","b"), 
                 lylab="Años de Vida", rylab="Hijos x Mujer", 
                 xlab="Tiempo",
                 main="Mortalidad/Fecundidad:1950–2100",
                 border="grey80")
legend("bottomright", c(paste("Proy:", 
                      c("A. Latina", "Brasil", "Colombia"))), cex=1,
        col=c("black","red", "blue"), lwd=2, bty="n",  
        lty=c(1,1,2), pch=c(NA,1,1) )

1

@BenBolker tarafından kabul edilen yanıta benzer bir başka alternatif de, ikinci bir nokta kümesi eklerken mevcut arsanın koordinatlarını yeniden tanımlamaktır.

İşte minimal bir örnek.

Veri:

x  <- 1:10
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)

Arsa:

par(mar=c(5,5,5,5)+0.1, las=1)

plot.new()
plot.window(xlim=range(x), ylim=range(y1))
points(x, y1, col="red", pch=19)
axis(1)
axis(2, col.axis="red")
box()

plot.window(xlim=range(x), ylim=range(y2))
points(x, y2, col="limegreen", pch=19)
axis(4, col.axis="limegreen")

misal

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.