如何使用带掩码的numpy数组绘制带levels参数的contourf填充等高线
问题根源
你遇到的问题核心由两个原因共同导致:
- 掩码数组运算的规则不一致:你计算
hdd时用的是普通NumPy数组hdd_norm和掩码数组meantempf做减法,虽然NumPy理论上会保留掩码属性,但实际运算中可能出现掩码传播异常;而meantempf的计算全程是掩码数组之间的算术操作,掩码属性始终正常。 - 数值范围与levels不匹配:
hdd的物理意义是采暖度日数,当平均温度高于65℉时hdd会出现负数,而你设置的levels下限是0,大量负数值+异常的掩码会让contourf把原本无数据的区域、负数值区域错误填充,而meantempf的数值范围刚好和你设置的levels匹配,所以不会出问题。
解决方法
按以下步骤修改代码即可正常绘图:
- 统一用掩码数组计算
hdd:你已经定义了掩码数组格式的hdd_norm_ma,把计算hdd的代码换成:
hdd = hdd_norm_ma - meantempf
避免普通数组和掩码数组运算导致的掩码异常。
2. 截断无效负数值:按照采暖度日数的定义,高于65℉时HDD为0,把负数区域设为掩码,添加一行代码:
hdd = np.ma.masked_less(hdd, 0)
- 缩放后同步调整levels范围:如果你需要把
hdd乘以10,要同步调整levels的数值范围匹配缩放后的hdd取值,比如:
hdd = hdd * 10 levels = np.arange(0, 600, 50) # 数值范围根据你实际hdd的最大值调整
- 给
contourf添加extend参数:明确超出levels范围的数值处理逻辑,避免乱填充:
hdd_contours = plt.contourf(lons, lats, hdd, levels = levels, cmap=get_cmap("gist_rainbow"), transform = crs.PlateCarree(), zorder = 1, extend='max')
另外注意你代码里的循环逻辑:range_times遍历2、3两个时次,每次都会覆盖hdd的值,最终绘图用的是最后一个时次的计算结果,确认是否符合你的业务需求。
内容的提问来源于stack exchange,提问作者alpinemike
相关产品推荐
相关产品推荐

