This is with plotly
, as I mentioned in my comment. There are means of adding lighting and all that, but it won't every render quite like rgl
. That being said, the colors looked pretty washed out. You will find that your original colors are in the comments next to the colors I used (should you want to change them back.
I used your foo
data (but didn't reiterate the code here). I set the seed to 199
, so that I would see the results consistently if you wanted to see the same output.
First, some setup:
- data for the planes (instead of using
background
)
- layout content
- content repeated for each plane (lighting)
library(plotly)
# this data will be used for all three planes
planeXy = data.frame(x = rep(c(-1.1, 1.1), 2),
y = rep(c(-1.1, 1.1), each = 2),
z = rep(-1.1, 4))
# set names for the layout of the axes
aLbls <- list(title = "PC1", title = "PC2", title = "PC3")
# set styles that apply to all three axes
# you can set a background here (instead of mesh planes),
# but opacity attached to the hex is the only way to control it
# it didn't look right, so I added the planes
bkg <- list(range = c(-1.2, 1.2),
showgrid = FALSE, # hide grid lines
zeroline = FALSE, # don't emphasize the 0 line
tickangle = -45, # -45 degree angle (labels only)
showline = TRUE, # the outside line/connected to ticks
linewidth = 4, # thickness of th line in px
ticks = "outside", # so the ticks are seen with grid hidden
ticklen = 10, # default is 5px
tickwidth = 2, # line thickness of ticks
nticks = 5) # same meaning as your rgl plot
# set lighting for mesh planes (this is reused for each axis)
lights <- list(ambient = 1, # .7 for orig colors/ avail range is 0:1
specular = 1) # shininess/ avail range 0:2
# set light position for mesh planes (this is reused for each axis)
lightpos <- list(x = -.3, y = -.5, z = .1)
Here is the plot. It may look like a lot, but the three add_trace
are nearly identical.
plot_ly(data = as.data.frame(foo), # change it back to a data frame
x = ~V1,
y = ~V2,
z = ~V3,
type = "scatter3d", # scatter plot
mode = "markers", # use points
showlegend = F, # no legend
name = "Foo Data Point",
marker = list(
size = 12, # point size
color = ifelse(foo[,4] == 1,
'#1F51FF', # '#636EFA', # original color
'#FF3131'), # '#EF553B')
# this gives the marker points a slightly darker outer ring
line = list(
color = ifelse(foo[,4] == 1,
'#2837a2', #'#45499f', # darker of orig color
'#BA0000'), # '#9a3b2a')
width = 1))) %>%
# add the planes, the only things that differ are
# the names, the arrang. of xyz and the delauney axis
add_trace(inherit = F, # xy plane
data = planeXy,
x = ~x,
y = ~y,
z = ~z,
facecolor = rep("#333777", nrow(planeXy)),
opacity = .6,
hoverinfo = "skip",
lighting = lights,
lightposition = lightpos,
name = "xy",
type = "mesh3d") %>%
# uses the same data, but the xyz is zxy
add_trace(inherit = F, # yz plane
data = planeXy,
x = ~z * -1,
y = ~x,
z = ~y,
facecolor = rep("#333777", nrow(planeXy)),
opacity = .6,
delaunayaxis = "x", # perpendicular plane
hoverinfo = "skip",
lighting = lights,
lightposition = lightpos,
name = "yx",
type = "mesh3d") %>%
# uses the same data, but the xyz is yzx
add_trace(inherit = F, # yz plane
data = planeXy,
x = ~y,
y = ~z * -1,
z = ~x,
facecolor = rep("#333777", nrow(planeXy)),
opacity = .6,
delaunayaxis = "y", # perpendicular plane
hoverinfo = "skip",
lighting = lights,
lightposition = lightpos,
name = "yx",
type = "mesh3d") %>%
# labels, axes, and initial perspective
layout(scene = list( # have to use scene when using 3D
xaxis = append(aLbls[1], bkg),
yaxis = append(aLbls[2], bkg),
zaxis = append(aLbls[3], bkg),
camera = list(eye = list(x = -1, # the initial view
y = -2,
z = .1))
))
Because plotly
uses JSON, this should work regardless of where you view it. Let me know if you have any questions or if I missed something.
This is what it looks like for me:
