改造XY轴聚类着色绘图代码为XYZ 3D体积着色绘图并支持视角调整的技术咨询
改造XY轴聚类着色绘图代码为XYZ 3D体积着色绘图并支持视角调整的技术咨询
嗨,我来帮你把现有的2D聚类着色绘图代码改成3D版本,同时满足视角调整的需求,咱们一步步拆解改动:
核心改动要点
- 切换到3D坐标轴:创建子图时指定
projection='3d',让每个轴都变成3D空间 - 适配3D绘图元素:把2D的
scatter和tricontourf替换成3D版本,同时新增Z轴数据的处理 - 添加视角控制:通过
view_init()方法设置仰角(elev)和方位角(azim),也支持用户手动交互调整 - 适配3D空间的文本、图例布局:调整文本框位置避免遮挡,适配3D轴的显示逻辑
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt def plot_with_3d_trisurf_customized(dfs, figures_organizer, figsize_setting, list_points_mean, list_points_type, x_col, y_col, z_col, color_col, titles, marker_type='o', apply_limits=False, x_limits=None, y_limits=None, z_limits=None, view_elev=30, view_azim=45): rows, cols = figures_organizer # 创建3D子图,指定projection参数 fig, axes = plt.subplots(rows, cols, figsize=(figsize_setting[0], figsize_setting[1] * rows), constrained_layout=True, subplot_kw={'projection': '3d'}) axes = axes.flatten() # 扁平化轴数组方便索引 for i, (ax, df, title, points_mean, points_type) in enumerate(zip(axes, dfs, titles, list_points_mean, list_points_type)): x = df[x_col].to_numpy() y = df[y_col].to_numpy() z = df[z_col].to_numpy() volume = df[color_col].to_numpy() # 选用适合3D的配色方案 cmap = plt.colormaps['viridis'] # 3D散点图:按volume着色 scatter = ax.scatter(x, y, z, c=volume, cmap=cmap, edgecolor='black', marker=marker_type, s=40, alpha=0.8) # 3D三角填充着色(对应原2D的tricontourf效果) norm = plt.Normalize(min(volume), max(volume)) trisurf = ax.plot_trisurf(x, y, z, cmap=cmap, alpha=0.3, edgecolor='none', facecolors=cmap(norm(volume))) # 绘制固定点(支持3D坐标) for point, type in zip(points_mean, points_type): ax.scatter([point[0]], [point[1]], [point[2]], color='black', marker=type, s=100) # 添加穿过固定点的辅助线(3D中分别平行于三个轴) for point in points_mean: # 平行于Y-Z平面的竖线(固定X) ax.plot([point[0], point[0]], [y.min(), y.max()], [z.min(), z.max()], color='black', linestyle='--', alpha=0.5) # 平行于X-Z平面的横线(固定Y) ax.plot([x.min(), x.max()], [point[1], point[1]], [z.min(), z.max()], color='black', linestyle='--', alpha=0.5) # 平行于X-Y平面的竖线(固定Z) ax.plot([x.min(), x.max()], [y.min(), y.max()], [point[2], point[2]], color='black', linestyle='--', alpha=0.5) # 设置坐标轴标签和标题 ax.set_xlabel(x_col) ax.set_ylabel(y_col) ax.set_zlabel(z_col) ax.set_title(title) ax.grid(True) # 设置坐标轴范围(如果开启) if apply_limits: if x_limits: ax.set_xlim(x_limits) if y_limits: ax.set_ylim(y_limits) if z_limits: ax.set_zlim(z_limits) # 添加颜色图例 legend1 = ax.legend(*scatter.legend_elements(), loc="upper right", title=color_col) ax.add_artist(legend1) # 添加固定点说明文本框(调整位置适配3D视图) textstr = "★ : y=1 mean\n♦ : y=0 mean" props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) ax.text2D(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=12, verticalalignment='top', bbox=props) # 设置3D视角:elev是仰角,azim是方位角 ax.view_init(elev=view_elev, azim=view_azim) # 隐藏未使用的子图 for ax in axes[len(dfs):]: ax.axis('off') # 添加统一的颜色条 plt.colorbar(scatter, ax=axes[:len(dfs)], orientation='horizontal', fraction=0.02, pad=0.04, ticks=np.arange(df[color_col].min(), df[color_col].max() + 1)) plt.show() # 示例用法 # 假设你有多个包含x、y、z、volume列的DataFrame,以及对应的均值点(3D坐标)、类型、标题列表 # plot_with_3d_trisurf_customized(dfs, (4, 4), (12, 8), list_points_mean, list_points_type, # 'x', 'y', 'z', 'volume', titles, view_elev=20, view_azim=60)
关键功能说明
3D视图调整:
- 你可以通过修改函数参数
view_elev(仰角,范围0-90)和view_azim(方位角,范围0-360)来预设视角 - 绘图完成后,你也可以手动拖动3D窗口,自由旋转、缩放来调整到合适的视角
- 你可以通过修改函数参数
绘图元素适配:
- 原2D的散点图换成了3D散点图,同时保留了按
color_col(即volume)着色的逻辑 - 用
plot_trisurf实现了类似原tricontourf的填充着色效果,让3D空间的分布更直观 - 固定点的辅助线也适配了3D空间,分别平行于三个坐标轴
- 原2D的散点图换成了3D散点图,同时保留了按
额外适配:
- 新增了Z轴范围的控制参数
z_limits - 用
text2D来绘制说明文本,确保在3D视图旋转时文本始终保持在画布上
- 新增了Z轴范围的控制参数
备注:内容来源于stack exchange,提问作者PTQuoc
相关产品推荐
相关产品推荐

