三维热力图实战:从Matplotlib到Plotly,可视化决策边界与损失曲面

发布时间:2026/7/30 13:58:39
三维热力图实战:从Matplotlib到Plotly,可视化决策边界与损失曲面 1. 从二维到三维为什么我们需要地形图式的热力图在机器学习和数据分析的日常工作中热力图Heatmap是我们再熟悉不过的工具。无论是查看混淆矩阵、相关性矩阵还是观察二维数据分布一张色彩斑斓的方块图总能直观地揭示数据间的“冷热”关系。但不知道你有没有遇到过这样的场景当你面对一个由两个自变量比如地理位置经纬度和一个因变量比如温度、海拔或某种指标强度构成的数据集时传统的二维热力图虽然能展示强度却丢失了“地形”的起伏感。你看到的只是一个平面的色块而无法直观感受到数据在空间中的“山峰”与“山谷”。这就是三维热力图或者说地形图式可视化大显身手的地方。它本质上是一种将三维数据X, Y, Z映射到三维空间表面并用颜色表示第四维通常是Z值本身或另一个相关强度值的图形。在机器学习中这种可视化尤其有用模型决策边界可视化对于有两个特征的分类模型我们可以将整个特征空间网格化用模型预测的概率值作为“高度”Z轴绘制出决策面的三维地形。哪里是概率的“高原”高置信度区域哪里是概率的“峡谷”决策边界概率≈0.5一目了然。损失函数曲面分析在理解优化算法如梯度下降时将模型的损失函数相对于两个参数进行可视化形成一座崎岖的“山脉”。这能直观展示为何优化会陷入局部最小值以及不同优化器的“下山”路径有何不同。空间数据插值展示比如气象数据经纬度对应温度、地质勘探数据坐标对应矿藏密度三维地形图能比等高线图更直观地呈现数据的空间连续性和变化趋势。最近在跟进一些前沿的论文和开源项目时我发现越来越多的研究者开始用这种更具冲击力的三维视图来辅助分析它不再是科研论文里的“花瓶”而是成了洞察模型行为和数据结构的重要诊断工具。今天我就结合Python中最主流的几个库Matplotlib, Plotly, Mayavi手把手带你实现从数据准备到高级渲染的完整流程并分享几个我实际项目中踩过的坑和提升效果的关键技巧。2. 核心工具选型Matplotlib、Plotly 与 Mayavi 的实战对比在Python中绘制三维图形我们有几个主要选择。每个库都有其独特的优势和适用场景选择哪一个取决于你的具体需求是追求快速出图、交互性还是需要电影级的渲染质量2.1 Matplotlib稳健的“基本功”适合集成与出版Matplotlib是Python可视化的基石其3D工具包mpl_toolkits.mplot3d提供了最基础、最稳定的三维绘图能力。它的优势在于与整个Matplotlib生态无缝集成图形风格统一输出为静态的出版级矢量图如PDF, SVG非常方便。基本实现代码框架import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 1. 准备数据创建网格 x np.linspace(-5, 5, 100) y np.linspace(-5, 5, 100) X, Y np.meshgrid(x, y) # 计算高度Z例如一个二维高斯函数模拟一个“山峰” Z np.exp(-(X**2 Y**2) / 10) # 2. 创建图形和3D坐标轴 fig plt.figure(figsize(10, 8)) ax fig.add_subplot(111, projection3d) # 3. 绘制三维曲面并用颜色映射表示高度 surf ax.plot_surface(X, Y, Z, cmapviridis, linewidth0, antialiasedTrue, alpha0.8) # 4. 添加颜色条 fig.colorbar(surf, axax, shrink0.5, aspect10, labelIntensity) # 5. 设置标签和视角 ax.set_xlabel(X Axis) ax.set_ylabel(Y Axis) ax.set_zlabel(Z Axis (Intensity)) ax.set_title(3D Heatmap (Terrain) with Matplotlib) ax.view_init(elev25, azim45) # 设置视角仰角方位角 plt.tight_layout() plt.show()Matplotlib 3D 的局限与技巧性能瓶颈当网格数据点X, Y, Z的维度超过 100x100 时旋转和缩放会明显卡顿不适合大数据量交互。渲染质量其3D渲染是基于2D投影的伪3D在复杂光照、透明度和纹理方面能力有限。实用技巧使用alpha参数透明度可以让图形看起来更“轻”避免一大坨实心色块。antialiasedTrue能平滑曲面边缘。调整view_init(elev, azim)是找到最佳展示角度的关键我通常先设elev30, azim45作为起点。2.2 Plotly交互式分析的利器适合演示与探索Plotly特别是其开源版本plotly.graph_objects的核心优势是交互性。生成的图形可以在网页中自由旋转、缩放、平移并且支持悬停显示精确数值。这对于数据探索和结果演示来说体验提升巨大。基本实现代码框架import plotly.graph_objects as go import numpy as np # 准备数据同Matplotlib示例 x np.linspace(-5, 5, 100) y np.linspace(-5, 5, 100) X, Y np.meshgrid(x, y) Z np.exp(-(X**2 Y**2) / 10) # 创建Surface图三维曲面 fig go.Figure(data[go.Surface(zZ, xX, yY, colorscaleViridis)]) # 更新布局设置更美观的标签和视角 fig.update_layout( titleInteractive 3D Heatmap with Plotly, scenedict( xaxis_titleX Axis, yaxis_titleY Axis, zaxis_titleZ Axis (Intensity), # 可以精细调整每个轴的显示范围、刻度等 aspectmodemanual, # 手动控制比例 aspectratiodict(x1, y1, z0.7) # 调整Z轴缩放让地形更突出 ), autosizeTrue, width900, height700, ) # 在Jupyter Notebook中直接显示 fig.show() # 如果要保存为独立的HTML文件便于分享 # fig.write_html(interactive_3d_heatmap.html)Plotly 的强大之处与注意事项交互与分享fig.show()在Jupyter中直接生成可交互图表。fig.write_html()生成的HTML文件包含了所有数据和渲染引擎在任何现代浏览器中打开都能完美交互是汇报和分享的绝佳格式。丰富的色彩映射colorscale参数支持大量内置方案如 ‘Viridis’, ‘Plasma’, ‘Rainbow’也支持自定义。性能考量虽然交互流畅但渲染超大数据集如 500x500 以上时初始加载和响应仍可能有延迟。对于静态报告有时仍需回归Matplotlib的PDF。一个关键技巧默认情况下Plotly的3D场景会自动调整比例有时会使图形显得扁平。通过设置scene_aspectmode‘manual’和scene_aspectratio你可以像调整相机镜头一样控制三个轴的比例让地形起伏更加明显。2.3 Mayavi科学计算的重炮追求极致可视化Mayavi 基于 VTKVisualization Toolkit是专门为科学计算和三维数据可视化设计的库。它能处理海量数据提供高质量的光线追踪渲染、复杂的等值面绘制、矢量场可视化等高级功能。如果你需要制作用于论文或演示的“大片级”三维图像Mayavi是首选。安装与基本实现安装Mayavi稍麻烦pip install mayavi。它依赖VTK在Windows上可能需要对应版本的whl文件。import numpy as np from mayavi import mlab # 准备数据 x np.linspace(-5, 5, 200) # Mayavi能轻松处理更高分辨率 y np.linspace(-5, 5, 200) X, Y np.meshgrid(x, y) Z np.exp(-(X**2 Y**2) / 10) # 创建三维曲面图 mlab.figure(size(800, 600), bgcolor(1, 1, 1)) # 设置图形大小和背景色白色 surf mlab.surf(X, Y, Z, colormapviridis, warp_scaleauto) # 添加颜色条和标签 mlab.colorbar(surf, titleIntensity, orientationvertical) mlab.xlabel(X Axis) mlab.ylabel(Y Axis) mlab.zlabel(Z Axis) # 调整视角可以通过GUI交互调整也可代码设置 mlab.view(azimuth45, elevation60, distanceauto) # 显示图形会弹出交互窗口 mlab.show()Mayavi 的优势与学习曲线渲染质量支持抗锯齿、多种光照模型、阴影输出图像质量极高。大数据处理其流水线架构能高效渲染数百万甚至千万级的数据点。交互与脚本结合弹出的窗口允许你用鼠标进行实时旋转、缩放。你可以在交互调整到满意视角后通过mlab.view()获取当前的方位角、仰角参数并固化到脚本中。主要缺点API 设计与 Matplotlib 差异较大学习成本高。在纯脚本环境中如远程服务器使用不如前两者方便通常需要配合屏幕或使用离屏渲染。选择建议对于日常快速分析和集成到自动化报告中Matplotlib是可靠选择。当你需要向他人展示并允许其探索数据时Plotly的交互HTML是无敌的。而当项目涉及复杂的科学可视化、需要处理极大网格或追求出版级静态图像质量时则值得投入时间学习Mayavi。3. 数据准备与地形生成从数学函数到真实数据集三维热力图的基石是规整的网格数据(X, Y, Z)。X和Y定义了二维平面上的网格点Z则是每个网格点上的“高度”或“强度”值。数据准备的核心就是生成或处理出这样的三元组。3.1 生成模拟数据理解地形构造最常用的方法是使用numpy.meshgrid函数创建坐标网格然后通过数学函数计算Z值。这非常适合演示和算法分析。import numpy as np # 定义X和Y轴的范围和点数 x np.linspace(-np.pi, np.pi, 200) y np.linspace(-np.pi, np.pi, 200) X, Y np.meshgrid(x, y) # X, Y 现在都是 200x200 的矩阵 # 示例1多个高斯峰叠加模拟复杂地形 Z1 np.exp(-(X**2 Y**2)) Z2 0.5 * np.exp(-((X-1.5)**2 (Y1.5)**2)/0.5) Z Z1 Z2 # 示例2正弦余弦组合模拟波纹 R np.sqrt(X**2 Y**2) Z np.sin(R) / R # sinc函数在中心有一个主瓣 Z np.nan_to_num(Z) # 处理R0处的除零问题 # 示例3随机噪声叠加模拟真实数据的不平滑性 noise np.random.normal(0, 0.1, X.shape) Z_smooth np.exp(-(X**2 Y**2)/4) Z_noisy Z_smooth noise关键点np.linspace决定了分辨率和范围。点数越多曲面越平滑但计算和渲染负担越重。通常 100-200 的点数在清晰度和性能之间是一个较好的平衡。3.2 处理真实数据集从散点到网格真实世界的数据往往是离散的散点(x_i, y_i, z_i)。我们需要将其插值Interpolate到规则的网格上。scipy.interpolate模块提供了强大的工具。假设我们有一组气象站数据经纬度和温度import numpy as np from scipy.interpolate import griddata import matplotlib.pyplot as plt # 模拟的散点数据100个随机站点的经纬度和温度 np.random.seed(42) n_points 100 lons np.random.uniform(115, 118, n_points) # 经度 lats np.random.uniform(35, 40, n_points) # 纬度 temps np.random.uniform(10, 25, n_points) # 温度这里用随机数模拟 # 可以加入一些空间相关性例如温度随纬度升高而降低 temps temps - 0.5 * (lats - 37.5) # 定义我们想要插值到的规则网格 grid_lon np.linspace(115, 118, 200) grid_lat np.linspace(35, 40, 200) grid_lon, grid_lat np.meshgrid(grid_lon, grid_lat) # 200x200的网格 # 使用 griddata 进行插值。method可选 linear, cubic, nearest grid_temp griddata((lons, lats), temps, (grid_lon, grid_lat), methodcubic) # 处理插值边缘可能产生的NaN值网格点超出散点凸包范围 grid_temp_filled np.nan_to_num(grid_temp, nannp.nanmean(grid_temp)) # 现在 grid_lon, grid_lat, grid_temp_filled 就构成了可用于绘图的三维网格数据插值方法的选择nearest最近邻插值速度最快但结果呈块状不连续。linear线性插值默认速度较快结果连续但不够平滑。cubic三次样条插值结果最平滑但计算量最大且要求数据点足够多、分布均匀否则边缘容易产生震荡。踩坑记录在处理地理数据时直接对经纬度进行插值可能会因为地球曲率而产生畸变。对于大范围区域更专业的做法是先将经纬度投影到平面坐标系如使用pyproj库在投影坐标上进行插值和绘图。这是一个常见的进阶坑点。4. 进阶美化与实战技巧让你的三维热力图脱颖而出基础图形生成后如何让它更专业、更清晰地传达信息以下是我在多个项目中总结出的美化技巧。4.1 色彩映射Colormap的学问颜色不是随便选的。它应该直观地反映数据的大小顺序并且对于色觉障碍者友好。顺序数据Sequential像高度、温度、密度这类从低到高连续变化的数据应使用单色调渐变的色彩映射如‘viridis’,‘plasma’,‘inferno’,‘cividis’。Matplotlib 的viridis是默认的也是很好的选择它在感知上均匀且黑白打印时也能区分。# Matplotlib 中设置 surf ax.plot_surface(..., cmapviridis) # Plotly 中设置 go.Surface(..., colorscaleViridis)发散数据Diverging如果数据有一个有意义的中间值比如0或平均值并且你想突出显示与中间值的偏差应使用发散色系如‘RdBu’,‘PiYG’,‘coolwarm’。例如显示预测误差正负误差。# 假设Z是误差值0是中心 cmap plt.cm.get_cmap(RdBu_r) # _r 表示反转色系 surf ax.plot_surface(..., cmapcmap)自定义与归一化有时数据范围不是从0到1我们需要将颜色映射归一化到数据的实际范围。import matplotlib.cm as cm from matplotlib.colors import Normalize # 假设Z的范围是 [-10, 20] norm Normalize(vmin-10, vmax20) # 创建归一化对象 cmap cm.viridis colors cmap(norm(Z)) # 将Z值映射到颜色 # 在Matplotlib的plot_surface中可以通过facecolors参数直接传入RGBA颜色数组 surf ax.plot_surface(X, Y, Z, facecolorscolors, shadeFalse)4.2 光照、阴影与透明度增强立体感三维图形的立体感很大程度上依赖于光照和阴影。在Matplotlib中增强Matplotlib的3D渲染光照比较简单但调整plot_surface的light_source参数可以微调。from matplotlib.colors import LightSource # 创建光源对象 ls LightSource(azdeg315, altdeg45) # 设置光源方位角和高度角 # 使用光源着色Hillshading rgb ls.shade(Z, cmapcm.viridis, vert_exag0.1, blend_modesoft) surf ax.plot_surface(X, Y, Z, facecolorsrgb, linewidth0, antialiasedFalse)vert_exag垂直夸张系数在这里非常有用。如果实际数据起伏不大图形会显得很平。适当增大这个系数如0.5甚至2可以夸张地显示地形起伏让特征更明显。这在学术海报中经常使用。在Plotly中调整光照Plotly提供了更精细的光照控制。fig.update_layout( scenedict( ... # 调整场景光照 lightingdict( ambient0.4, # 环境光强度 diffuse0.8, # 漫反射强度 specular0.2, # 镜面反射强度 roughness0.5, # 表面粗糙度 fresnel0.2 # 菲涅尔效应强度 ), # 也可以设置整个场景的背景和网格线 xaxisdict(showbackgroundTrue, backgroundcolorrgb(230, 230,230)), yaxisdict(showbackgroundTrue, backgroundcolorrgb(230, 230,230)), ) )增加ambient光可以让暗部细节更清晰调整specular可以控制高光点的强弱模拟不同材质如湿润地表 vs 干燥岩石。4.3 多视角与动画动态展示数据全貌一张静态图可能无法展示复杂地形的全貌。生成多视角截图或动画非常有效。生成旋转动画Matplotlibimport matplotlib.animation as animation fig plt.figure(figsize(8,6)) ax fig.add_subplot(111, projection3d) surf ax.plot_surface(X, Y, Z, cmapviridis, alpha0.8) ax.set_zlim(Z.min(), Z.max()) def animate(i): ax.view_init(elev30, azimi) # 方位角从0度旋转到360度 return fig, ani animation.FuncAnimation(fig, animate, frames360, interval50, blitFalse) # 保存为GIF需要pillow库 ani.save(3d_terrain_rotation.gif, writerpillow, fps30) plt.close()在Plotly中创建动画帧Plotly可以创建更复杂的交互动画但原理是生成一系列不同视角的帧。import plotly.graph_objects as go import numpy as np frames [] for azim in np.arange(0, 360, 10): # 每10度一帧 frames.append(go.Frame( layoutdict(scene_cameradict(eyedict(x2*np.cos(np.radians(azim)), y2*np.sin(np.radians(azim)), z1.5))) # 相机位置 )) fig go.Figure(data[go.Surface(zZ, xX, yY)], framesframes) # 添加动画播放控件 fig.update_layout(updatemenus[dict(typebuttons, buttons[dict(labelPlay, methodanimate, args[None, {frame: {duration: 100}}])])]) fig.show()4.4 叠加等高线与标注融合2D与3D信息有时我们需要在三维地形上精确读取某个点的数值。叠加等高线Contour是一个好方法。# 在Matplotlib的3D图上叠加等高线投影 fig plt.figure(figsize(12, 5)) # 子图1纯3D曲面 ax1 fig.add_subplot(121, projection3d) ax1.plot_surface(X, Y, Z, cmapviridis, alpha0.7) ax1.set_title(3D Surface) # 子图23D曲面 底部等高线投影 ax2 fig.add_subplot(122, projection3d) surf ax2.plot_surface(X, Y, Z, cmapviridis, alpha0.6) # 在Z轴最小值处绘制等高线的投影 cset ax2.contourf(X, Y, Z, zdirz, offsetZ.min()-0.1, cmapviridis, alpha0.5) # 在X轴和Y轴侧面也绘制投影可选 # cset_x ax2.contourf(X, Y, Z, zdirx, offsetX.min()-1, cmapviridis, alpha0.3) # cset_y ax2.contourf(X, Y, Z, zdiry, offsetY.max()1, cmapviridis, alpha0.3) ax2.set_title(3D Surface with Contour Projection) ax2.set_zlim(Z.min()-0.5, Z.max()) plt.tight_layout() plt.show()这个技巧能同时提供三维形态和二维数值分布的信息在分析损失函数曲面或决策边界时特别有用你可以一眼看出“山谷”的走向和深度。5. 机器学习实战案例可视化分类模型的决策地形让我们用一个完整的例子将上述所有技巧串联起来。我们将训练一个简单的二维特征分类器如SVM或神经网络然后将其在整个特征空间上的预测概率可视化成交错起伏的“决策地形”。import numpy as np import matplotlib.pyplot as plt from sklearn.svm import SVC from sklearn.datasets import make_moons from sklearn.preprocessing import StandardScaler from matplotlib.colors import ListedColormap # 1. 生成模拟数据月牙形数据集 X, y make_moons(n_samples300, noise0.15, random_state42) scaler StandardScaler() X_scaled scaler.fit_transform(X) # 标准化有助于模型训练和可视化范围 # 2. 训练一个非线性SVM分类器 model SVC(kernelrbf, C1.0, gamma1, probabilityTrue) # 启用概率估计 model.fit(X_scaled, y) # 3. 创建覆盖特征空间的网格 h 0.02 # 网格步长 x_min, x_max X_scaled[:, 0].min() - 0.5, X_scaled[:, 0].max() 0.5 y_min, y_max X_scaled[:, 1].min() - 0.5, X_scaled[:, 1].max() 0.5 xx, yy np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) # 4. 对网格上每一点进行预测得到属于类别1的概率 Z model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1] Z Z.reshape(xx.shape) # 5. 绘制三维决策地形图 fig plt.figure(figsize(16, 6)) # 子图13D决策曲面 ax1 fig.add_subplot(121, projection3d) # 曲面颜色映射到预测概率 surf ax1.plot_surface(xx, yy, Z, cmapcoolwarm, alpha0.8, linewidth0, antialiasedTrue) # 将原始数据点以散点形式“钉”在曲面上 ax1.scatter(X_scaled[:, 0], X_scaled[:, 1], model.predict_proba(X_scaled)[:, 1], cy, cmapcoolwarm, edgecolork, s50, depthshadeTrue) ax1.set_xlabel(Feature 1 (scaled)) ax1.set_ylabel(Feature 2 (scaled)) ax1.set_zlabel(P(Class1)) ax1.set_title(3D Decision Terrain of SVM (RBF Kernel)) fig.colorbar(surf, axax1, shrink0.5, aspect10, labelProbability) ax1.view_init(elev25, azim-60) # 调整到一个能看清地形起伏的角度 # 子图2对应的2D等高线图传统可视化 ax2 fig.add_subplot(122) # 绘制概率等高线 contour ax2.contourf(xx, yy, Z, levels20, cmapcoolwarm, alpha0.7) # 绘制决策边界概率0.5的等高线 ax2.contour(xx, yy, Z, levels[0.5], colorsblack, linewidths2) # 绘制原始数据点 ax2.scatter(X_scaled[:, 0], X_scaled[:, 1], cy, cmapcoolwarm, edgecolork, s50) ax2.set_xlabel(Feature 1 (scaled)) ax2.set_ylabel(Feature 2 (scaled)) ax2.set_title(2D Contour with Decision Boundary) plt.colorbar(contour, axax2, labelP(Class1)) ax2.set_aspect(equal) plt.tight_layout() plt.show()从这个案例中我们能学到什么直观理解非线性决策在3D图中你可以清晰看到概率曲面如何从蓝色“山谷”P≈0蜿蜒上升到红色“山峰”P≈1。两个类别区域之间的陡峭悬崖就是模型的决策边界。这比2D等高线图更能让人感受到分类的“置信度”变化。诊断模型问题如果概率曲面在大部分区域都非常平坦接近0.5说明模型对自己的预测很不确定可能欠拟合或数据本身难以区分。如果曲面有很多不自然的尖锐峰谷可能意味着过拟合。对比不同模型将线性模型如Logistic回归和复杂的非线性模型如RBF SVM或神经网络的决策地形放在一起对比你能直观看到后者如何通过扭曲曲面来拟合复杂数据。这个可视化过程本身就是深入理解模型行为的一种强有力的探索性数据分析EDA手段。6. 性能优化与常见问题排查当数据量变大或图形复杂时你可能会遇到性能问题或奇怪的图形显示错误。6.1 大数据量下的渲染优化降低分辨率这是最直接有效的方法。在调用meshgrid或插值时减少网格点数。例如从np.linspace(start, stop, 500)降到200。使用降采样如果原始数据分辨率很高可以先计算高分辨率数据然后均匀降采样后再绘图。# 假设有高分辨率数据 X_hi, Y_hi, Z_hi (1000x1000) stride 5 # 每隔5个点取一个 X_lo X_hi[::stride, ::stride] Y_lo Y_hi[::stride, ::stride] Z_lo Z_hi[::stride, ::stride] # 用 X_lo, Y_lo, Z_lo 绘图选择更轻量的库对于超大规模数据千万级点Matplotlib和Plotly可能力不从心。此时应考虑Datashader专门用于大数据集的栅格化渲染先聚合再绘图。PyVista或VTK (Python接口)提供更底层的、性能导向的三维渲染管线。Plotly的WebGL后端Plotly的scatter3d等图表类型支持render_mode‘webgl’可以利用GPU加速渲染大量散点。对于曲面图可以尝试先将其转换为三角网格再渲染。6.2 图形显示异常排查图形一片空白或只有部分显示检查数据范围确保X,Y,Z都是有限数值没有inf或NaN。使用np.nan_to_num清理数据。检查轴范围Matplotlib的ax.set_xlim(), ax.set_ylim(), ax.set_zlim()可能被自动设置到一个不包含你数据的范围。手动设置它们。视角问题可能你的视角正好“看”到了图形的边缘或背面。尝试用ax.view_init(elev90, azim0)从正上方俯视或者慢慢调整角度。颜色映射显示不正确全蓝或全红检查Z值范围如果Z的所有值都非常接近比如都在0.499到0.501之间那么颜色映射的整个动态范围就只用到了中间的一小段看起来颜色差异很小。可以手动设置归一化范围Normalize(vminZ.min(), vmaxZ.max())或者考虑对Z值做一点拉伸。检查cmap参数确保传入的cmap字符串是有效的。Matplotlib中可以用plt.colormaps()查看所有可用名称。Matplotlib 3D图形锯齿严重或边缘粗糙启用抗锯齿在plot_surface中设置antialiasedTrue。增加网格分辨率这是根本解决方法。保存为高DPI矢量图当保存为PDF或SVG时锯齿问题会大大减轻。plt.savefig(output.pdf, dpi300, bbox_inchestight)Plotly图形在Jupyter Notebook中不显示确保安装了正确的渲染器pip install plotly通常会自动配置。如果不行尝试import plotly.io as pio; pio.renderers.default ‘plotly_mimetypenotebook’或‘notebook’。对于离线环境可能需要初始化from plotly.offline import init_notebook_mode; init_notebook_mode(connectedFalse)。三维可视化是一个需要不断调试和审美的过程。最好的学习方式就是多动手尝试不同的数据、不同的参数并仔细观察结果。当你能够熟练地运用这些工具将高维数据的内在结构直观地呈现出来时你对模型和数据的理解也会达到一个新的层次。