在曲面上使用条件着色

时间:2017-03-22 21:45:51

标签: r 3d plotly

我第一次通过R使用plotly并尝试从网格创建表面并根据计算对其进行着色。

例如,我想使用data(volcano)中的曲面,如

library(plotly)
plot_ly(z = ~volcano) %>% add_surface()

enter image description here

但是不是基于z值(海拔高度)的颜色,我只想说我想根据我家在(20,60)的小台面上的距离进行着色。

house_loc <- c(20,60,150) # (x,y,z) of my house
dist_to_house <- Vectorize(function(x,y,z){sqrt(sum( (c(x,y,z)-house_loc)^2 ))})

到目前为止,我已经尝试过:

color_me <-function(x){
  colorRampPalette(c('tan','blue')
  )(24L)[findInterval(x,seq(0,1,length.out=25),
                      all.inside=TRUE)]
} 

library(dplyr)
library(reshape2)
volcano %>% 
     melt( varnames=c('y','x'),value.name='z' ) %>%
     mutate( d = dist_to_house(x, y, z) ,
             d_rel = d/max(d),
             d_color = color_me(d_rel) 
     ) -> df

plot_ly(df,
        type='scatter3d',
        mode='none', # no markers, just surface
        x=~x,
        y=~y,
        z=~z,
        surfaceaxis=2,
        surfacecolor=~d_color) # last argument seems not to work

刚刚回归:

enter image description here

期望的结果将使房屋区域的景观变成棕褐色,并在远离房屋的区域逐渐淡化为蓝色。

有些related question使用其他地方找到的mesh3d代码,但没有解释如何计算(i,j,k)

2 个答案:

答案 0 :(得分:3)

您的代码几乎拥有您需要的一切,只需使用surface绘图并将距离数组用作color

library(plotly)
library(dplyr)
library(reshape2)

house_loc <- c(20,60,150)
dist_to_house <- Vectorize(function(x,y,z){sqrt(sum( (c(x,y,z)-house_loc)^2 ))})

volcano %>% 
  melt( varnames=c('y','x'),value.name='z' ) %>%
  mutate( d = dist_to_house(x, y, z) ,
          d_rel = d/max(d)
  ) -> df

color <- df$d_rel
dim(color) <- dim(volcano)

plot_ly(df,
        type='surface',
        z=volcano,
        surfacecolor=color,
        colors=c('tan','blue'))

enter image description here

答案 1 :(得分:0)

除了surface情节(参见接受的答案)之外,我们还可以制作mesh3d情节并避免情节所需的重塑(回到网格)步骤。

但是,比例尺仍然不对(显示z的范围,而不是d_rel

plot_ly(df,
        type='mesh3d',
        x = ~x,
        y = ~y,
        z = ~z,
        intensity=~d_rel,
        colors = colorRamp(c("tan", "blue"))
    )

与直觉相反,intensity=而非color=似乎控制了条件着色。

enter image description here

我最初避免mesh3d,因为我认为我必须创建一个三角形网格(Delaunay或其他东西)并且不知道如何做到这一点,但在这种情况下似乎会自动处理。