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

Plotly三子图色条自定义、布局优化及视图同步问题咨询

解决方案

1. 为每个子图配置独立右侧色条

要让每个子图右侧显示专属色条,需给每个Surface轨迹分配独立coloraxis,并在布局中针对性配置色条位置和数值范围:

  • 给每个Surface添加coloraxis参数,如coloraxis="coloraxis1"、coloraxis2、coloraxis3
  • 在layout中定义每个coloraxis的cmin/cmax(匹配对应子图数据的最值),并通过colorbar.x参数定位色条到对应子图右侧,yanchor="middle"保证垂直居中

2. 修复子图尺寸与副标题显示问题

  • 副标题不显示是因为原代码将布局margin.t(顶部边距)设为0,导致标题被裁剪,需调整t值(如设为60)预留标题空间
  • 加宽整体画布宽度(如设为1200),并通过horizontal_spacing增加子图间距,避免色条与子图重叠,让整体布局更协调

3. 实现子图视图同步联动

纯静态Plotly图无法直接实现联动,需借助JavaScript监听交互事件,以下是具体实现方式:
在生成的HTML中插入自定义JS代码,监听任一子图的relayout事件,将更新后的相机参数同步到另外两个子图,实现缩放、旋转同步。


修正后的完整代码
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.io as pio

# 加载并处理数据(修正原代码未定义的df_1/df_2问题)
Real_df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv")
Model_df = Real_df[np.random.default_rng(seed=42).permutation(Real_df.columns.values)]
Error_df = pd.DataFrame(np.random.randint(0, 5, size=Real_df.shape), columns=Real_df.columns)

# 创建3D子图
fig = make_subplots(
    rows=1, cols=3,
    specs=[[{'is_3d': True}, {'is_3d': True}, {'is_3d': True}]],
    subplot_titles=['True', 'Model', 'Error Percentage'],
    horizontal_spacing=0.15  # 增加子图间距,避免色条重叠
)

# 添加Surface轨迹并绑定独立coloraxis
fig.add_trace(
    go.Surface(z=Real_df.values.tolist(), colorscale="jet", coloraxis="coloraxis1"),
    row=1, col=1
)
fig.add_trace(
    go.Surface(z=Model_df.values.tolist(), colorscale="jet", coloraxis="coloraxis2"),
    row=1, col=2
)
fig.add_trace(
    go.Surface(z=Error_df.values.tolist(), colorscale="jet", coloraxis="coloraxis3"),
    row=1, col=3
)

# 计算各子图数据的最值,用于设置色条范围
real_min, real_max = Real_df.values.min(), Real_df.values.max()
model_min, model_max = Model_df.values.min(), Model_df.values.max()
error_min, error_max = Error_df.values.min(), Error_df.values.max()

# 更新布局:配置色条、尺寸、边距
fig.update_layout(
    width=1200,
    height=700,
    autosize=False,
    margin=dict(t=60, b=20, l=20, r=20),  # 顶部边距预留标题空间
    template="plotly_white",
    # 第一个子图的色条配置
    coloraxis1=dict(
        cmin=real_min, cmax=real_max,
        colorbar=dict(x=0.3, yanchor="middle", title="Value")
    ),
    # 第二个子图的色条配置
    coloraxis2=dict(
        cmin=model_min, cmax=model_max,
        colorbar=dict(x=0.65, yanchor="middle", title="Value")
    ),
    # 第三个子图的色条配置
    coloraxis3=dict(
        cmin=error_min, cmax=error_max,
        colorbar=dict(x=0.98, yanchor="middle", title="Error")
    )
)

# 统一3D场景比例
fig.update_scenes(
    aspectratio=dict(x=1, y=1, z=0.7),
    aspectmode="manual"
)

# 添加视图同步的JS代码(保存为HTML后生效)
js_sync_code = """
<script>
document.addEventListener('DOMContentLoaded', function() {
    const plotDiv = document.querySelector('.plotly-graph-div');
    plotDiv.addEventListener('plotly_relayout', function(event) {
        let camera;
        if (event['scene.camera']) camera = event['scene.camera'];
        else if (event['scene2.camera']) camera = event['scene2.camera'];
        else if (event['scene3.camera']) camera = event['scene3.camera'];
        
        if (camera) {
            Plotly.relayout(plotDiv, {
                'scene.camera': camera,
                'scene2.camera': camera,
                'scene3.camera': camera
            });
        }
    });
});
</script>
"""

# 生成带同步功能的HTML文件
html_content = pio.to_html(fig, full_html=True)
html_content = html_content.replace('</body>', js_sync_code + '</body>')
with open('synced_3d_subplots.html', 'w') as f:
    f.write(html_content)

fig.show()

关键说明

  1. 独立色条:每个Surface绑定唯一coloraxis,通过colorbar.x精准定位色条到对应子图右侧,确保互不干扰。
  2. 布局修复:调整顶部边距显示副标题,加宽画布并增加子图间距,解决布局拥挤问题。
  3. 视图同步:通过JS监听子图的相机参数变化,实时同步到所有子图,打开生成的HTML文件即可体验联动效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:35:45