如何使用Python的Matplotlib、Pyplot绘制含缺失(x,y)对数据的3D彩色映射曲面图并合并不同数据量的平滑曲线
如何合并不同长度数据点的平滑曲线为3D彩色图(Python)
这其实是3D绘图里很常见的问题,核心解决思路是通过插值把每条曲线统一到相同的采样点上,就能让所有数据长度一致,顺利绘制3D图了。下面是具体的实现步骤和代码:
步骤1:整理并清洗原始数据
首先把你的数据按y值分组,过滤掉z为'-'的无效数据,提取每组有效的x和z值:
import numpy as np from scipy.interpolate import make_interp_spline import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 把原始数据整理为列表格式 raw_data = [ (6, 0, '-'), (6, 3, '-'), (6, 7.5, 10.66), (6, 12, '-'), (6, 15, '-'), (8, 0, 23.23), (8, 3, 14.93), (8, 7.5, 11.38), (8, 12, 3.16), (8, 15, 3.49), (10, 0, '-'), (10, 3, 16.12), (10, 7.5, 10.14), (10, 12, 3.37), (10, 15, '-'), (12, 0, '-'), (12, 3, '-'), (12, 7.5, 10.17), (12, 12, '-'), (12, 15, '-'), ] # 按y值分组,仅保留有有效z值的数据 grouped_data = {} for y_val, x_val, z_val in raw_data: if z_val != '-': if y_val not in grouped_data: grouped_data[y_val] = {'x': [], 'z': []} grouped_data[y_val]['x'].append(x_val) grouped_data[y_val]['z'].append(z_val)
步骤2:统一采样点并做平滑插值
我们先定义一组覆盖所有x范围的均匀采样点(比如从0到15取100个点,数量越多曲线越平滑),然后用三次样条插值给每条曲线生成对应这些采样点的z值,同时把y值扩展成和采样点长度一致的数组:
# 生成统一的x采样点,这里取100个点保证平滑度 uniform_x = np.linspace(0, 15, 100) # 存储插值后的平滑曲线数据 smoothed_curves = [] for y_val, data in grouped_data.items(): # 将每组的x、z转换为numpy数组 x_arr = np.array(data['x']) z_arr = np.array(data['z']) # 创建三次样条插值函数,k=3保证曲线平滑 spline_func = make_interp_spline(x_arr, z_arr, k=3) # 得到对应统一x采样点的平滑z值 smoothed_z = spline_func(uniform_x) # 把y值扩展为和uniform_x长度一致的数组,适配3D绘图要求 uniform_y = np.full_like(uniform_x, y_val) smoothed_curves.append( (uniform_y, uniform_x, smoothed_z) )
步骤3:绘制3D彩色平滑曲线
现在所有曲线的长度都一致了,直接用matplotlib的3D绘图功能,给每条曲线分配不同颜色,合并到同一幅图即可:
# 创建3D绘图对象 fig = plt.figure(figsize=(10, 7)) ax = fig.add_subplot(111, projection='3d') # 给每条曲线分配差异化的颜色 curve_colors = ['#FF9A56', '#4A90E2', '#2ECC71', '#E74C3C'] # 遍历绘制每条平滑曲线 for idx, (y_arr, x_arr, z_arr) in enumerate(smoothed_curves): ax.plot(x_arr, y_arr, z_arr, color=curve_colors[idx], linewidth=2, label=f'y={y_arr[0]}') # 设置坐标轴标签和图例 ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Z Axis') ax.legend(loc='upper right') plt.show()
额外小提示
- 如果数据量特别小,可以用
scipy.interpolate.interp1d代替make_interp_spline,但三次样条的平滑效果会更出色。 - 如果想要绘制彩色曲面而非单独曲线,可以进一步对
y轴做均匀采样,用griddata生成完整网格数据后,调用plot_surface绘制。 - 注意检查每组有效点数量:插值函数至少需要2个有效点,若某组有效点不足,可能需要补全数据或跳过该组。
内容的提问来源于stack exchange,提问作者Saba
相关产品推荐
相关产品推荐

