簡體   English   中英

在R中創建具有相同軸的多個散點圖

[英]creating multiple scatter plots with same axes in R

我試圖在R中用2 x 2排列繪制四個散點圖(我實際上是通過rpy2繪圖)。 我希望每個都具有1的縱橫比,但也是相同的比例,所以所有子圖的相同的X和Y標記,以便它們可以進行比較。 我嘗試用par來做到這一點:

par(mfrow=c(2,2))
# scatter 1
plot(x, y, "p", asp=1)
# scatter 2
plot(a, b, "p", asp=1)
# ...

編輯:

這是我現在擁有的直接例子:

> par(mfrow=c(2,2))
> for (n in 1:4) { plot(iris$Petal.Width, rnorm(length(iris$Petal.Width)), "p", asp=1) }

它創建了正確的散射類型,但具有不同的比例。 設置ylimxlim是在每次調用相同的plot上面並沒有解決問題。 您仍然會在每個軸上獲得非常不同的刻度線和刻度數,這使得分散不必要地難以解釋。 我希望X和Y軸相同。 例如,這個:

for (n in 1:4) { plot(iris$Petal.Width, rnorm(length(iris$Petal.Width)), "p", asp=1, xlim=c(-4, 6), ylim=c(-2, 4)) }

生成錯誤的結果:

在此輸入圖像描述

確保在所有子圖中使用相同軸的最佳方法是什么?

我所尋找的是一個像axis=same或類似於par(mfrow=...) ,這聽起來像是lattice的默認行為,使軸在每個子圖中共享和相同。

lgautier用ggplot給出了很好的代碼,但它要求提前知道軸。 我想澄清一點,我想避免遍歷每個子圖中的數據並自己計算要繪制的正確刻度。 如果在預先知道,那么ggplot解決方案不僅僅是密謀更加復雜plot和明確

agstudy給出了格子的解決方案。 這看起來與我想要的最接近,因為你不必明確預先計算每個散點的刻度位置,但作為新用戶,我無法弄清楚如何使格子看起來像普通的情節。 我得到的最接近的是:

> xyplot(y~x|group, data =dat, type='p',
        between =list(y=2,x=2),
        layout=c(2,2), aspect=1,
               scales =list(y = list(relation='same'), alternating=FALSE))

產量:

在此輸入圖像描述

我怎樣才能讓它看起來像R基座? 我不希望這些group字幕位於每個子圖的頂部,或者在每個散點的頂部和右側懸掛未標記的標記,我只想要標記散射的每個x和y。 我也不是在尋找X和Y的共享標簽 - 每個子圖都有自己的X和Y標簽。 並且每個散點中的軸標簽必須相同,盡管這里選擇的數據沒有意義。

除非有一種簡單的方法使格子看起來像R基礎,否則聽起來答案是沒有辦法做我想在R中做的事情(令人驚訝),沒有預先計算每個子圖中每個刻度的確切位置,這需要提前迭代數據。

使用latticeggplot2您需要重塑數據。 例如:

  1. 創建4個data.frame(x = x1,y = y1)...
  2. 為每個data.frame,group = 1,2,...添加一個組列
  3. 將4個data.frame重新綁定一次

這里使用lattice的例子

dat <- data.frame(x = rep(sample(1:100,size=10),4),
                  y = rep(rnorm(40)),
                  group = rep(1:4,each =10))

xyplot(y~x|group,       ## conditional formula to get 4 panels
       data =dat,       ## data
       type='l',        ## line type for plot
       groups=group,     ## group ti get differents colors
       layout=c(2,2))   ## equivalent to par or layout

在此輸入圖像描述

PS:不需要設置聖誕節。 xyplot ,默認的sacles設置是same (所有面板都有相同的sacles)。 您可以修改它,例如:

xyplot(y~x|group, data =dat, type='l',groups=group,
       layout=c(2,2), scales =list(y = list(relation='free')))

編輯

格子繪圖函數有大量參數可以控制繪圖的許多細節,例如我自定義:

  1. 用於條帶標簽和標題的文本
  2. 軸刻度標簽的大小和位置,
  3. 列和行之間的間隙大小。

     xyplot(y~x|group, data =dat, type='l',groups=group, between =list(y=2,x=2), layout=c(2,2), strip = myStrip, scales =list(y = list(relation='same',alternating= c(3,3)))) 

哪里

myStrip <- function(var.name,which.panel, which.given,...) {
  var.name <- paste(var.name ,which.panel)
  strip.default(which.given,which.panel,var.name,...)
  }

在此輸入圖像描述

編輯為了得到格子圖基本圖形圖,你可以試試這個:

