拟合曲面与同数据生成的热力图不符问题排查
问题分析与解决:热力图与拟合曲面不匹配问题
问题描述
我有一组覆盖8个x值、10个y值网格的z值,绘制的x-y平面热力图(左侧子图)与用相同数据拟合的曲面(右侧子图)完全不符;同时移除contour1 = ...行中的.T会出现形状不匹配的类型错误。
核心问题拆解
1. z值与网格的维度匹配错位
- 原始
z_values是**(8,10)的数组(对应8个x值为行、10个y值为列),但np.meshgrid(x_values, y_values)生成的x_grid和y_grid是(10,8)**的形状(默认indexing='xy'规则,先遍历y值再遍历x值)。 - 热力图中你用
z_values.T转成(10,8)才匹配网格形状,但拟合时直接用z_values.flatten(),相当于把原始(8,10)的z值按行展平,和x_grid、y_grid展平后的点顺序完全不对应,导致拟合数据错位,曲面自然和热力图不符。
2. 拟合时未对齐网格的维度顺序
x_grid和y_grid展平后是80个元素,顺序对应(10,8)网格的逐行遍历;而原始z_values展平的顺序是(8,10)的逐行遍历,两者的点无法一一对应,必须先把z_values转置成(10,8)再展平,才能和网格点匹配。
修正后的代码
import matplotlib.pyplot as plt import numpy as np from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression x_values = np.linspace(1, 8, 8) y_values = np.linspace(1, 10, 10) z_values = [[0.0128, 0.0029, 0.0009, 0.0006, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0049, 0.0157, 0.0067, 0.0003, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0203, 0.0096, 0.0055, 0.0096, 0.0012, 0.0023, 0.0000, 0.0000, 0.0000, 0.0000], [0.0229, 0.0191, 0.0020, 0.0073, 0.0055, 0.0026, 0.0022, 0.0000, 0.0000, 0.0000], [0.0218, 0.0357, 0.0035, 0.0133, 0.0073, 0.0145, 0.0000, 0.0029, 0.0000, 0.0000], [0.0261, 0.0232, 0.0365, 0.0200, 0.0212, 0.0107, 0.0036, 0.0007, 0.0022, 0.0007], [0.0305, 0.0244, 0.0284, 0.0786, 0.0226, 0.0160, 0.0000, 0.0196, 0.0007, 0.0007], [0.0171, 0.0189, 0.0598, 0.0215, 0.0218, 0.0464, 0.0399, 0.0051, 0.0000, 0.0000]] z_values = np.array(z_values) x_grid, y_grid = np.meshgrid(x_values, y_values) fig = plt.figure(figsize=(12, 5)) # 热力图保持原转置逻辑,匹配网格形状 ax1 = fig.add_subplot(121) contour1 = ax1.contourf(x_grid, y_grid, np.log(z_values.T + 1)) fig.colorbar(contour1, ax=ax1) ax1.set_xlabel('x values') ax1.set_ylabel('y values') # 关键修正:z值先转置,再展平,和x/y网格的点顺序对齐 z_values_matched = z_values.T x_flat = x_grid.flatten() y_flat = y_grid.flatten() z_flat = z_values_matched.flatten() degree = 4 poly_features = PolynomialFeatures(degree=degree) X_poly = poly_features.fit_transform(np.column_stack((x_flat, y_flat))) model = LinearRegression() model.fit(X_poly, z_flat) z_pred = model.predict(X_poly) z_pred_grid = z_pred.reshape(x_grid.shape) ax2 = fig.add_subplot(122, projection='3d') ax2.plot_surface(x_grid, y_grid, np.log(z_pred_grid + 1), cmap='viridis') ax2.set_xlabel('x values') ax2.set_ylabel('y values') ax2.set_zlabel('z values') plt.show()
补充说明
- 修正后,z值的维度和网格完全匹配,拟合出的曲面会和热力图的分布一致。
- 关于
.T的问题:原始z_values的行对应x、列对应y,而meshgrid生成的网格行对应y、列对应x,两者维度方向相反,必须转置才能兼容,否则形状(8,10)和(10,8)不匹配,报错是必然的。
内容的提问来源于stack exchange,提问作者PingPong
相关产品推荐
相关产品推荐

