【问题标题】:R image() plots matrix rotated?R image() 绘制矩阵旋转?
【发布时间】:2015-08-07 16:01:00
【问题描述】:

我一直在阅读the docs for R image(),但我不明白。为什么这个矩阵:

> mat1
     [,1] [,2] [,3]
[1,]    1    0    1
[2,]    0    1    0
[3,]    0    0    0

如下图:

> image(c(1:3), c(1:3), mat1)

输出这个:

我怎样才能使布局与打印的矩阵相同?这不仅仅是用转置来翻转 x 和 y 的问题,因为这最终会得到一个“颠倒”的图像。

【问题讨论】:

标签: r image


【解决方案1】:

你可以反转矩阵,然后转置。

mat1 <- apply(mat1, 2, rev)
image(1:3, 1:3, t(mat1))

这很令人困惑,因为它从下到上按行绘制,但 R 按列索引矩阵,自上而下。因此,第一行中的像素,从左到右,对应于矩阵中的第一列,自上而下。

【讨论】:

  • 感谢您的提示,但我想知道您是否知道此设计结束的合理化/或文档中的说明?我查看了文档,我很沮丧,因为在绘制图像之前我无法弄清楚我应该如何知道这一点?
  • @helloB 在?image 的详细信息部分隐藏了一些关于布局的讨论。除此之外,我认为图像通常是自下而上绘制的(不确定)?
  • @helloB 正如 nongkrong 指出的那样,检查 ?image 的详细信息部分,您会发现“注意图像将 z 矩阵解释为 f(x[i], y[j ]) 值,因此 x 轴对应于行号,y 轴对应于列号,第 1 列位于底部,即矩阵的传统打印布局逆时针旋转 90 度。”
  • @Jota 感谢您指出这一点。我总是错过那些手册页上的一些东西。
  • @nongkrong 我刚刚意识到您的答案需要修改。真的,您需要使用 apply 语句:apply(mat, rev, 2) 否则您将不需要镜像反转。当您将简单的 rev() 应用于非方阵时,它会反转整个矩阵,不会以镜像方式翻转行。
【解决方案2】:

当使用这样的方式将矩阵视为图像时:

m <- some matrix

image(m) R 把它颠倒过来。经过一些小麻烦后,我找到了这个快速解决方案。

image(m[,nrow(m):1])

nrow(m) 给出矩阵的行数

nrow(m):1 逆序排列

【讨论】:

    【解决方案3】:

    对于使用image() 的人来说,这似乎是一个非常普遍的问题。

    矩阵被“倒置”绘制的原因是因为图像空间是在标准化设备坐标中定义的,也就是 NDC 空间。这是一个与屏幕无关的坐标参考系统 (crs),其中左下角是单元格 (1,1),列号从左到右进行,而行号从矩阵的底部到顶部增加,即 X ={0:1},Y={0:1}

    来自文档:

    请注意,图像将 z 矩阵解释为 f(x[i], y[j]) 值的表,因此 x 轴对应于行号,y 轴对应于列号,第 1 列位于底部,即矩阵的传统印刷布局的 90 度逆时针旋转。

    不应忽视逆时针旋转这一点,因为它会影响操作顺序,我们需要得到一个看起来符合我们预期的绘图。

    票数最高的答案在理论上是正确的:

    你可以反转矩阵,然后转置。

    但是,执行此操作的最简单方法不需要任何循环和/或apply()

    R 中的标准矩阵从上到下打印,而传统上我们希望看到数据的逐行投影以用于显示目的。

    > m <- matrix(c(1:9),ncol=3)
    > m
         [,1] [,2] [,3]
    [1,]    1    4    7
    [2,]    2    5    8
    [3,]    3    6    9
    > image(m)
    

    NDC空间中的图像函数要求单元格(1,1)在左下角,并相应输出结果。因此,我们在左下角的单元格中看到最低的阴影值,在右上角的单元格中看到最高的阴影值。

    但也请注意,image() 的输出不仅仅是标准矩阵的行反转,而是逆时针旋转,因此m第一列变成image(m)最后一行 .

    所以我们可以进行自动转置,但我们需要先正确地进行反转,这意味着我们必须通过选择列对m 进行排序。通常排序/排序是按行进行的,但 NDC 空间会反转所有内容。

    How to reverse rows in matrix?

    要按照上述反转标准矩阵的行,我们会调用:

    m[nrow(m):1, ]
    

    相反,我们必须反转查询逻辑,以预期image() 应用的轮换。因此我们从上一个答案中得到了解决方案:

    > m <- m[,nrow(m):1]
    > m
         [,1] [,2] [,3]
    [1,]    7    4    1
    [2,]    8    5    2
    [3,]    9    6    3
    > image(m)
    

    将上述方法与将标准矩阵转换为 NDC 空间的一般方法进行对比,如下所示:

    m <- t(matrix(c(1:9),ncol=3))
    m <- m[nrow(m):1,]
    

    注意转置是如何首先执行的,并假设数据顺时针旋转;并且子集/排序是逐行的。这是我们之前校正过程的镜像,我们首先按列排序,然后使用image() 逆时针转置。

    P.S. 我强烈主张在学习 ggplot2 或任何其他图形包之前或同时探索图形参数以及与 par() 相关的所有内容。

    https://www.rdocumentation.org/packages/graphics/versions/3.6.2/topics/par

    在许多情况下,基本 R 函数非常健壮,并提供了可以解放用户的解决方案,同时扩展我们对语言的了解并提高我们对数据的灵活性。就个人而言,我迷上了开源,因为我觉得我使用的每一个软件装备都限制了我在简化到更高级别功能的过程中的表现力。

    当心任何产生您不完全理解并且在必要时无法手动重现的输出的函数。 Image() 很重要,因为重要的更高级别的工具(如光栅)是从它改编而来的。

    【讨论】:

      【解决方案4】:

      如果您想要一个倒置的镜像而不是旋转,您可以使用 R 包“Thermimage”中的矩阵上的函数mirror.matrix()

      【讨论】:

        【解决方案5】:

        我认为安迪和亚当最好。我相信罗夏的apply需要按行(margin = 1)而不是按列来做镜像。

        更正在反转行时使用 ncol 而不是 nrow。 nrow 仅在 cols 和 columns 长度相等时起作用,

        m <- matrix(c(1:9), nrow = 3)
        par(mfrow = c(1,4))
        m %>% image(main = title("orig"))
        m %>% apply(2,rev) %>% t() %>% image(main = title("Rorschach"))
        m %>% apply(1,rev) %>% t() %>% image(main = title("Rors alt"))
        m[,ncol(m):1] %>% image(main = title("Adam"))
        

        【讨论】:

          猜你喜欢
          • 2013-08-26
          • 2020-10-22
          • 2017-09-16
          • 1970-01-01
          • 2019-02-08
          • 1970-01-01
          • 2015-06-18
          • 1970-01-01
          • 2011-05-01
          相关资源
          最近更新 更多