xyplot(y~x|group, data =dat, type='l',groups=group,
       between=list(y=2,x=2),
       layout=c(2,2), 
       strip =FALSE,
       xlab=c('a','a'),
       xlab.top=c('a','a'),
       ylab=c('b','b'),
       ylab.right = c('b','b'),
       main=c('plot1','plot2'),
       sub=c('plot3','plot4'),
       scales =list(y = list(alternating= c(3,3)),
                    x = list(alternating= c(3,3))))

在此輸入圖像描述

如果開始,ggplot2可能具有最高的漂亮/簡單比率。

rpy2示例:

from rpy2.robjects.lib import ggplot2
from rpy2.robjects import r, Formula

iris = r('iris')

p = ggplot2.ggplot(iris) + \
    ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length", y="Sepal.Width")) + \
    ggplot2.facet_wrap(Formula('~ Species'), ncol=2, nrow = 2) + \
    ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) # aspect ratio
# coord_fixed() missing from the interface, 
# therefore the hack. This should be fixed in rpy2-2.3.3

p.plot()

閱讀上一個答案的評論我發現你可能意味着完全獨立的情節。 使用R的默認繪圖系統, par(mfrow(c(2,2))par(mfcol(c(2,2)))是最簡單的方法,並保持縱橫比,軸的范圍,以及通過通常的方式確定那些固定的標記。

在R中繪制的最靈活的系統可能是grid 它沒有看起來那么糟糕,可以想象是一個場景圖。 使用rpy2,ggplot2和grid:

from rpy2.robjects.vectors import FloatVector

from rpy2.robjects.lib import grid
grid.newpage()
lt = grid.layout(2,2) # 2x2 layout
vp = grid.viewport(layout = lt)
vp.push()


# limits for axes and tickmarks have to be known or computed beforehand
xlims = FloatVector((4, 9))
xbreaks = FloatVector((4,6,8))
ylims = FloatVector((-3, 3))
ybreaks = FloatVector((-2, 0, 2))

# first panel
vp_p = grid.viewport(**{'layout.pos.col':1, 'layout.pos.row': 1})
p = ggplot2.ggplot(iris) + \
    ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length",
                                          y="rnorm(nrow(iris))")) + \
    ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) + \
    ggplot2.scale_x_continuous(limits = xlims, breaks = xbreaks) + \
    ggplot2.scale_y_continuous(limits = ylims, breaks = ybreaks)
p.plot(vp = vp_p)
# third panel
vp_p = grid.viewport(**{'layout.pos.col':2, 'layout.pos.row': 2})
p = ggplot2.ggplot(iris) + \
    ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length",
                                          y="rnorm(nrow(iris))")) + \
    ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) + \
    ggplot2.scale_x_continuous(limits = xlims, breaks = xbreaks) + \
    ggplot2.scale_y_continuous(limits = ylims, breaks = ybreaks)
p.plot(vp = vp_p)

rpy2文檔中有關圖形的更多文檔,以及ggplot2和網格文檔之后的文檔。

雖然已經選擇了答案,但該答案使用ggplot而不是基礎R,這是OP想要的。 雖然ggplot非常適合快速繪圖,但對於出版物而言,您通常希望對ggplot提供的圖表進行更精細的控制。 這就是基礎情節優秀的地方。

我建議閱讀Sean Anderson對巧妙使用par的神奇解釋 ,以及使用layout()split.screen()等其他一些好的技巧。

用他的解釋,我想出了這個:

# Assume that you are starting with some data, 
# rather than generating it on the fly
data_mat <- matrix(rnorm(600), nrow=4, ncol=150)
x_val <- iris$Petal.Width

Ylim <- c(-3, 3)
Xlim <- c(0, 2.5)

# You'll need to make the ylimits the same if you want to share axes


par(mfrow=c(2,2))
par(mar=c(0,0,0,0), oma=c(4,4,0.5,0.5))
par(mgp=c(1, 0.6, 0.5))
for (n in 1:4) { 
  plot(x_val, data_mat[n,], "p", asp=1, axes=FALSE, ylim=Ylim, xlim=Xlim)
  box()
  if(n %in% c(1,3)){
    axis(2, at=seq(Ylim[1]+0.5, Ylim[2]-0.5, by=0.5))
  }
  if(n %in% c(3,4)){
    axis(1, at=seq(min(x_val), max(x_val), by=0.1))
  }
}

繪制共享邊距

這里還有一些工作要做。 就像在OP中一樣,數據似乎在中間被壓扁了。 當然,調整事物會很好,因此可以使用完整的繪圖區域。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM