I find it challenging to create aesthetically pleasing 3D surfaces in R. I am familiar with the solutions (persp
, image
, wireframe
, lattice
, rgl
and several other solutions in other questions in SO), but the results are not nice.
Is it possible to create 3D surface plots in R like in MATLAB?
Here is the MATLAB code
% Create a grid of x and y points
points = linspace(-2, 0, 20);
[X, Y] = meshgrid(points, -points);
% Define the function Z = f(X,Y)
Z = 2./exp((X-.5).^2+Y.^2)-2./exp((X+.5).^2+Y.^2);
% "phong" lighting is good for curved, interpolated surfaces. "gouraud"
% is also good for curved surfaces
surf(X, Y, Z); view(30, 30);
shading interp;
light;
lighting phong;
title('lighting phong', 'FontName', 'Courier', 'FontSize', 14);
The plot is modern, colorful, aesthetically pleasing, the code syntax is very readable.
Is this possible in base R?
surf( X , Y , Z ) creates a three-dimensional surface plot, which is a three-dimensional surface that has solid edge colors and solid face colors. The function plots the values in matrix Z as heights above a grid in the x-y plane defined by X and Y .
3D plot in R Language is used to add title, change viewing direction, and add color and shade to the plot. The persp() function which is used to create 3D surfaces in perspective view. This function will draw perspective plots of a surface over the x–y plane.
A 3D surface plot is a three-dimensional graph that is useful for investigating desirable response values and operating conditions. A surface plot contains the following elements: Predictors on the x- and y-axes. A continuous surface that represents the response values on the z-axis.
jet.colors
is the R-answer to one of hte Matlab color palettes:
points = seq(-2, 0, length=20)
#create a grid
XY = expand.grid(X=points,Y=-points)
# A z-function
Zf <- function(X,Y){
2./exp((X-.5)^2+Y^2)-2./exp((X+.5)^2+Y^2);
}
# populate a surface
Z <- Zf(XY$X, XY$Y)
zlim <- range(Z)
zlen <- zlim[2] - zlim[1] + 1
jet.colors <- # function from grDevices package
colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan",
"#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"))
colorzjet <- jet.colors(100) # 100 separate color
require(rgl)
open3d()
rgl.surface(x=points, y=matrix(Z,20),
coords=c(1,3,2),z=-points,
color=colorzjet[ findInterval(Z, seq(min(Z), max(Z), length=100))] )
axes3d()
rgl.snapshot("copyMatlabstyle.png")
I will admit that getting the colors to line up with the "Z-axis" (which is actually the rgl y-axis) seemed very unintuitive. If you want the shiny, specular effect that Matlab delivers you can play with the angle of illumination.
You can also add or remove lighting:
clear3d(type = "lights")
light3d(theta=0, phi=0)
light3d(theta=0, phi=0) # twice as much light.
After:
grid3d("x")
grid3d("y")
grid3d("z")
rgl.snapshot("copyMatlabstyle3.png")
You could have put the y-grid "behind" the surface with:
grid3d("y+")
Similar tweaks to the axes3d
or axis3d
calls could move the location of the scales.
For further examples, look at http://rgm3.lab.nig.ac.jp/RGM/R_image_list and search for 'plot3d' which brings up examples of the Look at Karline Soetaert's plot3D package vignette, "50 ways to plot a volcano"R2BayesX::plot3d
function,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With