R - 像素矩阵的图像?

36

如何在R中从矩阵生成图像?

矩阵的值将对应于图像上的像素强度(尽管我目前只对0,1值白色或黑色感兴趣),而列和行号对应于图像上的垂直和水平位置。

生成图像的意思是在屏幕上显示并将其保存为jpg格式。


这里的答案应该很有用:https://dev59.com/-FXTa4cB1Zd3GeqP6OkY#5554352 - Chase
将其保存为PNG格式,而不是对于这样清晰的“图纸”无用的JPEG格式。 - mdsumner
7个回答

38
您可以使用'image'最简单地在屏幕上显示它:
m = matrix(runif(100),10,10)
par(mar=c(0, 0, 0, 0))
image(m, useRaster=TRUE, axes=FALSE)

您还可以查看raster软件包...


1
+1 对于旧版图像.default(现在支持使用useRaster = TRUE的rasterImage)。 - mdsumner
1
矩阵应该被转置,以便得到其精确的表示。我是正确的吗? - gabt

27

设置没有边距的绘图:

par(mar = rep(0, 4))

将矩阵以灰度图像的形式显示,就像spacedman的答案一样,但是要完全填充设备:


m = matrix(runif(100),10,10)
image(m, axes = FALSE, col = grey(seq(0, 1, length = 256)))

将其包装在调用png()之内以创建文件:

png("simpleIm.png")
par(mar = rep(0, 4))
image(m, axes = FALSE, col = grey(seq(0, 1, length = 256)))
dev.off()
如果您需要使用空间轴(X和Y的默认值为[0,1])来完成此操作,则可以使用 image.default(x,y,z,...) 格式,其中x和y给出z中像素的中心位置。xy 可以具有长度dim(z)+1,以提供该约定的角落坐标。
像素中心(这是图像的默认设置):
x <- seq(0, 1, length = nrow(m))
y <- seq(0, 1, length = ncol(m))
image(x, y, m, col = grey(seq(0, 1, length = 256)))

像素的角落(需要额外的1个x和y,而0现在是最底部的左角):

x <- seq(0, 1, length = nrow(m) + 1)
y <- seq(0, 1, length = ncol(m) + 1)
image(x, y, m, col = grey(seq(0, 1, length = 256)))

请注意,从R 2.13开始,image.default函数增加了一个参数useRaster,该参数使用高效的新图形函数rasterImage而不是旧有的image函数。后者在底层上实际上是多次调用rect函数来绘制每个像素点的多边形。


这对我起作用了。但是,我不得不反转行并转置矩阵才能使图像以正确的方向显示。我不知道其他人是否也需要这样做。 - gung - Reinstate Monica

13

我用两种方法之一来创建矩阵(其中垂直轴向下增加)。以下是使用heatmap.2()的第一种方法。它可以更好地控制图中数字值的格式(请参见下面的formatC语句),但在更改布局时可能会有些困难。

 library(gplots)

 #Build the matrix data to look like a correlation matrix
 x <- matrix(rnorm(64), nrow=8)
 x <- (x - min(x))/(max(x) - min(x)) #Scale the data to be between 0 and 1
 for (i in 1:8) x[i, i] <- 1.0 #Make the diagonal all 1's

 #Format the data for the plot
 xval <- formatC(x, format="f", digits=2)
 pal <- colorRampPalette(c(rgb(0.96,0.96,1), rgb(0.1,0.1,0.9)), space = "rgb")

 #Plot the matrix
 x_hm <- heatmap.2(x, Rowv=FALSE, Colv=FALSE, dendrogram="none", main="8 X 8 Matrix Using Heatmap.2", xlab="Columns", ylab="Rows", col=pal, tracecol="#303030", trace="none", cellnote=xval, notecol="black", notecex=0.8, keysize = 1.5, margins=c(5, 5))

在此输入图片描述


有趣,我得去看看那个库。 - Stedy

4
您可以创建一个矩阵的热力图。
library(pheatmap)

# Create a 10x10 matrix of random numbers
m = matrix(runif(100), 10, 10)

# Save output to jpeg
jpeg("heatmap.jpg")

pheatmap(m, cluster_row = FALSE, cluster_col = FALSE, color=gray.colors(2,start=1,end=0))

dev.off()

更多选项请查看?pheatmap


4

尝试使用levelplot:

library(lattice)
levelplot(matrix)

2
这里是第二种方式(同样是纵轴向下增长)。这种方法更易于布局,但在绘图中对数值格式的显示控制较少。
 library(plotrix)

 #Build the matrix data to look like a correlation matrix
 n <- 8
 x <- matrix(runif(n*n), nrow=n)
 xmin <- 0
 xmax <- 1
 for (i in 1:n) x[i, i] <- 1.0 #Make the diagonal all 1's

 #Generate the palette for the matrix and the legend.  Generate labels for the legend
 palmat <- color.scale(x, c(1, 0.4), c(1, 0.4), c(0.96, 1))
 palleg <- color.gradient(c(1, 0.4), c(1, 0.4), c(0.96, 1), nslices=100)
 lableg <- c(formatC(xmin, format="f", digits=2), formatC(1*(xmax-xmin)/4, format="f", digits=2), formatC(2*(xmax-xmin)/4, format="f", digits=2), formatC(3*(xmax-xmin)/4, format="f", digits=2), formatC(xmax, format="f", digits=2))

 #Set up the plot area and plot the matrix
 par(mar=c(5, 5, 5, 8))
 color2D.matplot(x, cellcolors=palmat, main=paste(n, " X ", n, " Matrix Using Color2D.matplot", sep=""), show.values=2, vcol=rgb(0,0,0), axes=FALSE, vcex=0.7)
 axis(1, at=seq(1, n, 1)-0.5, labels=seq(1, n, 1), tck=-0.01, padj=-1)

 #In the axis() statement below, note that the labels are decreasing.  This is because
 #the above color2D.matplot() statement has "axes=FALSE" and a normal axis()
 #statement was used.
 axis(2, at=seq(1, n, 1)-0.5, labels=seq(n, 1, -1), tck=-0.01, padj=0.7)

 #Plot the legend
 pardat <- par()
 color.legend(pardat$usr[2]+0.5, 0, pardat$usr[2]+1, pardat$usr[2], paste(" ", lableg, sep=""), palleg, align="rb", gradient="y", cex=0.7)

enter image description here


0
使用ggplot2
library(tidyverse)
n <- 12
m <- matrix(rnorm(n*n),n,n)
rownames(m) <- colnames(m) <- 1:n
df <- as.data.frame(m) %>% gather(key='y', value='val')
df$y <- as.integer(df$y)
df$x <- rep(1:n, n)
ggplot(df, aes(x, y, fill= val)) + 
   geom_tile() +
   geom_text(aes(x, y, label=round(val,2))) +
   scale_fill_gradient(low = "white", high = "red") + 
   theme_bw() 

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接