有一些我想添加“点画”的数据来显示它在哪里是“重要的”,就像他们在 IPCC 图中所做的那样
目前,我真的在努力尝试在 R 中做到这一点。
如果我制作一些测试数据并绘制它:
data <- array(runif(12*6), dim=c(12,6) )
over <- ifelse(data > 0.5, 1, 0 )
image(1:12, 1:6, data)
我最终想要做的是基于当前图像顶部的数组“over”过度绘制一些点。
有什么建议么!??
这应该会有所帮助 - 我以前做过类似的事情,并写了一个我在这里发布的函数。
#required function from www.menugget.blogspot.com
matrix.poly <- function(x, y, z=mat, n=NULL){
if(missing(z)) stop("Must define matrix 'z'")
if(missing(n)) stop("Must define at least 1 grid location 'n'")
if(missing(x)) x <- seq(0,1,,dim(z)[1])
if(missing(y)) y <- seq(0,1,,dim(z)[2])
poly <- vector(mode="list", length(n))
for(i in seq(length(n))){
ROW <- ((n[i]-1) %% dim(z)[1]) +1
COL <- ((n[i]-1) %/% dim(z)[1]) +1
dist.left <- (x[ROW]-x[ROW-1])/2
dist.right <- (x[ROW+1]-x[ROW])/2
if(ROW==1) dist.left <- dist.right
if(ROW==dim(z)[1]) dist.right <- dist.left
dist.down <- (y[COL]-y[COL-1])/2
dist.up <- (y[COL+1]-y[COL])/2
if(COL==1) dist.down <- dist.up
if(COL==dim(z)[2]) dist.up <- dist.down
xs <- c(x[ROW]-dist.left, x[ROW]-dist.left, x[ROW]+dist.right, x[ROW]+dist.right)
ys <- c(y[COL]-dist.down, y[COL]+dist.up, y[COL]+dist.up, y[COL]-dist.down)
poly[[i]] <- data.frame(x=xs, y=ys)
}
return(poly)
}
#make vector of grids for hatching
incl <- which(over==1)
#make polygons for each grid for hatching
polys <- matrix.poly(1:12, 1:6, z=over, n=incl)
#plot
png("hatched_image.png")
image(1:12, 1:6, data)
for(i in seq(polys)){
polygon(polys[[i]], density=10, angle=45, border=NA)
polygon(polys[[i]], density=10, angle=-45, border=NA)
}
box()
dev.off()
或者,用“点画”替代:
png("hatched_image2.png")
image(1:12, 1:6, data)
for(i in seq(polys)){
xran <- range(polys[[i]]$x)
yran <- range(polys[[i]]$y)
xs <- seq(xran[1], xran[2],,5)
ys <- seq(yran[1], yran[2],,5)
grd <- expand.grid(xs,ys)
points(grd, pch=19, cex=0.5)
}
box()
dev.off()
在(很晚)对 Paul Hiemstra 评论的回复中,这里有另外两个具有更高分辨率矩阵的示例。孵化保持一个很好的规则模式,但分解时不好看。点画的例子要好得多:
n <- 100
x <- 1:n
y <- 1:n
M <- list(x=x, y=y, z=outer(x, y, FUN = function(x,y){x^2 * y * rlnorm(n^2,0,0.2)}))
image(M)
range(M$z)
incl <- which(M$z>5e5)
polys <- matrix.poly(M$x, M$y, z=M$z, n=incl)
png("hatched_image.png", height=5, width=5, units="in", res=400)
op <- par(mar=c(3,3,1,1))
image(M)
for(i in seq(polys)){
polygon(polys[[i]], density=10, angle=45, border=NA, lwd=0.5)
polygon(polys[[i]], density=10, angle=-45, border=NA, lwd=0.5)
}
box()
par(op)
dev.off()
png("stippled_image.png", height=5, width=5, units="in", res=400)
op <- par(mar=c(3,3,1,1))
image(M)
grd <- expand.grid(x=x, y=y)
points(grd$x[incl], grd$y[incl], pch=".", cex=1.5)
box()
par(op)
dev.off()
这是使用 ggplot2 的@mdsummer 评论精神的解决方案。我先画网格,然后+
在超过某个值的位置画 es。请注意,它ggplot2
适用于data.frame
's,而不适用于多维数组或矩阵。您可以使用melt
fromreshape
包将数组 / marix 转换为 data.frame 平面结构。
这是使用文档中示例数据的具体示例geom_tile
:
pp <- function (n,r=4) {
x <- seq(-r*pi, r*pi, len=n)
df <- expand.grid(x=x, y=x)
df$r <- sqrt(df$x^2 + df$y^2)
df$z <- cos(df$r^2)*exp(-df$r/6)
df
}
require(ggplot2)
dat = pp(200)
over = dat[,c("x","y")]
over$value = with(dat, ifelse(z > 0.5, 1, 0))
ggplot(aes(x = x, y = y), data = dat) +
geom_raster(aes(fill = z)) +
scale_fill_gradient2() +
geom_point(data = subset(over, value == 1), shape = "+", size = 1)
?image
使用[1]的坐标定位机制进行。
data(volcano)
m <- volcano
dimx <- nrow(m)
dimy <- ncol(m)
d1 <- list(x = seq(0, 1, length = dimx), y = seq(0, 1, length = dimy), z = m)
通过以这种方式构建的“图像”,您可以保持与对象的结构及其坐标不变。您可以将多个矩阵收集到一个 3D 数组中或作为多个元素,但您需要扩充image()
才能处理它,因此我将它们分开放置。
制作数据副本以指定感兴趣的区域。
d2 <- d1
d2$z <- d2$z > 155
使用坐标指定感兴趣的单元格。如果您有一个非常大的光栅,这会很昂贵,但它非常容易做到。
pts <- expand.grid(x = d2$x, y = d2$y)
pts$over <- as.vector(d2$z)
设置情节。
op <- par(mfcol = c(2, 1))
image(d1)
image(d1)
points(pts$x[pts$over], pts$y[pts$over], cex = 0.7)
par(op)
不要忘记修改点的绘图以获得不同的效果,特别是具有很多点的非常密集的网格将需要很长时间才能绘制所有这些小圆圈。pch = "."
是一个不错的选择。
现在,你有一些真实的数据可以绘制在那个漂亮的投影上吗?有关某些选项,请参见此处的示例:http ://spatial-analyst.net/wiki/index.php?title=Global_datasets
[1] R 具有用于更复杂地处理栅格数据的类,请参阅包 sp 和 raster 了解两种不同的方法。
这可能来得太晚了,但我也想发布我的答案作为参考。
空间数据的一个不错的选择是使用 rasterVis 包。一旦有了“基础”光栅对象和用于绘制点画的“蒙版”对象,就可以执行以下操作:
require(raster)
require(rasterVis)
# Scratch raster objects
data(volcano)
r1 <- raster(volcano)
# Here we are selecting only values from 160 to 180.
# This will be our "mask" layer.
over <- ifelse(volcano >=160 & volcano <=180, 1, NA)
r2 <- raster(over)
# And this is the key step:
# Converting the "mask" raster to spatial points
r.mask <- rasterToPoints(r2, spatial=TRUE)
# Plot
levelplot(r1, margin=F) +
layer(sp.points(r.mask, pch=20, cex=0.3, alpha=0.8))
这类似于 OP 正在寻找的地图。可以微调点的颜色、大小和类型等参数。?sp.points 提供了所有可用于执行此操作的参数。