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

如何用Plotly绘制大量Scatter3d子图?解决渲染异常问题

Plotly 5×5 Scatter3d子图阵列仅渲染最后16个的解决方法

问题描述

使用Plotly创建Scatter3d子图阵列时,当子图数量≤16时所有图可正常渲染,但创建5×5(25个)的阵列时,仅最后16个图会被渲染,其他图类型(如Scatter)无此问题。

16 plots out of 25 render correctly

可复现代码:

from plotly.subplots import make_subplots
import plotly.graph_objects as go

import numpy as np

Npts = 30
nrows,ncols = 5,5
speclist = [[{"type": "Scatter3d"} for i in range(0,ncols)] for j in range(0,nrows)]

fig = make_subplots(rows=nrows,cols=ncols,specs=speclist)

for i in range(0,nrows*ncols):
    row,col = (i//ncols)+1,(i%ncols)+1
    print("Index: {i:02d} Row: {row:02d} Column: {col:02d}".format(i=i,row=row,col=col))
    xvals=np.random.uniform(0.0,1.0,Npts)
    yvals=np.random.uniform(0.0,1.0,Npts)
    zvals=np.random.uniform(0.0,1.0,Npts)
    fig.add_trace(go.Scatter3d(x=xvals, y=yvals, z=zvals,mode='markers',showlegend=False),row=row,col=col)

fig.show()

原因分析

Plotly默认限制了最多16个3D子图的渲染,这是出于浏览器渲染大量3D场景的性能考量,默认仅分配了16个独立的3D场景资源,超出的子图会复用之前的场景,导致早期的子图被覆盖。

解决方案

为每个Scatter3d子图指定唯一的scene标识,让Plotly为每个子图创建独立的3D渲染场景,突破默认上限。同时调整布局尺寸避免子图重叠。

修改后的代码:

from plotly.subplots import make_subplots
import plotly.graph_objects as go

import numpy as np

Npts = 30
nrows,ncols = 5,5
# 为每个3D子图生成唯一的scene ID
speclist = []
for row_idx in range(nrows):
    current_row = []
    for col_idx in range(ncols):
        scene_id = f"scene{row_idx * ncols + col_idx + 1}"
        current_row.append({"type": "Scatter3d", "scene": scene_id})
    speclist.append(current_row)

fig = make_subplots(rows=nrows, cols=ncols, specs=speclist)

# 添加所有Scatter3d轨迹
for i in range(nrows * ncols):
    row = (i // ncols) + 1
    col = (i % ncols) + 1
    xvals = np.random.uniform(0.0, 1.0, Npts)
    yvals = np.random.uniform(0.0, 1.0, Npts)
    zvals = np.random.uniform(0.0, 1.0, Npts)
    fig.add_trace(
        go.Scatter3d(x=xvals, y=yvals, z=zvals, mode='markers', showlegend=False),
        row=row, col=col
    )

# 调整布局尺寸,避免子图重叠
fig.update_layout(
    height=1000,
    width=1000,
    margin=dict(l=0, r=0, t=20, b=20)
)

fig.show()

可选优化

如果需要自定义每个子图的坐标轴标签等属性,可以遍历所有scene ID进行配置:

for i in range(nrows * ncols):
    scene_id = f"scene{i+1}"
    fig.update_layout(
        **{
            f"{scene_id}.xaxis.title": "X轴",
            f"{scene_id}.yaxis.title": "Y轴",
            f"{scene_id}.zaxis.title": "Z轴"
        }
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:50:11