Python绘制等高线图时plt.clabel触发TypeError错误的解决求助
Python等高线图plt.clabel报错解决方法
问题场景
尝试绘制简单等高线图,使用的样本数据如下:
1,1,0.008935424499213696 2,1,0.0003330092004034668 3,1,0.0007237526588141918 4,1,0.009105708450078964 5,1,0.005323910620063543 6,1,0.002217665547505021 7,1,0.02252855896949768 8,1,0.01543859951198101 9,1,0.005959200672805309 10,1,0.003394557628780603 11,1,0.004915744531899691 12,1,0.7103423476219177 13,1,4.735919952392578 14,143,6.962272167205811 15,143,9.117818832397461 16,143,10.14690971374512 17,143,11.10696411132812 18,143,13.1904764175415 19,143,13.69217777252197 20,143,12.86547660827637 21,143,11.97461032867432 22,143,11.42048358917236 23,143,10.77302360534668 24,143,8.853728294372559 25,143,7.49812650680542 26,143,5.019758224487305 27,143,0.771071195602417
使用的代码如下:
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata # load values X_dat, Y_dat, Z_dat = np.loadtxt('file.txt', unpack=True, delimiter=',') # Convert to numpy arrays X, Y, Z, = np.array([]), np.array([]), np.array([]) for i in range(len(X_dat)): X = np.append(X, X_dat[i]) Y = np.append(Y, Y_dat[i]) Z = np.append(Z, Z_dat[i]) # create x-y points to be used in heatmap xi = np.linspace(X.min(), X.max(), 290) yi = np.linspace(Y.min(), Y.max(), 290) # Interpolate for plotting zi = griddata((X, Y), Z, (xi[None, :], yi[:, None]), method='cubic') # Create the contour plot levels = [0.0, 0.2, 0.5, 0.9, 1.5, 2.5, 3.5] cp = plt.contour(xi, yi, zi, levels, cmap='RdGy') plt.colorbar() plt.show() plt.clabel(cp, fmt='%2.1f', inline='true', fontsize=12) plt.title('Contour Plot') plt.xlabel('x (cm)') plt.ylabel('y (cm)')
运行时触发错误:
TypeError: slice indices must be integers or None or have an __index__ method
错误由plt.clabel()触发。
问题原因
核心问题是**plt.show()的位置错误**:plt.show()会显示并关闭当前绘图窗口,窗口关闭后,contour对象cp已经失效,后续调用plt.clabel(cp)时就会出现切片索引相关的错误。
另外代码中存在冗余逻辑:np.loadtxt返回的本身就是numpy数组,不需要再通过循环逐个append转换。
修复方案
- 调整
plt.show()的位置,将其放在所有绘图修饰(标签、标题、刻度等)之后 - 删除冗余的数组转换逻辑
- 可选:补充处理插值后可能出现的NaN值(避免绘图警告)
修复后的完整代码:
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata # 加载数据,直接得到numpy数组 X, Y, Z = np.loadtxt('file.txt', unpack=True, delimiter=',') # 创建网格点 xi = np.linspace(X.min(), X.max(), 290) yi = np.linspace(Y.min(), Y.max(), 290) # 插值,替换NaN为0(可选,根据需求调整) zi = griddata((X, Y), Z, (xi[None, :], yi[:, None]), method='cubic') zi = np.nan_to_num(zi) # 绘制等高线图 levels = [0.0, 0.2, 0.5, 0.9, 1.5, 2.5, 3.5] cp = plt.contour(xi, yi, zi, levels, cmap='RdGy') # 添加绘图修饰 plt.clabel(cp, fmt='%2.1f', inline=True, fontsize=12) plt.title('Contour Plot') plt.xlabel('x (cm)') plt.ylabel('y (cm)') plt.colorbar() # 最后显示图形 plt.show()
说明
- 调整
plt.show()顺序后,cp对象在窗口显示前是有效的,plt.clabel()可以正常为等高线添加标签 np.nan_to_num(zi)用于处理插值后可能出现的NaN值,避免绘图时的警告信息- 去掉了冗余的数组循环转换,直接使用
np.loadtxt返回的数组,提升代码效率
内容的提问来源于stack exchange,提问作者Conny91
相关产品推荐
相关产品推荐

