如何从matplotlib 3D图表及对应方程中提取X/Y/Z数据点
问题说明
现有一段可正常运行、用于生成3D曲面图的Python代码,需求是提取图表对应的X、Y、Z轴数值为列表格式,方便后续复制到Excel做数据运算处理,属于「基于已有数据集绘制图表」的逆向操作,原代码如下:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter import numpy as np fig = plt.figure() ax = fig.gca(projection='3d') N = np.arange(0, 10, 1) M = np.arange(0, 15, 1) N, M = np.meshgrid(N, M) DNM = 3992.88*N - 2585.96*M surf = ax.plot_surface(N, M, DNM, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False) ax.set_zlim(-25000, 20000) ax.zaxis.set_major_locator(LinearLocator(10)) ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) fig.colorbar(surf, shrink=0.5, aspect=10) plt.show()
实现方案
你不需要从渲染完成的图表对象里反向提取数据,绘图用的X/Y/Z原始数据在代码里已经生成了,直接转换格式即可使用:
- 轴和变量的对应关系:
- X轴对应网格数组
N - Y轴对应网格数组
M - Z轴对应高度计算结果数组
DNM
- X轴对应网格数组
- 转普通Python列表:直接调用numpy数组的
.tolist()方法即可,如果是要粘贴到Excel,更推荐用扁平化的一维列表,三个列表同索引的值就是曲面上一个点的完整坐标,不需要处理二维嵌套结构,代码如下:
# 保留二维网格结构的列表 x_grid_list = N.tolist() y_grid_list = M.tolist() z_grid_list = DNM.tolist() # 扁平化逐点对应的一维列表,适合Excel按列粘贴 x_flat_list = N.flatten().tolist() y_flat_list = M.flatten().tolist() z_flat_list = DNM.flatten().tolist()
- 如果想省掉手动复制的步骤,可以直接导出为Excel能直接打开的CSV文件,代码如下:
import csv # 导出为CSV,用Excel直接打开即可使用 with open("3d曲面数据.csv", "w", newline="", encoding="utf-8-sig") as f: write = csv.writer(f) # 写表头 write.writerow(["X值", "Y值", "Z值"]) # 逐行写入每个点的坐标 for x, y, z in zip(x_flat_list, y_flat_list, z_flat_list): write.writerow([x, y, z])
注意:不要尝试从
plot_surface返回的surf对象里反向提取数据,绘图时设置的zlim等参数会裁剪超出范围的数值,拿到的不是完整原始数据,直接用绘图前生成的N/M/DNM数组才是和计算逻辑完全一致的完整数据集。
内容的提问来源于stack exchange,提问作者Mohamed Osman
相关产品推荐
相关产品推荐

