【问题标题】:Use conditional coloring on a plotly surface在绘图表面上使用条件着色
【发布时间】:2017-03-22 21:45:51
【问题描述】:

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

例如,我想使用来自data(volcano)的表面,如

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

但不是基于 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

刚刚返回:

理想的结果是将房屋区域的景观染成棕褐色,并在远离房屋的区域逐渐褪色为蓝色。

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

【问题讨论】:

    标签: r 3d plotly


    【解决方案1】:

    您的代码几乎拥有您需要的一切,只需使用 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'))
    

    【讨论】:

    • 感谢您提醒我有关颜色的信息!我将其添加到答案中。
    • 您好 - 我一直在尝试做类似的事情,这是我最接近解决方案的方法,但它在我的实现中仍然不起作用。我正在尝试将颜色矩阵映射到平坦的 3D 表面(即平板,本质上是漂浮在 3d 平面中的 2d 热图)。一旦我将此代码与全 1 的 z 矩阵和可变颜色矩阵作为表面颜色一起使用,我就会得到一个单色表面。知道我做错了什么吗?
    • @renegademonkey:请将其作为一个单独的问题与您的代码一起发布,我相信有人可以帮助您。
    【解决方案2】:

    除了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=

    我最初避免使用mesh3d,因为我认为我必须创建一个三角形网格(Delaunay 之类的)并且不知道如何做到这一点,但在这种情况下它似乎是自动处理的。

    【讨论】:

    • 如果有人知道如何修复比例尺,请评论或回答。
    猜你喜欢
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2015-06-11
    • 2012-10-30
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多