1

我试图用两个横截面的表面制作一个 plot_ly 表面图,即在 Z 平面上映射一个表面,在 X 平面上映射另一个表面。

z 平面上的表面工作正常,但在另一个平面上添加第二个表面让我绊倒了。我可能对 plot_ly 如何处理数据有误解。

我正在尝试做这样的事情,但我无法从这个情节中获取代码在我自己的 R (RStudio) https://plot.ly/~schippkus/0/slices-in-volumetric-data/ #阴谋

这是一个具有单面工作的可重现示例,而两个面是奇数。此示例中创建的数据与我正在处理的数据具有相同的维度。它最初以 3 维数组的形式出现,我强制采用这种格式。

library(plotly); library(tidyverse); 

    x = 1:91
    y = 1:109
    z = 1:91

    val = as.numeric(scale(sample(length(x)*length(y)*length(z))))

    DATA = expand.grid(X=x,Y=y,Z=z) %>% as.data.frame() %>% 
      mutate(Val = val)

    getTrace = function(data,plane,slice){
      require(tidyverse)
      tmp = data %>% filter(get(plane) %in% slice)

      Trace = list(
        x = tmp %>% select(X) %>% unique() %>% unlist() %>% unname(),
        y = tmp %>% select(Y) %>% unique() %>% unlist() %>% unname(),
        z = tmp %>% select(Z) %>% unique() %>% unlist() %>% unname()
      )

      switch(plane,
             "Z"={
               oneplane = expand.grid(x = Trace$x, y = Trace$y)
               oneplane$z <- tmp %>% select(Val) %>% unlist() %>% unname()

               Trace$SurfaceColor = as.matrix(spread(oneplane, key = x, value = z)[, -1]) %>% unname()
               Trace$z <- matrix(slice, ncol=ncol(Trace$SurfaceColor), nrow=nrow(Trace$SurfaceColor))
               Trace
             },
             "Y"={
               oneplane = expand.grid(x = Trace$x, z = Trace$z)
               oneplane$y <- tmp %>% select(Val) %>% unlist() %>% unname()

               Trace$SurfaceColor = as.matrix(spread(oneplane, key = z, value = y)[, -1]) %>% unname()
               Trace$y <- matrix(slice, ncol=ncol(Trace$SurfaceColor), nrow=nrow(Trace$SurfaceColor))
               Trace
             },
             "X"={
               oneplane = expand.grid(y = Trace$y, z = Trace$z)
               oneplane$x <- tmp %>% select(Val) %>% unlist() %>% unname()

               Trace$SurfaceColor = as.matrix(spread(oneplane, key = y, value = x)[, -1]) %>% unname()
               Trace$x <- matrix(slice, ncol=ncol(Trace$SurfaceColor), nrow=nrow(Trace$SurfaceColor))
               Trace
             }
      )
    }

    Trace1 = getTrace(DATA,"Z",45)
    Trace2 = getTrace(DATA,"Y",45)

    # This works as intended (except I can't seem to make the surface greyscale)
    plot_ly() %>% 
      add_trace(x=Trace1$x,
                y=Trace1$y,
                z=Trace1$z, 
                type="surface", 
                cauto=T,
                surfacecolor=Trace1$SurfaceColor,
                colorscale=c("white","black")
      )  %>%
      layout(title="Ok one-surface plot",
             scene = list(
        aspectratio = list(
          x = 91/109, 
          y = 1, 
          z = 91/109
        ), 
        xaxis = list(
          backgroundcolor = "rgb(230, 230,230)", 
          gridcolor = "rgb(255, 255, 255)", 
          showbackground = TRUE, 
          zerolinecolor = "rgb(255, 255, 255)",
          range=c(1,91)
        ), 
        yaxis = list(
          backgroundcolor = "rgb(230, 230,230)", 
          gridcolor = "rgb(255, 255, 255)", 
          showbackground = TRUE, 
          zerolinecolor = "rgb(255, 255, 255)",
          range=c(1,109)
        ), 
        zaxis = list(
          backgroundcolor = "rgb(230, 230,230)", 
          gridcolor = "rgb(255, 255, 255)", 
          range = c(1, 91), 
          showbackground = TRUE, 
          zerolinecolor = "rgb(255, 255, 255)"
        )
      ))

    # This definately does not do as intended
    plot_ly() %>% 
      add_trace(x=Trace1$x,
                y=Trace1$y,
                z=Trace1$z, 
                type="surface", 
                cauto=T,
                surfacecolor=Trace1$SurfaceColor,
                colorscale=c("white","black")
      ) %>%
      add_trace(x=Trace2$x,
                y=Trace2$y,
                z=Trace2$z, 
                type="surface", 
                cauto=T,
                surfacecolor=Trace2$SurfaceColor,
                colorscale=c("white","black")
      ) %>%
      layout(title="Bogus plot",
             scene = list(
               aspectratio = list(
                 x = 91/109, 
                 y = 1, 
                 z = 91/109
               ), 
               xaxis = list(
                 backgroundcolor = "rgb(230, 230,230)", 
                 gridcolor = "rgb(255, 255, 255)", 
                 showbackground = TRUE, 
                 zerolinecolor = "rgb(255, 255, 255)",
                 range=c(1,91)
               ), 
               yaxis = list(
                 backgroundcolor = "rgb(230, 230,230)", 
                 gridcolor = "rgb(255, 255, 255)", 
                 showbackground = TRUE, 
                 zerolinecolor = "rgb(255, 255, 255)",
                 range=c(1,109)
               ), 
               zaxis = list(
                 backgroundcolor = "rgb(230, 230,230)", 
                 gridcolor = "rgb(255, 255, 255)", 
                 range = c(1, 91), 
                 showbackground = TRUE, 
                 zerolinecolor = "rgb(255, 255, 255)"
               )
             ))
4

1 回答 1

1

在 Trace2 中,z是一个整数。而且我相信,z在这两个痕迹中都需要一个矩阵才能工作。

> class(Trace2$y)
[1] "matrix"
> class(Trace2$z)
[1] "integer"

因此,使用两个z矩阵的更简单示例,它可以工作。在第一个矩阵中,所有 z 值都相同(矩阵 2 = 6)。但在第二种情况下,y值是恒定的,但z值是不同的。

matrix2 <- c(
  c(6,6,6,6,6,6),
  c(6,6,6,6,6,6),
  c(6,6,6,6,6,6),
  c(6,6,6,6,6,6)
)
dim(matrix2) <- c(6,4)

x <- c(1,2,3,4,5, 6)
y <- c(1,2,3,4)
rownames(matrix2) <- x
colnames(matrix2) <- y


plot_ly() %>% add_surface(z~matrix2, x= x, y = y)

matrix22 <- c(
  c(5,5.5,6,6.5),
  c(5,5.5,6,6.5),
  c(5,5.5,6,6.5),
  c(5,5.5,6,6.5)
)
dim(matrix22) <- c(4,4)

x2 <- c(1,2,3,4)
y2 <- c(3,3,3,3)
rownames(matrix22) <- x2
colnames(matrix22) <- y2

plot_ly() %>% add_surface(z~matrix22, x= x2, y = y2) %>% add_surface(z~matrix2, x= x, y = y)

给出了这个:

在此处输入图像描述

于 2018-01-26T11:13:35.050 回答