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

如何用Python实现两个3D曲面图沿彼此表面滑动的交互可视化?

实现Plotly 3D曲面图的滑动交互动画

需求说明

已编写两个3D曲面图的Python代码,需要实现二者沿彼此表面滑动的动画效果,用于观察重叠、间隙及接触状态,计划基于Plotly动画功能改造现有代码。

现有代码及效果

代码1:双曲面及散点展示

import plotly.graph_objects as go
import numpy as np

# 假设W_vals、W_pivot、data为已定义的数据对象
fig = go.Figure(
    layout=dict(
        template="ggplot2",
        margin=dict(l=50, r=10, b=50, t=50),
        font=dict(family="Computer Modern", size=12, color="black"),
        width=1000,
        height=800,
        scene=dict(aspectmode="cube"),
        legend=dict(
            title="", orientation="h", yanchor="bottom", x=0, y=1.0, xanchor="left"
        ),
    )
)

fig.add_trace(
    go.Scatter3d(
        x=W_vals["x"],
        y=W_vals["y"],
        z=W_vals["value"],
        text=W_vals["value"],
        texttemplate="%{text:.2f}",
        mode="markers+text",
        marker=dict(size=3, color="black"),
        name="W Values",
        showlegend=True,
        
    )
)
fig.add_trace(go.Surface(
        x=W_vals["x"],
        y=W_vals["y"],
        z=W_vals["value"],))
fig.add_trace(
    go.Surface(
        x=W_pivot.columns,
        y=W_pivot.index,
        z=W_pivot.values,
        name="W Surface",
        opacity=0.8,
        showlegend=True, 
        colorscale="Viridis",
        cmid=np.mean(W_pivot.values)
    )
)

fig.add_trace(go.Surface(z=data.values, name="Lotus Surface", colorscale="Greys", showlegend=True,visible="legendonly",
))

fig.show()

3D曲面图展示效果

代码2:带等高线的曲面图

import plotly.graph_objects as go

# 假设data为已定义的数据对象
fig = go.Figure(
    layout=dict(
        template="ggplot2",
        margin=dict(l=50, r=10, b=50, t=50, pad=0),
        font=dict(family="Computer Modern", size=12, color="black"),
        width=800,
        height=800,
        scene=dict(aspectmode="cube"),
    )
)

fig.add_trace(go.Surface(z=data.values))
fig.update_traces(
    contours_z=dict(
        show=True, usecolormap=True, highlightcolor="limegreen", project_z=True
    )
)
fig.show()

带等高线的3D曲面图效果

改造方案:滑动动画实现

核心思路是通过位移参数控制其中一个曲面的位置,生成多帧动画并配置播放控件,具体实现如下:

改造后的完整代码

import plotly.graph_objects as go
import numpy as np

# 假设W_pivot(W曲面)和data(Lotus曲面)为已准备好的二维数据
w_x, w_y = W_pivot.columns, W_pivot.index
w_z = W_pivot.values
lotus_z = data.values

# 定义滑动位移范围(根据数据尺寸调整步长和范围)
slide_steps = np.linspace(-5, 5, 20)  # X方向滑动的位移值,可自定义
frames = []

# 创建基础布局
fig = go.Figure(
    layout=dict(
        template="ggplot2",
        margin=dict(l=50, r=10, b=50, t=50),
        font=dict(family="Computer Modern", size=12, color="black"),
        width=1000,
        height=800,
        scene=dict(
            aspectmode="cube",
            xaxis_title="X", yaxis_title="Y", zaxis_title="Z"
        ),
        legend=dict(
            title="", orientation="h", yanchor="bottom", x=0, y=1.0, xanchor="left"
        ),
        # 配置动画播放/暂停控件
        updatemenus=[dict(
            type="buttons",
            showactive=True,
            buttons=[dict(label="Play",
                          method="animate",
                          args=[None, dict(frame=dict(duration=300, redraw=True),
                                          fromcurrent=True,
                                          transition=dict(duration=0))]),
                    dict(label="Pause",
                          method="animate",
                          args=[[None], dict(frame=dict(duration=0, redraw=False),
                                          mode="immediate",
                                          transition=dict(duration=0))])]
        )]
    )
)

# 添加初始帧的两个曲面
fig.add_trace(go.Surface(
    x=w_x, y=w_y, z=w_z,
    name="W Surface", opacity=0.8,
    colorscale="Viridis", cmid=np.mean(w_z)
))
fig.add_trace(go.Surface(
    x=w_x, y=w_y, z=lotus_z,
    name="Lotus Surface", opacity=0.6,
    colorscale="Greys"
))

# 生成动画帧:仅更新Lotus曲面的X位置(可改为Y方向或组合方向)
for step in slide_steps:
    frames.append(go.Frame(
        data=[
            # 保持W曲面位置不变
            go.Surface(x=w_x, y=w_y, z=w_z),
            # 滑动Lotus曲面的X坐标
            go.Surface(x=w_x + step, y=w_y, z=lotus_z)
        ],
        name=f"frame_{step:.1f}"
    ))

# 添加帧到图中并设置位移滑块
fig.frames = frames
fig.update_layout(
    sliders=[dict(
        steps=[dict(
            method="animate",
            args=[[f"frame_{step:.1f}"], dict(mode="immediate")],
            label=f"{step:.1f}"
        ) for step in slide_steps],
        currentvalue=dict(prefix="X方向位移: ")
    )]
)

fig.show()

关键改造点说明

  • 位移控制:通过修改其中一个曲面的x(或y)坐标实现滑动,示例为X方向,可按需改为Y方向或组合位移
  • 动画帧生成:遍历位移参数,为每个位移值创建一帧,仅更新滑动曲面的位置
  • 交互控件:添加播放/暂停按钮和位移滑块,支持手动控制动画进度
  • 样式保留:沿用原代码的模板、字体、场景比例等样式设置,保证视觉一致性
  • 透明度调整:适当降低曲面透明度(如opacity=0.6),便于观察重叠区域

内容的提问来源于stack exchange,提问作者J.P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:45:58