简体   繁体   中英

Trajectory Plot inside of 3D transparent sphere using R

I want to make a trajectory plot of my df inside of a transparent 3d sphere.

I searched the stackoverflow but couldn't find the same question. So it might be helpful for everybody who is interested about trajectory of their vectors.

The df could be like this

df <- data.frame(mx=runif(100,-0.05,0.05),
             my=runif(100,-1,1),
             mz=runif(100,-0.5,0.5))

在此输入图像描述

I agree with Frank's answer. If what you want to do is to plot trajectories on a sphere like the supplied picture, you should be a bit more careful, since ordinary interpolation won't give paths on the sphere. There are different options, but the easiest is probably to just project the paths onto the sphere.

require(rgl)

# Construct a Brownian motion on a sphere
n <- 100
sigma <- 0.5

df <- array(NA, dim = c(n, 3))
df[1, ] <- rnorm(3, sd = sigma) # Starting point
df[1, ] <- df[1, ] / sqrt(sum(df[1, ]^2))
for (i in 2:n) {
  df[i, ] <- rnorm(3, sd = sigma) + df[i - 1, ]
  df[i, ] <- df[i, ] / sqrt(sum(df[i, ]^2))
}

# Linear interpolation of observed trajectories, but projected onto sphere
times <- seq(1, n, length = 1000)

xx <- approx(1:n, df[, 1], xout = times)$y
yy <- approx(1:n, df[, 2], xout = times)$y
zz <- approx(1:n, df[, 3], xout = times)$y
df_proj <- cbind(xx, yy, zz)
df_proj <- df_proj / sqrt(rowSums(df_proj ^2))

# Plot
plot3d(df_proj, type = 'l', col = heat.colors(1000), lwd = 2, xlab = 'x', ylab = 'y', zlab = 'z')
rgl.spheres(0, 0, 0, radius = 0.99, col = 'red', alpha = 0.6, back = 'lines')

球体上的轨迹

You can of course do the same thing with the smooth trajectories from Frank's answer:

# Smooth trajectories plot

times <- seq(1, n, length = 1000)
xx <- spline(1:n, df[, 1], xout = times)$y
yy <- spline(1:n, df[, 2], xout = times)$y
zz <- spline(1:n, df[, 3], xout = times)$y

df_smooth <- cbind(xx, yy, zz)
df_smooth <- df_smooth / sqrt(rowSums(df_smooth^2))

plot3d(df_smooth, type = 'l', col = heat.colors(1000), lwd = 2, xlab = 'x', ylab = 'y', zlab = 'z')
rgl.spheres(0, 0, 0, radius = 0.99, col = 'red', alpha = 0.6, back = 'lines')

在此输入图像描述

You can connect the points inside the sphere using type="l" in plot3d and plot the sphere using spheres3d :

library(rgl)
plot3d(df, type="l", axes=FALSE) # type="l" is for "line"
spheres3d(0,0,0, radius=1, alpha=0.3, back="cull") # transparency set by alpha from 0 to 1

在此输入图像描述

Or to use splines to make a "smooth" trajectory, taking from Duncan Murdoch :

xx <- splinefun(seq_along(df$mx), df$mx)
yy <- splinefun(seq_along(df$my), df$my)
zz <- splinefun(seq_along(df$mz), df$mz)
times<-seq(1, dim(df)[1], len=2000) # vary length to change smoothness

plot3d(xx(times), yy(times), zz(times), type="l", axes=FALSE) 
spheres3d(0,0,0, radius=1, alpha=0.3, back="cull")

在此输入图像描述

As you can see, this way, you may end up with a line outside of the radius of 1, so you can simply increase the radius of the sphere either by entering a larger number for radius or by using radius=max(xx(times), yy(times), zz(times))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM