0
votes

I am trying to plot two sets of points in the same 3D scatterplot using interactive "rgl" package for R

this is the data:

> head(tsne_train)
           X1         X2          X3
2   18.940912 -46.761145 -56.1818708
4   17.768953  68.678871   0.8070582
6   -2.440751 -53.021051  55.0437596
7   44.740812  -2.347877 -54.1501468
8  -87.924687  15.354890 -30.1806330
12  21.991465  38.406572 -33.0551010`

> head(tsne_test)
          X1         X2          X3
1   1.585156  71.568255    7.438958
3  62.204021  -3.817038  -37.609328
5   5.422276 -21.855152   66.865478
9  21.223133 -29.763255 -107.832779
10  9.037427 -62.816717   65.560664
11 24.775047 -51.820532   57.106795

this is what I tried so far:

scatter3d( x=tsne_train[,1],y=tsne_train[,2],z=tsne_train[,3],
          groups = train$Result,
          surface=F, grid = T, ellipsoid = FALSE,sphere.size = 1.5,
          surface.col = c("red", "orange", "green"),fogtype="none",
          axis.col=c("black","black","black"))

produces: enter image description here

and

scatter3d(x=tsne_test[,1],y=tsne_test[,2],z=tsne_test[,3], groups = test$Result,
                surface=F, grid = T, ellipsoid = FALSE,sphere.size = 1.5,
                col = c("purple", "blue", "cyan"), fogtype="none",
                axis.col=c("black","black","black"))

produces: enter image description here

I want all the points in one scatterplot but preserving the color grouping (6 colors in total). Kind of like overlaying plot 2 over plot 1

Using spheres3d to add more points to a plot leads to this mess:

spheres3d(x=tsne_test[,1],y=tsne_test[,2],z=tsne_test[,3],
         surface=F, grid = T,
         col = c("purple", "blue", "cyan"), sphere.size = 3,
         axis.col=c("black","black","black"))

enter image description here

this does not preserve the green/red/orange points from plot #1, the axes aren't visible and the position of the points looks off since plot #2 looks nothing like it. Maybe I am just using spheres3d wrong?

1
Welcome to Stack Overflow Dumitrescu Calin! You may want to ensure yourself, that you share all necessary data (e.g. train) and state all library calls (e.g. car)to enable us to reproduce your code. - jay.sf
scatter3d is not an rgl function. There's a function by that name in the car package. It rescales points before it plots them, so you'll need to figure out how to do the same rescaling to add your points. - user2554330
It appears the rescaling is simply (x - minx)/(maxx - minx) (and similarly for y and z). You should be able to do the same if you use the min and max from the first plot to transform the values in the spheres3d call. - user2554330

1 Answers

0
votes

Here is some code based on my suggestions. We don't have your real data, so I've used the data that you gave, with random values for groups.

tsne_train <- read.table(textConnection(
"           X1         X2          X3
2   18.940912 -46.761145 -56.1818708
4   17.768953  68.678871   0.8070582
6   -2.440751 -53.021051  55.0437596
7   44.740812  -2.347877 -54.1501468
8  -87.924687  15.354890 -30.1806330
12  21.991465  38.406572 -33.0551010"
), header=TRUE)
trainGroup <- factor(sample(1:3, 6, replace=TRUE))

tsne_test <- read.table(textConnection(
"          X1         X2          X3
1   1.585156  71.568255    7.438958
3  62.204021  -3.817038  -37.609328
5   5.422276 -21.855152   66.865478
9  21.223133 -29.763255 -107.832779
10  9.037427 -62.816717   65.560664
11 24.775047 -51.820532   57.106795"
), header=TRUE)
testGroup <- factor(sample(1:3, 6, replace=TRUE))

scatter3d(x = tsne_train[,1],
          y = tsne_train[,2],
          z = tsne_train[,3],
          groups = trainGroup,
          surface=FALSE, 
          grid = TRUE, 
          ellipsoid = FALSE,
          sphere.size = 1.5,
          surface.col = c("red",  "orange", "green"),
          fogtype = "none",
          axis.col = c("black","black","black"))
spheres3d(x = (tsne_test[,1]-min(tsne_train[,1]))/
              (max(tsne_train[,1]) - min(tsne_train[,1])),
          y = (tsne_test[,2]-min(tsne_train[,2]))/
              (max(tsne_train[,2]) - min(tsne_train[,2])),
          z = (tsne_test[,3]-min(tsne_train[,3]))/
              (max(tsne_train[,3]) - min(tsne_train[,3])),
          col = c("purple", "blue", "cyan")[testGroup], 
          radius = 0.1)

Here's what the plot looks like:

screenshot

This would all be easier if you didn't use the scatter3d function, you stuck with rgl functions. For example,

plot3d( x = tsne_train,
            col = c("red", "orange", "green")\[trainGroup\], 
            type="s")
spheres3d(x = tsne_test,
          col = c("purple", "blue", "cyan")\[testGroup\], 
          radius = 3)

This produces the following plot:

screenshot