【问题标题】:Contour - Plot - Ascending order等高线 - 绘图 - 升序
【发布时间】:2016-05-30 20:02:52
【问题描述】:

我有一个包含位置 (X,Y,elevation) 的矩阵。我将一列添加到我称之为“索引”的矩阵中。我从矩阵创建了一个 X 和一个 Y 向量。它们都包括索引列。然后我对刚刚创建的 X 和 Y 向量进行升序排序。然后我构造一个包含高程的 Z 矩阵,并使用索引将其与位置相关联。然后我尝试使用命令 contour (我想绘制等高线图)并且我得到错误说 X 和 Y 应该是升序......我刚刚做了!!!我做错了什么?

noeud<-read.table("position.out")
Matrice_Noeud<-matrix(ncol = ncol(noeud), nrow=nrow(noeud))
for (i in 1:nrow(noeud)) {
  for (j in 1:ncol(noeud)) {
    Matrice_Noeud[i,j]<-noeud[i,j]
  }
}

Matrice_Noeud <- cbind(Matrice_Noeud, c(seq(1,nrow(noeud),1)))


x<-data.frame(x=Matrice_Noeud[,1],Index=Matrice_Noeud[,4])
y<-data.frame(y=Matrice_Noeud[,2],Index=Matrice_Noeud[,4])

X<-x[order(x$x),]
Y<-y[order(y$y),]


Z<-matrix(NA, ncol=nrow(noeud),nrow=nrow(noeud))
for (x_i in 1:nrow(noeud)) {
  for (y_i in 1:nrow(noeud)) {
    if (Y$Index[y_i]==X$Index[x_i]) {
      niveau<-which(Matrice_Noeud[,4]==Y$Index[y_i])
      Z[x_i,y_i]<-Matrice_Noeud[niveau,3]
    }


    }
  }

Xx<-array(X[,1])
Yy<-array(Y[,1])
Zz<-data.frame(Z)

contour(Xx,Yy,Zz)

【问题讨论】:

  • length( unique(noeud[,1]) ) * length( unique(noeud[,2]) ) = nrow( noeud ) ??如果不是,contour() 无法处理数据。
  • 不,他们不是。长度(唯一(noeud[,1])= 19;长度(唯一(noeud[,2])= 12 nrow(noeud)= 121
  • 我不太明白为什么他们需要平等?我以这样的方式构造了矩阵 Z,它相当于一个带有 X 和 Y 的网格,并且 Z 的相应值被放置与它们的初始位置相关......我很困惑。你愿意跟我解释一下吗? (对不起,如果这个问题有点愚蠢,但我现在很困惑)。
  • plot(0,0, type="n",ann=F,xlim=c(0,7), ylim=c(0,6), axes=F, xaxs="i", yaxs="i") abline(v=0:7, col="#00000040"); abline(h=0:6, col="#00000040") points(0:7, rep(-0.2, 8), col="red", pch=19, xpd=T, cex=1.1) points(rep(-0.2, 7), 0:6, col="blue", pch=19, xpd=T, cex=1.1) points(expand.grid(0:7, 0:6), col="green3", pch=19, xpd=T)contour() 需要 X(红色点)、Y(蓝色)和几乎所有网格点的 Z 值(绿色)。
  • 例如,link;有 228 个 Z(上),有 121 个 Z 和 107 个 NA(下),需要插值。

标签: r plot contour


【解决方案1】:

好的,既然我已经开始做,我就做到了。

#### making example data
## assumptions: length(unique(x))=19, length(unique(y))=12, nrow(data)=121
## (They mean the number of grid points is 19 * 12 = 228, but z.value is only 121.)
xyz.f <- function(m, n) - m + (n - 7)^2 + 16         # make z from x and y (it means nothing special)
xyz <- cbind( xyz <- expand.grid(x = round(seq(11,15,,19), 2), y = round(seq(6,10,,12), 2)),
               z = apply(xyz, 1, function(k) xyz.f(k[1], k[2])) )
set.seed(1); ind <- sample(19*12, 121)               # decide to use the 121 z of 19*12
noeud <- as.matrix(xyz[ind,])                        # example data maked out

#### making contour()'s arguments
Xx <- sort(unique(noeud[,1]))
Yy <- sort(unique(noeud[,2]))    # nrow(noeud); length(Xx); length(Yy)  # OK (121, 19, 12)

Zz <- matrix(NA, ncol=length(Yy), nrow=length(Xx))           # make 19 x 12 Z matrix (empty)
# In each row, calculate x (y) value is what number in Xx (Yy)  (= the position in Z matrix)
X0 <- as.numeric( factor( noeud[,1] ) )  # (edit) using Mr.Tufte's code in R help mailing.
Y0 <- as.numeric( factor( noeud[,2] ) ) 
apply(cbind(X0, Y0, noeud[,3]), 1, function (a) Zz[ a[1], a[2] ] <<- a[3])
## contour()'s arguments ( Xx, Yy, Zz ) maked out    
contour(Xx, Yy, Zz, xlab="including NAs")  # length(Zz); length(Zz[!is.na(Zz)]) # OK (228,121)

#### interpolating
## I know few packages having interpolation functions.
library(akima)                       # use cubic spline interpolation methods of H. Akima
NOEUD <- interp(noeud[,1], noeud[,2], noeud[,3])

#### results
par.old <- par(no.readonly=T); par(mfrow=c(1,3), mar=c(4,0,1,0))
contour(Xx, Yy, Zz, xlab="including NAs", yaxt="n")    # the including NAs data
contour(NOEUD, xlab="Akima interpolation", yaxt="n")   # the Akima interpolation data
contour(Xx, Yy, matrix(xyz[,3], nrow=19), xlab="origin", yaxt="n")  # the origin data
# (edit) I noticed some interp()'s arguments make a difference (default: linear=T, extrap=F).
contour(interp(noeud[,1], noeud[,2], noeud[,3], linear=T, extrap=F), xlab="Akima interp() default")
contour(interp(noeud[,1], noeud[,2], noeud[,3], linear=F, extrap=F), xlab="interp(linear=F)")
contour(interp(noeud[,1], noeud[,2], noeud[,3], linear=F, extrap=T), xlab="interp(linear=F, extrap=T)")
par(par.old)

### supplement (using the same data, output is about the same)
noeud2 <- data.frame(x=noeud[,1], y=noeud[,2], z=noeud[,3])      # equal to the including NAs data
NOEUD2 <- cbind(expand.grid(x=NOEUD$x, y=NOEUD$y), z=c(NOEUD$z)) # equal to the Akima interpolation data
ggplot2::ggplot( noeud2, aes( x, y, z = z )) + geom_contour()  
lattice::contourplot( z ~ x * y, NOEUD2 )

【讨论】:

  • 非常感谢!我已经从您的上一条评论中设法构建了正确的 Z 矩阵(228),但我在插值方面遇到了困难。非常有帮助,再次感谢!
  • 我还想知道您构建 Z 矩阵的方式是否与我的方式相同。我的很长(有三个 for 循环),而你的看起来很简单。 [编辑]:评论中的代码很难看......我应该在哪里发布更清楚? [编辑]:我刚刚检查过,它们是等价的。感谢您的帮助,我会尝试了解您的编码方式,这样效率更高!
  • 很高兴你喜欢它。我也觉得制作 X0 和 Y0 的代码是技术性的。 X0 &lt;- sapply(noeud[,1], function(a) which(Xx == a)) 相当于它,对你有好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多