Matplotlib中3D热力图(XY,C)插值结果异常,求助排查
极坐标环形插值热力图异常问题
我在2D极坐标图中绘制了带第三维度强度值的XY坐标点,尝试实现圆形插值热力图,但结果不符合预期:左侧散点图能正确呈现三层环形强度分布(外层值100、中层50、内层1),但右侧插值后的热力图完全无法匹配该分布,更换插值方法也未解决问题。
原始代码
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata ### INTENSITY VALUES FOR HEATMAP ### T1 = 100,100,100,100,100,100,50,50,50,50,50,50,1,1,1,1,1,1, ### CO-ORDINATES ### a=0 b=0 rO = 7.5 rM = 5 rI = 2.5 heights = 1,2,3,4,5 ### RADIAL POINTS ### def XCoords(a,rO,rM,rI): XsX = [] O = np.linspace(0,2*np.pi,6,endpoint=False) for i in O: xx = a+rO*np.cos(i),a+rM*np.cos(i),a+rI*np.cos(i) XsX.append(xx) return XsX Xs1,Xs2,Xs3 = np.column_stack(XCoords(a,rO,rM,rI)) def YCoords(b,rO,rM,rI): YsY = [] O = np.linspace(0,2*np.pi,6,endpoint=False) for i in O: yy = a+rO*np.sin(i),a+rM*np.sin(i),a+rI*np.sin(i) YsY.append(yy) return YsY Ys1,Ys2,Ys3 = np.column_stack(YCoords(b,rO,rM,rI)) def cart2pol(x,y): rho = np.sqrt(x**2 + y**2) phi = np.arctan2(y,x) return (rho,phi) PolarR1, PolarT1 = cart2pol(Xs1,Ys1) PolarR2, PolarT2 = cart2pol(Xs2,Ys2) PolarR3, PolarT3 = cart2pol(Xs3,Ys3) PolarRF = PolarR1,PolarR2,PolarR3 PolarTF = PolarT1,PolarT2,PolarT3 ### INTERPOLATION ATTEMPT ### max_r = 7.5 max_theta = 2*np.pi theta = np.linspace(0,max_theta,200) r = np.linspace(0,max_r,200) grid_r,grid_theta = np.meshgrid(r,theta) X,Y = np.meshgrid(PolarRF,PolarTF) points = np.column_stack((X.flatten(),Y.flatten())) values = np.linspace(np.min(T1),np.max(T1),324) data = griddata(points,values,(grid_r,grid_theta),method='nearest',fill_value=0,rescale=False) ### HEAT MAP COLORS ### grad = 'viridis' cA = T1 mB = plt.cm.ScalarMappable(cmap=grad) fAcolors = mB.to_rgba(cA) ### PLOT ### fig = plt.figure(figsize=(15,15), dpi=300) ax = fig.add_subplot(121,projection='polar') ax.scatter(PolarTF,PolarRF,s=200,c=fAcolors,alpha=0.5) fig2 = plt.figure(figsize=(15,15),dpi=300) ax2 = fig.add_subplot(122,projection='polar') ax2.pcolormesh(grid_theta,grid_r,data,alpha=0.5) plt.show()
问题根源与修正方案
核心问题
- 点-值对应关系错误:用
np.linspace生成的values完全脱离了原始T1的强度分配,每个坐标点没有匹配到正确的强度值。 - 原始点构建冗余:
np.meshgrid(PolarRF,PolarTF)生成了多余的点组合,导致points数组维度错误。 - 插值网格维度不匹配:
griddata的输入网格与points的维度对应错误,导致插值结果混乱。 - 函数笔误:
YCoords函数中误用了变量a,应该使用b。
修正后的代码
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata ### INTENSITY VALUES FOR HEATMAP ### T1 = np.array([100]*6 + [50]*6 + [1]*6) # 明确外层6个100,中层6个50,内层6个1 ### CO-ORDINATES ### a=0 b=0 rO = 7.5 rM = 5 rI = 2.5 ### RADIAL POINTS ### def XCoords(a,rO,rM,rI): XsX = [] O = np.linspace(0,2*np.pi,6,endpoint=False) for i in O: xx = (a+rO*np.cos(i), a+rM*np.cos(i), a+rI*np.cos(i)) XsX.append(xx) return XsX Xs1,Xs2,Xs3 = np.column_stack(XCoords(a,rO,rM,rI)) def YCoords(b,rO,rM,rI): YsY = [] O = np.linspace(0,2*np.pi,6,endpoint=False) for i in O: yy = (b+rO*np.sin(i), b+rM*np.sin(i), b+rI*np.sin(i)) # 修复笔误:a改为b YsY.append(yy) return YsY Ys1,Ys2,Ys3 = np.column_stack(YCoords(b,rO,rM,rI)) def cart2pol(x,y): rho = np.sqrt(x**2 + y**2) phi = np.arctan2(y,x) return (rho,phi) PolarR1, PolarT1 = cart2pol(Xs1,Ys1) PolarR2, PolarT2 = cart2pol(Xs2,Ys2) PolarR3, PolarT3 = cart2pol(Xs3,Ys3) # 合并原始极坐标点,确保每个点对应正确的T1值 PolarR = np.concatenate([PolarR1, PolarR2, PolarR3]) PolarT = np.concatenate([PolarT1, PolarT2, PolarT3]) ### INTERPOLATION ATTEMPT ### max_r = 7.5 max_theta = 2*np.pi theta = np.linspace(0, max_theta, 200) r = np.linspace(0, max_r, 200) grid_theta, grid_r = np.meshgrid(theta, r) # 调整顺序,匹配griddata输入要求 # 构建正确的点数组:每个点是(theta, r) points = np.column_stack((PolarT, PolarR)) values = T1 # 直接用原始强度值,确保一一对应 # 插值:使用cubic获得更平滑的效果,也可切换为linear/nearest data = griddata(points, values, (grid_theta, grid_r), method='cubic', fill_value=0) ### HEAT MAP COLORS ### grad = 'viridis' mB = plt.cm.ScalarMappable(cmap=grad) mB.set_array(T1) # 设置颜色映射的范围 ### PLOT ### fig = plt.figure(figsize=(12,6), dpi=100) # 左侧散点图 ax1 = fig.add_subplot(121, projection='polar') ax1.scatter(PolarT, PolarR, s=200, c=T1, cmap=grad, alpha=0.5) ax1.set_title('原始散点图') # 右侧插值热力图 ax2 = fig.add_subplot(122, projection='polar') im = ax2.pcolormesh(grid_theta, grid_r, data, cmap=grad, alpha=0.8) ax2.set_title('插值热力图') fig.colorbar(mB, ax=[ax1, ax2], shrink=0.8) plt.tight_layout() plt.show()
关键改动说明
- 明确
T1的数组结构,确保每个环形的点对应正确的强度值 - 合并原始极坐标点时直接拼接,避免冗余的网格点生成
- 调整插值网格的生成顺序,匹配
griddata的输入要求 - 修复了
YCoords函数中误用a的笔误 - 统一颜色映射,添加色标方便对比
内容的提问来源于stack exchange,提问作者IrwinJ
相关产品推荐
相关产品推荐

