R_User R_User - 1 month ago 20
R Question

plotting 3D data in R

I have a 3D dataset:

data = data.frame(
x = rep( c(0.1, 0.2, 0.3, 0.4, 0.5), each=5),
y = rep( c(1, 2, 3, 4, 5), 5)
)

data$z = runif(
25,
min = (data$x*data$y - 0.1 * (data$x*data$y)),
max = (data$x*data$y + 0.1 * (data$x*data$y))
)

data
str(data)


And I want to plot it, but the built-in-functions of R alwyas give the error


increasing 'x' and 'y' values expected


# ### 3D Plots ######################################################
# built-in function always give the error
# "increasing 'x' and 'y' values expected"
demo(image)
image(x = data$x, y = data$y, z = data$z)

demo(persp)
persp(data$x,data$y,data$z)

contour(data$x,data$y,data$z)


When I searched on the internet, I found that this message happens when combinations of X and Y values are not unique. But here they are unique.

I tried some other libraries and there it works without problems. But I don't like the default style of the plots (the built-in functions should fulfill my expectations).

# ### 3D Scatterplot ######################################################
# Nice plots without surface maps?
install.packages("scatterplot3d", dependencies = TRUE)
library(scatterplot3d)
scatterplot3d(x = data$x, y = data$y, z = data$z)

# ### 3D Scatterplot ######################################################
# Only to play around?
install.packages("rgl", dependencies = TRUE)
library(rgl)
plot3d(x = data$x, y = data$y, z = data$z)
lines3d(x = data$x, y = data$y, z = data$z)
surface3d(x = data$x, y = data$y, z = data$z)


Why are my datasets not accepted by the built-in functions?

Thanks for your help,

Sven

Answer

If you're working with "real" data for which the grid intervals and sequence cannot be guaranteed to be increasing or unique (hopefully the (x,y,z) combinations are unique at least, even if these triples are duplicated), I would recommend the akima package for interpolating from an irregular grid to a regular one.

Using your definition of data:

library(akima)
im <- with(data,interp(x,y,z))
with(im,image(x,y,z))

enter image description here

And this should work not only with image but similar functions as well.

Note that the default grid to which your data is mapped to by akima::interp is defined by 40 equal intervals spanning the range of x and y values:

> formals(akima::interp)[c("xo","yo")]
$xo
seq(min(x), max(x), length = 40)

$yo
seq(min(y), max(y), length = 40)

But of course, this can be overridden by passing arguments xo and yo to akima::interp.

Comments