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

如何用光学显微镜图像为Plotly表面图着色(独立于Z值)

解决方案:Plotly Surface图叠加光学显微镜RGB颜色

Plotly的Surface组件不直接支持传入(rows, cols, 3)的RGB数组作为surfacecolor,它要求surfacecolor是2D数值数组,再通过色阶映射颜色。要实现每个像素独立对应光学图像的RGB颜色,需要通过「索引映射+自定义色阶」的方式实现,具体步骤如下:

核心思路

  1. 给光学图像的每个像素分配唯一的数值索引
  2. 构建自定义色阶,让每个索引对应光学图像中该位置的RGB颜色
  3. 强制Plotly使用我们指定的索引范围作为色阶边界,避免自动压缩色阶

完整代码示例

import numpy as np
import plotly.graph_objects as go

# 假设:
# surface_data: 形状(206,247)的numpy数组,对应3D表面Z值
# surface_color: 形状(206,247,3)的uint8数组,对应光学显微镜RGB图像(像素值0-255)
rows, cols = surface_data.shape

# 1. 创建2D索引数组:每个像素对应唯一的数值索引
color_indices = np.arange(rows * cols).reshape(rows, cols)

# 2. 构建自定义色阶:每个索引对应对应的RGB颜色
colorscale = []
total_pixels = rows * cols
for idx in range(total_pixels):
    # 提取当前索引对应的RGB值
    r, g, b = surface_color.flatten()[idx*3 : (idx+1)*3]
    # 色阶格式为[归一化索引, 'rgb(r,g,b)']
    colorscale.append([idx / (total_pixels - 1), f'rgb({r}, {g}, {b})'])

# 3. 创建Surface图并配置关键参数
fig = go.Figure(data=go.Surface(
    z=surface_data,
    surfacecolor=color_indices,
    colorscale=colorscale,
    cmin=0,               # 色阶最小值,对应第一个索引
    cmax=total_pixels - 1,# 色阶最大值,对应最后一个索引
    cauto=False,          # 关闭自动色阶调整,必须设置!
    showscale=False       # 隐藏默认色阶(可选,因为我们不需要它)
))

# 调整3D场景布局(可选)
fig.update_layout(
    scene=dict(
        xaxis_title="X轴",
        yaxis_title="Y轴",
        zaxis_title="Z轴"
    ),
    height=800
)

fig.show()

为什么之前的方法无效?

  • 直接传入RGB数组给surfacecolor:Plotly的Surface组件不支持(rows, cols, 3)格式的输入,RGB数组会被自动解析为数值(例如取第一个通道或扁平化),导致颜色映射完全错误。
  • 自定义色阶但未设置cauto=False:Plotly默认会自动计算色阶的cmin和cmax,如果你的索引数值范围很小,会被压缩为近似二值的色阶,导致颜色显示异常。

注意事项

  • 确保surface_color的尺寸与surface_data完全一致,否则会出现维度不匹配的错误。
  • 如果surface_color的像素值是0-1的浮点数,需要先转换为0-255的整数再构建RGB字符串。
  • 若图像存在大量重复颜色,可以合并相同颜色的索引以减少色阶长度,提升性能(不影响最终显示效果)。

内容的提问来源于stack exchange,提问作者SariO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:33:30