Making a wireframe plot from an x,y,z data.frame - r

I have a data.frame of x/y/z points. I know how to make a 3d scatterplot using the rgl package but I would like to connect each point in the scatterplot to make a wireframe or surface plot.
This code returns the scatter plot
library(rgl)
Data <- expand.grid(x=seq(0,10),y=seq(0,10))
Data$z <- Data$x^2+Data$y^2
plot3d(Data)
While this code returns a blank graph:
plot3d(Data,type='wire')
I can make the plot I want with lattice:
library(lattice)
wireframe(z~x+y,Data)
I can even make it rotate:
library(TeachingDemos)
rotate.wireframe(z~x+y,Data)
But I prefer rgl over lattice because it renders much quicker and lets you rotate the plot with the mouse.
Whats the proper way to make a wireframe plot in rgl?

The surface drawing plot function in rgl is persp3d and like base::persp, it needs a matrix as input to the z argument
zmat <- matrix(Data$z, 11,11)
persp3d(x=seq(0,10), y=seq(0,10), z=zmat)
I did spin this graphic a bit before capturing it with a screen grabbing program I use:

Related

rgl 3D scatterplot - controlling size of spheres from 4th dimension (bubble plot)

I am working on a 3D scatter plot using rgl package in R, with multiple colors for different series. I was wondering if there would be a way to plot a 4th dimension by controlling the size of spheres.
I know it's possible with plotly ("bubble plot") : https://plot.ly/r/3d-scatter-plots/, but Plotly starts to flicker when dealing with lots of datapoints. Can the same result be achieved using Rgl?
set.seed(101)
dd <- data.frame(x=rnorm(100),y=rnorm(100),z=rnorm(100),
c=rnorm(100),s=rnorm(100))
Scaling function (I tweaked to keep the values strictly in (0,1), don't know if that's really necessary):
ss <- function(x) scale(x,center=min(x)-0.01,scale=diff(range(x))+0.02)
library(rgl)
Define colours (there may be a better way to do this ...)
cvec <- apply(colorRamp(c("red","blue"))(ss(dd$c))/255,1,
function(x) rgb(x[1],x[2],x[3]))
The picture (need type="s" to get spheres)
with(dd,plot3d(x,y,z,type="s",radius=ss(s), col=cvec))

Adding a polar background to a ggplot without using polar coordinates

I'd like make a plot using cartesian coordinate system, but then have it overlaid on a polar plot background, like that produced by coord_polar. Panel.background from theme.R only has element_rect; Ideally I could use something like element_polar.
Any way to do this?
Simply using coord_polar doesn't work because I'm also plotting various other geoms that map idiosyncratically onto coord_polar (geom_ellispis from the ggforce package, for example).
Reproducible example code:
library(ggplot2)
library(ggforce) # NB this is the github version #install_github("thomasp85/ggforce"). Includes 'geom_ellipsis'
#### Make example data
r<-runif(50,-100,100) # radial coordinates
theta<-runif(50,0,2) # theta
a<-runif(50,1,20)
b<-runif(50,1,20)
# Convert r and theta to cartesian:
x<-r*cos(theta*pi) # x-coordinate of ellipse foci
y<-r*sin(theta*pi) # y-coordinate of ellipse foci
angle.random<-runif(50,min=0,max=2) # random angle for ellipsis rotation
df<-as.data.frame(cbind(r,theta,x,y,a,b,angle.random))
# Make plots
# Plot should look like this:
ggplot(df,aes(x,y))+
geom_point(aes(x,y))+
geom_ellipsis(data=df,aes(x0=x,y0=y,a=a,b=b,angle=angle.random,fill=T))
# But I want the panel background in polar coordinates (and auto-adjusing to scale), like this:
ggplot(df,aes(x,y))+
geom_point(aes(x,y))+
coord_polar()
# However, using geom_ellipsis (among other functions) has idiosyncratic effects in non-cartesian coordinate systems:
ggplot(df,aes(r,theta))+
geom_point(aes(x,y))+
geom_ellipsis(data=df,aes(x0=x,y0=y,a=a,b=b,angle=angle.random,fill=T))+
coord_polar()
I would like the polar background from the 3rd plot, with the un-distorted ellipses from the first plot. Is there any way to do this?

rgl plot3d plotting points (spheres) with vertical lines to x–y plane

I am using rgl plot3d function to plot 3d points from Multidimensional scaling. So far I can draw the points as spheres using type="s", I can rotate the plots as I need:
plot3d(x,y,z,type = "s", col=rainbow(20), size= 4,xlab="F1",ylab="F2",zlab="F3",main=title.main,box=TRUE,top=TRUE).
I know that I can get this using rgl scatter3d function but this is used scatters/regression ... and I can also do this with scatterplot3d, but I can't rotate this one. I would have imagined that if it is possible to do this using rgl scatter3d function. I would expect that it would be easy in rgl plot3d function... but I haven't figure out how to plot these vertical lines from the points(spheres) using plot3d? If I use type = "h" it only draws vertical lines to the x–y plane and I don't see a separate parameter to draw the spheres.
Try:
> x=1:10
> y=21:30
> z=51:60
> plot3d(x,y,z, type='s')
> plot3d(x,y,z, type='h',add=TRUE)

Add a curve to a log/log scatterplot

I have a scatterplot in a log/log space
plot(a,b,log="xy")
or in ggplot2
qplot(a,b,data="time",log="xy")
Now I would like to impose upon this scatter plot the curve f(x)=x*x+2. Butthe function woudl need to be plotted in the logarithmic space as well. How would I do this? Is there an way to do this in ggplot2?
As you guessed, curve is the command that you're looking for in base graphics.
#Make up some data
set.seed(0)
a <- 1:10
b <-(a^2+2)*exp(0.1*rnorm(10))
plot(a,b,log='xy')
curve(x^2+2,add=TRUE)
in ggplot2 world:
qplot(a,b,data=time)+stat_function(fun=function(x){x^2+2}) + coord_trans(xtrans = "log10",ytrans="log10")
from Plotting in R using stat_function on a logarithmic scale seems to do what you're after.

Save the orientation of a RGL plot3d() plot

I have a 3D plot using RGL. I would like to make identical plots using color to highlight the distribution of some variable. To do this I would like to have identical plots, how do I find and set the orientation of a plot?
Once I make a preliminary plot, I move it around to find a nice display angle and I would like to save that angle and incorporate it into future plotting scripts. Anyone have a suggestion on how to do this?
library(rgl)
plot3d(iris)
#play with the plot to find a good angle
#save the angle for future plots
Ben's comment basically answers your question; this just applies expand.dots to what he wrote ;)
## In an inital session:
library(rgl)
plot3d(iris)
## Now move the image around to an orientation you like
## Save RGL parameters to a list object
pp <- par3d(no.readonly=TRUE)
## Save the list to a text file
dput(pp, file="irisView.R", control = "all")
.......
## Then, in a later session, to recreate the plot just as you had it:
library(rgl)
pp <- dget("irisView.R")
plot3d(iris)
par3d(pp)

Resources