如何使用 R 中的 Plotly 包按两个因素分组的 3D 线图?

How to do 3D line plots grouped by two factors with the Plotly package in R?

我已经检查了 official webpage of Plotly,但是如何绘制以下任务仍然让我感到困惑:

id <- c(rep(1,5), rep(2,5), rep(3,5), rep(4,5))
t <- rep(seq(50,75,length.out=5), 4)
x <- runif(20) + sin(t) 
y <- rnorm(20) + cos(t)
gender <- c(rep("F",10), rep("M",10))
smoke <- c(rep("Y",5), rep("N",10), rep("Y",5))

DATA <- data.frame(ID, t, x, y, gender, smoke)

fig <- plot_ly(DATA, x = ~t, y = ~y, z = ~x, .......)

假设我有 4 组患者(按 2 个因素分组,Female/Male 和 Smokers/Non-smokers),每组与 5 个观察值相关 $(x_i, y_i) $ 沿着时间戳 $t_i$。所以我需要为每个患者绘制一个 3D 线图 $${(t_i, x_i, y_i)}_{i=1}^{i=5}$,但是多合一策划 canvas。如果我想用 red/blue 表示 性别,用实线表示吸烟者,用虚线 表示吸烟者,并在图例中指定这些,我应该怎么做(最好使用 R) ?

你心目中的那种3D剧情可以这样实现:

library(plotly)

id <- c(rep(1,5), rep(2,5), rep(3,5), rep(4,5))
t <- rep(seq(50,75,length.out=5), 4)
x <- runif(20) + sin(t) 
y <- rnorm(20) + cos(t)
gender <- c(rep("F",10), rep("M",10))
smoke <- c(rep("Y",5), rep("N",10), rep("Y",5))

DATA <- data.frame(id, t, x, y, gender, smoke)

col_gender <- c(M = "red", F = "blue")
lt_smoke <- c(Y = "solid", N = "dash")
sym_id <- c(`1` = "circle", `2` = "square", `3` = "diamond", `4` = "cross")

fig <- plot_ly(DATA, 
               x = ~x, y = ~y, z = ~t, symbol = ~id, color = ~gender, linetype = ~smoke, type = 'scatter3d', mode = 'lines+markers',
               line = list(width = 6),
               marker = list(size = 3.5, cmin = -20, cmax = 50),
               colors = col_gender,
               linetypes = lt_smoke,
               symbols = sym_id)
fig

编辑:

如果患者较多,最好的选择是将 id 映射到颜色上,然后使用变换 groupby

id 分组
library(plotly)

id <- c(rep(1,5), rep(2,5), rep(3,5), rep(4,5), rep(5,5), rep(6,5), rep(7,5), rep(8,5))
t <- rep(seq(50,75,length.out=5), 8)
x <- runif(40) + sin(t) 
y <- rnorm(40) + cos(t)
gender <- c(rep("F",10), rep("M",10), rep("F",10), rep("M",10))
smoke <- c(rep("Y",5), rep("N",10), rep("Y",5), rep("Y",5), rep("N",10), rep("Y",5))

lt_smoke <- c(Y = "solid", N = "dash")
sym_id <- c(M = "circle", F = "square")

fig <- plot_ly(DATA, 
               x = ~x, y = ~y, z = ~t, symbol = ~gender, color = ~id, linetype = ~smoke, type = 'scatter3d', mode = 'lines+markers',
               line = list(width = 6),
               marker = list(size = 3.5, cmin = -20, cmax = 50),
               linetypes = lt_smoke,
               symbols = sym_id,
               transforms = list(
                 list(
                   type = 'groupby',
                   groups = ~id)
               ))
fig