buhtz buhtz - 3 months ago 12
R Question

How to draw multiple 2d-plots in a 3d-plot in R?

I am not sure if I formulated the title/question correct. Maybe one of my problems are missing terms in my vocabulary. Sorry. But lets try:

I have data (

sleep
in this example) I would describe as three-dimensional. Maybe a real statistican wouldn't do that?

I think I want to draw multiple two-dimensional plots into a three-dimensial one. I want to plot them side by side. Please correct me if I am wrong.

enter image description here

My problem here is that there is only one line.
There are two groups. I want one line per group. The same data with
type='h'
give a better description I think:

enter image description here

Can you imagine the two lines here? What I am missing in that concept?
We could use another ploting library for printing/publication. Currently it doesn't matter for me which one. Maybe I am totaly at the wrong place?

This is the code:

require('mise')
require('scatterplot3d')
mise() # clear the workspace

# example data
print(sleep)

scatterplot3d(x=sleep$ID,
x.ticklabs=levels(sleep$ID),
y=sleep$group,
y.ticklabs=levels(sleep$group),
lab = c(length(unique(sleep$ID)), 1),
z=sleep$extra,
type='o')


And the data

extra group ID
1 0.7 1 1
2 -1.6 1 2
3 -0.2 1 3
4 -1.2 1 4
5 -0.1 1 5
6 3.4 1 6
7 3.7 1 7
8 0.8 1 8
9 0.0 1 9
10 2.0 1 10
11 1.9 2 1
12 0.8 2 2
13 1.1 2 3
14 0.1 2 4
15 -0.1 2 5
16 4.4 2 6
17 5.5 2 7
18 1.6 2 8
19 4.6 2 9
20 3.4 2 10

Answer

You could add the lines manually in two steps:

# Store the plot in rr
rr <- scatterplot3d(x=as.numeric(sleep$ID),
                    x.ticklabs=levels(sleep$ID),
                     y=sleep$group,
                     y.ticklabs=levels(sleep$group),
                     z=sleep$extra)
# find all that belong to group one
idx = sleep$group == 1
# add the first line
rr$points3d(x = sleep$ID[idx], y = rep(1, each = sum(idx)), z = sleep$extra[idx], type = 'l', col = 'red')
# add the second line
rr$points3d(x = sleep$ID[!idx], y = rep(2, each = sum(!idx)), z = sleep$extra[!idx], type = 'l', col = 'blue')

So to add ribbons instead of lines things change a bit. In particular, the ribbons are plotted with the polygon function. However, this function only handles 2D coordinates, so we need to transform our 3D coordinates to 2D coordinates with the function rr$xyz.convert.

rr <- scatterplot3d(x=sleep$ID,
                    x.ticklabs=levels(sleep$ID),
                     y=sleep$group,
                     y.ticklabs=levels(sleep$group),
                     z=sleep$extra)
idx = sleep$group == 1
# draw first group
mat = matrix(c(rep(sleep$ID[idx], 2),
               rep(c(1, 1.05), each = sum(idx)), # 1.05 determines width
               rep(sleep$extra[idx], 2)), ncol = 3)
ll = rr$xyz.convert(mat)
polygon(x = ll$x[c(1:10, 20:11)], 
        y = ll$y[c(1:10, 20:11)], col = 'red')
# draw second group
mat = matrix(c(rep(sleep$ID[!idx], 2),
               rep(c(2, 1.95), each = sum(!idx)), # 1.95 determines width
               rep(sleep$extra[!idx], 2)), ncol = 3)
ll = rr$xyz.convert(mat)
polygon(x = ll$x[c(1:10, 20:11)], 
        y = ll$y[c(1:10, 20:11)], col = 'blue')