The problem is the argument z
and the ordering of both x
and y
. As shadow mentions in the comments this needs to be a matrix of dim(z) = length(x) x length(y)
in this case 100x100
. And apparently x and y need to be both ordered at the same time exactly as shadow mentions above which is seen in the source code of persp.default
as.well:
if (any(diff(x) <= 0) || any(diff(y) <= 0)) #both need to be ordered
stop("increasing 'x' and 'y' values expected")
So the following works:
lng=runif(100,1,4)
lat=runif(100,40,40.1)
z=matrix(rnorm(10000),ncol=100,nrow=100) #use the correct z as matrix
data=data.frame(lng,lat)
data=data[ order(data[,1],data[,2]), ] #just order lng as you do
data$lat <- sort(data$lat) #you need to sort lat too
persp(data[,1] ,data[,2], z)
And this works now.

Edit
I think what you really want to do is to have you lan/lng coordinates in z and plot them. The z
argument needs to carry the coordinates. the x and y arguments just carry the values of the x and y axes respectively. You can use the default x and y argumens (i.e. leave them blank) or just sort lan and lng separately to provide the real values. So, the solution you are looking for is:
lng=runif(100,1,4)
lat=runif(100,40,40.1)
z= as.matrix(data.frame(lng=lng,lat=lat))
z=matrix(rnorm(10000),ncol=100,nrow=100) #z contains lan and lng
#plot z with default x and y values (or use sorted lng and lat instead)
persp( z = z)
Which outputs:
