はじめに
3Dグラフは 1枚だけだと比較が難しい。
サブプロット(2画面・4画面など) にすると
時系列比較・条件比較・モデル比較・群比較 が一気にわかりやすくなる。
Plotly は make_subplots(specs=[[{'type':'scene'}]]) を使うことで
3Dグラフを並べて表示できる。
この記事でできること
- 3Dグラフを複数レイアウトで並べて表示
- Surface × Surface
- Scatter3d × Scatter3d
- Surface × Scatter3d の異種比較
- Colabでそのまま動くコードつき
① まずは必要なライブラリと例データ
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
# データ準備
x = np.linspace(-3, 3, 60)
y = np.linspace(-3, 3, 60)
X, Y = np.meshgrid(x, y)
Z1 = np.sin(np.sqrt(X**2 + Y**2))
Z2 = np.cos(np.sqrt(X**2 + Y**2))
② 2画面サブプロット(横に並べる)
fig = make_subplots(
rows=1, cols=2,
specs=[[{'type':'scene'}, {'type':'scene'}]],
subplot_titles=("Surface A", "Surface B")
)
# Surface A
fig.add_trace(
go.Surface(x=X, y=Y, z=Z1, colorscale="Viridis", showscale=False),
row=1, col=1
)
# Surface B
fig.add_trace(
go.Surface(x=X, y=Y, z=Z2, colorscale="Cividis", showscale=False),
row=1, col=2
)
fig.update_layout(
title="Side-by-Side 3D Surface Comparison",
scene=dict(aspectmode="data"),
scene2=dict(aspectmode="data")
)
fig.show()
結果:
- 2つのSurfaceが横に並ぶ
- 色の違い・形状の違い・変化パターンを即比較できる
③ 散布図どうしの比較(Scatter3d × Scatter3d)
例として異なる点群を比較表示。
# 点群生成
np.random.seed(0)
x1, y1, z1 = np.random.randn(3, 200)
x2, y2, z2 = np.random.randn(3, 200) + 1.5
fig = make_subplots(
rows=1, cols=2,
specs=[[{'type':'scene'}, {'type':'scene'}]],
subplot_titles=("Group A", "Group B")
)
fig.add_trace(go.Scatter3d(
x=x1, y=y1, z=z1,
mode="markers",
marker=dict(size=3, color=z1, colorscale="Viridis", opacity=0.7)
), row=1, col=1)
fig.add_trace(go.Scatter3d(
x=x2, y=y2, z=z2,
mode="markers",
marker=dict(size=3, color=z2, colorscale="Plasma", opacity=0.7)
), row=1, col=2)
fig.update_layout(scene=dict(aspectmode="data"),
scene2=dict(aspectmode="data"))
fig.show()
結果:
- 2群の分布差がひと目で理解できる
④ 異種比較(Surface × Scatter)も可能
fig = make_subplots(
rows=1, cols=2,
specs=[[{'type':'scene'}, {'type':'scene'}]],
subplot_titles=("Surface", "Scatter Points")
)
# Surface
fig.add_trace(go.Surface(
x=X, y=Y, z=Z1,
colorscale="Viridis", showscale=False
), row=1, col=1)
# Scatter
fig.add_trace(go.Scatter3d(
x=x1, y=y1, z=z1,
mode="markers",
marker=dict(size=4, color=z1, colorscale="Rainbow", opacity=0.7)
), row=1, col=2)
fig.update_layout(scene=dict(aspectmode="data"),
scene2=dict(aspectmode="data"))
fig.show()
結果:
- 「連続的な形状」vs「離散点」などの比較に便利
- モデル出力 vs 現実データの比較例としても定番
⑤ 4画面レイアウト(2×2)で詳細比較
fig = make_subplots(
rows=2, cols=2,
specs=[
[{'type':'scene'}, {'type':'scene'}],
[{'type':'scene'}, {'type':'scene'}],
],
subplot_titles=("A", "B", "C", "D")
)
fig.add_trace(go.Surface(z=Z1, x=X, y=Y, colorscale='Viridis', showscale=False), row=1, col=1)
fig.add_trace(go.Surface(z=Z2, x=X, y=Y, colorscale='Cividis', showscale=False), row=1, col=2)
fig.add_trace(go.Scatter3d(x=x1,y=y1,z=z1,mode='markers'), row=2, col=1)
fig.add_trace(go.Scatter3d(x=x2,y=y2,z=z2,mode='markers'), row=2, col=2)
# 全sceneに aspectmode を付与
for name in ["scene", "scene2", "scene3", "scene4"]:
fig.update_layout({name: dict(aspectmode="data")})
fig.update_layout(title="4-View 3D Comparison")
fig.show()
結果:
- 4パターン比較 → パラメータ検証やモデル比較に最適
⑥ 背景と軸設定でサブプロットが見やすくなる
fig.update_layout(
scene=dict(xaxis=dict(backgroundcolor='rgb(245,245,245)')),
scene2=dict(xaxis=dict(backgroundcolor='rgb(245,245,245)'))
)
- 各sceneごとに個別設定可能
- 背景色を統一すると比較の精度が上がる
トラブルシュート
表示が歪む
→ 各 scene に aspectmode="data" を設定
色バーが重複する
→ showscale=False でオフ
各画面のズームが同期しない
→ Plotlyはデフォルトで独立
Colabで重い
→ Surface の解像度を下げる(60→40)
まとめ
- make_subplots(... specs=[[{"type":"scene"}]]) で3Dサブプロットが作れる
- Surface × Surface、Scatter × Scatter、異種比較も自由
- 多画面で比較すると "違いが一瞬で分かる"
- パラメータチューニング、モデル比較、条件差分の可視化に最適
複数3D可視化の"比較力"は、分析の質を大きく押し上げる。
動画解説
参考情報






