imagine I have a 3 columns matrix
x, y, z
where z is a function of x and y.
I know how to plot a "scatter plot" of these points with
plot3d(x,y,z)
But if I want a surface instead I must use other commands such as surface3d The problem is that it doesn't accept the same inputs as plot3d it seems to need a matrix with
(nº elements of z) = (n of elements of x) * (n of elements of x)
How can I get this matrix? I've tried with the command interp, as I do when I need to use contour plots.
How can I plot a surface directly from x,y,z without calculating this matrix? If I had too many points this matrix would be too big.
cheers
If your x and y coords are not on a grid then you need to interpolate your x,y,z surface onto one. You can do this with kriging using any of the geostatistics packages (geoR, gstat, others) or simpler techniques such as inverse distance weighting.
I'm guessing the 'interp' function you mention is from the akima package. Note that the output matrix is independent of the size of your input points. You could have 10000 points in your input and interpolate that onto a 10x10 grid if you wanted. By default akima::interp does it onto a 40x40 grid:
That'll look spiky and rubbish because its random data. Hopefully your data isnt!
You could look at using Lattice. In this example I have defined a grid over which I want to plot z~x,y. It looks something like this. Note that most of the code is just building a 3D shape that I plot using the wireframe function.
The variables "b" and "s" could be x or y.
You can use the function
outer()
to generate it.Have a look at the demo for the function
persp()
, which is a base graphics function to draw perspective plots for surfaces.Here is their first example:
The same applies to
surface3d()
:Maybe is late now but following Spacedman, did you try duplicate="strip" or any other option?
rgl
is great, but takes a bit of experimentation to get the axes right.If you have a lot of points, why not take a random sample from them, and then plot the resulting surface. You can add several surfaces all based on samples from the same data to see if the process of sampling is horribly affecting your data.
So, here is a pretty horrible function but it does what I think you want it to do (but without the sampling). Given a matrix (x, y, z) where z is the heights it will plot both the points and also a surface. Limitations are that there can only be one z for each (x,y) pair. So planes which loop back over themselves will cause problems.
The
plot_points = T
will plot the individual points from which the surface is made - this is useful to check that the surface and the points actually meet up. Theplot_contour = T
will plot a 2d contour plot below the 3d visualization. Set colour torainbow
to give pretty colours, anything else will set it to grey, but then you can alter the function to give a custom palette. This does the trick for me anyway, but I'm sure that it can be tidied up and optimized. Theverbose = T
prints out a lot of output which I use to debug the function as and when it breaks.The
add_rgl_model
does the same job without the options, but overlays a surface onto the existing 3dplot.So my approach would be to, try to do it with all your data (I easily plot surfaces generated from ~15k points). If that doesn't work, take several smaller samples and plot them all at once using these functions.