Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中创建具有相同轴的多个散点图_R_Graphics_Plot_Rpy2 - Fatal编程技术网

在R中创建具有相同轴的多个散点图

在R中创建具有相同轴的多个散点图,r,graphics,plot,rpy2,R,Graphics,Plot,Rpy2,我试图在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

我试图在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) }
它创建了正确的散射类型,但具有不同的比例。在对上述
plot
的每次调用中将
ylim
xlim
设置为相同并不能解决问题。在每个轴上仍然会有非常不同的记号和记号号,这使得不必要地难以解释散布。我希望X轴和Y轴相同。例如,这:


对于(1:4中的n){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
和显式绘制要复杂得多

研究给出了一个晶格的解。这看起来与我想要的最接近,因为您不必显式地预计算每个散射的刻度位置,但是作为一个新用户,我无法弄清楚如何使晶格看起来像一个普通的绘图。我得到的最接近的结果是:

> 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底座?我不希望这些
字幕出现在每个子批次的顶部,或者在每个散点的顶部和右侧挂着未标记的记号,我只希望散点的每个x和y都被标记。我也不是在寻找X和Y的共享标签——每个子地块都有自己的X和Y标签。轴标签在每个散射中都必须相同,尽管这里选择的数据没有意义


除非有一种简单的方法使网格看起来像R基,否则答案似乎是,如果不预先计算每个子批次中每个勾号的确切位置,就无法完成我在R中尝试做的事情(令人惊讶),这需要提前迭代数据

使用
lattice
ggplot2
您需要重塑数据。例如:

  • 创建4个数据帧(x=x1,y=y1)
  • 为每个data.frame添加组列,组=1,2
  • r按一次键入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
    
    编辑

    晶格绘图有大量参数 允许控制绘图的许多细节的函数,例如我自定义:

  • 用于条带标签和标题的文本
  • 轴标记标签的大小和位置
  • 面板的列和行之间的间隙大小

    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,...)
      }
    

    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)
    

    在ggplot2和网格文档中以及之后有更多文档。

    虽然已经选择了答案,但该答案使用的是
    ggplot
    而不是OP想要的基R。虽然
    ggplot
    非常适合快速打印,但对于发布,您通常希望对打印进行更好的控制<代码>ggplot
    提供。这就是基本绘图的优势所在

    我建议阅读可以巧妙使用
    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))
      }
    }
    
    #假设您从一些数据开始,
    #而不是动态生成
    
    data_mat如果您想要普通比例,则使用ggplot2或晶格和镶嵌面或网格(分别)会容易得多。我对任何一个都很感兴趣,尤其是lattice,因为ggplot2对我来说可能太复杂了。好吧,计算轴的记号和范围是lattice或ggplot2在没有引擎盖的情况下所做的。似乎您正在寻找一个解决方案,该解决方案会在生成新的绘图时更新以前的绘图,因此记号和坐标范围是相同的。这可以用网格来实现,但前面计算刻度线和范围的工作量似乎要小得多。@lgautier:那么在R base中进行预计算的标准方法是什么呢?正如我在编辑设置xlim/ylim中所写的那样,这是不够的。此外,它不必是实时更新的-我很乐意将所有数据放在r矩阵或数据帧中的所有分散首先当查看您提供的带有r基本图形的图形时,对我来说,刻度线在绘图中看起来非常相同。我通常也对理想解决方案应该具备的要求感到困惑。可能模型会更有用。谢谢,但此布局
    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)
    
    # 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))
      }
    }