You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly球体按悬停值及交集区域着色技术咨询

解决方案:Plotly中基于值为球体及交集区域着色

一、单个球体按悬停值(0-500范围)用热力图调色板着色

要实现单个球体根据其悬停值映射到热力图调色板,核心是利用Plotly mesh3d 的以下参数:

  • color:为每个三角面指定对应值(若整个球体为同一值,可将该值重复赋值给所有面)
  • colorscale:选用热力图调色板(如'Viridis'、'RdYlBu')
  • cmin/cmax:固定颜色映射范围为0-500,确保不同球体的颜色对比基准一致

二、交集区域基于两球体值之和着色

交集区域的实现需先计算两个球体的重叠部分并生成对应3D网格,再将该区域的颜色映射为两球体值的总和(范围设为0-1000,适配两值最大各500的情况),确保值越大颜色越深。

完整代码示例

library(plotly)
library(misc3d)

# 定义球体方程
sphere_eq <- function(x, y, z, cx, cy, cz, r) {
  (x - cx)^2 + (y - cy)^2 + (z - cz)^2 - r^2
}

R <- 2 # 球体半径
# 生成覆盖两个球体的网格
x <- y <- z <- seq(-R, R + 2, length.out = 100) 
g <- expand.grid(x = x, y = y, z = z)

# 两个球体的参数:中心坐标+悬停值
sphere1 <- list(cx=0, cy=0, cz=0, val=150)
sphere2 <- list(cx=2, cy=2, cz=2, val=43)
intersection_val <- sphere1$val + sphere2$val

# 生成单个球体的轮廓
cont1 <- computeContour3d(with(g, sphere_eq(x, y, z, sphere1$cx, sphere1$cy, sphere1$cz, R)),
                          level = 0, x = x, y = y, z = z)
cont2 <- computeContour3d(with(g, sphere_eq(x, y, z, sphere2$cx, sphere2$cy, sphere2$cz, R)),
                          level = 0, x = x, y = y, z = z)

# 生成交集区域的轮廓:提取同时属于两个球体的点的表面
intersection_voxel <- array(
  with(g, 
       ifelse(sphere_eq(x, y, z, sphere1$cx, sphere1$cy, sphere1$cz, R) <= 0 &
                sphere_eq(x, y, z, sphere2$cx, sphere2$cy, sphere2$cz, R) <= 0,
              1, 0)),
  dim = c(100, 100, 100)
)
cont_intersect <- computeContour3d(intersection_voxel, level = 0.5, x = x, y = y, z = z)

# 生成三角面索引的工具函数
get_idx <- function(cont) {
  matrix(0:(nrow(cont)-1), ncol=3, byrow=TRUE)
}
idx1 <- get_idx(cont1)
idx2 <- get_idx(cont2)
idx_intersect <- get_idx(cont_intersect)

# 绘制可视化图形
plot_ly() |> 
  # 第一个球体
  add_trace(
    type = "mesh3d",
    x = cont1[, 1], y = cont1[, 2], z = cont1[, 3],
    i = idx1[, 1], j = idx1[, 2], k = idx1[, 3],
    opacity = 0.3,
    hoverinfo = "text",
    text = sprintf("值: %d", sphere1$val),
    color = rep(sphere1$val, nrow(idx1)),
    colorscale = "Viridis",
    cmin = 0,
    cmax = 1000, # 兼容交集的和值范围
    showscale = TRUE
  ) |> 
  # 第二个球体
  add_trace(
    type = "mesh3d",
    x = cont2[, 1], y = cont2[, 2], z = cont2[, 3],
    i = idx2[, 1], j = idx2[, 2], k = idx2[, 3],
    opacity = 0.3,
    hoverinfo = "text",
    text = sprintf("值: %d", sphere2$val),
    color = rep(sphere2$val, nrow(idx2)),
    colorscale = "Viridis",
    cmin = 0,
    cmax = 1000,
    showscale = FALSE # 仅保留一个颜色条
  ) |> 
  # 交集区域
  add_trace(
    type = "mesh3d",
    x = cont_intersect[, 1], y = cont_intersect[, 2], z = cont_intersect[, 3],
    i = idx_intersect[, 1], j = idx_intersect[, 2], k = idx_intersect[, 3],
    opacity = 0.8,
    hoverinfo = "text",
    text = sprintf("交集值: %d", intersection_val),
    color = rep(intersection_val, nrow(idx_intersect)),
    colorscale = "Viridis",
    cmin = 0,
    cmax = 1000,
    showscale = FALSE
  ) |> 
  layout(scene = list(aspectmode = "data"))

关键细节说明

  1. 颜色映射逻辑:将cmax设为1000,同时兼容单个球体的0-500值和交集的0-1000值,确保值越大颜色越深的需求。
  2. 交集计算方式:通过判断网格点是否同时属于两个球体生成voxel数据,再提取表面轮廓,保证交集区域的准确性。
  3. 视觉层次优化:调整不同trace的opacity参数,让交集区域更突出,同时保留两个球体的可见性。

内容的提问来源于stack exchange,提问作者its.me.adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:54:52