R图像()绘制矩阵旋转?

时间:2015-08-07 16:01:01

标签: r image

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

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

绘制如下:

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

产生这个:

enter image description here

如何使布局与印刷矩阵相同?这不仅仅是让转置翻转x和y,因为它会以“颠倒”的图像结束。

3 个答案:

答案 0 :(得分:11)

您可以反转矩阵,然后进行转置。

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

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

答案 1 :(得分:1)

使用以下方式将矩阵作为图像查看时:

m <- some matrix

image(m) R将其上下颠倒。经过一阵头痛之后,我找到了快速修复方法。

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

nrow(m)给出矩阵的行数

nrow(m):1向后排列

答案 2 :(得分:1)

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

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

来自文档:

<块引用>

注意 image 将 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) 位于左下角并相应地输出结果。因此,我们在左下角的单元格中看到了最低的阴影值,在右上角的单元格中看到了最高的阴影值。

enter image description here

但还要注意 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)

enter image description here

将上述方法与将标准矩阵转换为 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() 很重要,因为重要的更高级别的工具(如栅格)都是从它改编而来的。

相关问题