You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib中Contour图与Colorbar不匹配问题求助

问题分析与解决方案

核心问题点

  1. 误用contour而非contourf:contour仅绘制等高线线条,不会填充区域,所以图中大部分区域显示白色背景,只有阈值处的线条有颜色,和你需要的区域填充效果不符。
  2. BoundaryNorm边界设置错误:当使用ncolors=2时,boundaries数组需要包含3个值(用来划分2个区间:低于阈值、高于阈值),原代码仅提供2个边界值,导致颜色映射逻辑混乱,出现异常白色区域。
  3. Colorbar刻度与映射不匹配:由于norm的边界错误,colorbar的刻度计算出现偏差,导致多余的未命名刻度。

修正后的代码

from matplotlib import colors, cm
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri

np.random.seed(19680801)
npts = 200
ngridx = 100
ngridy = 200
x = np.random.uniform(-2, 2, npts)
y = np.random.uniform(-2, 2, npts)
z = x * np.exp(-x**2 - y**2)

xi = np.linspace(-2.1, 2.1, ngridx)
yi = np.linspace(-2.1, 2.1, ngridy)

triang = tri.Triangulation(x, y)
interpolator = tri.LinearTriInterpolator(triang, z)

Xi, Yi = np.meshgrid(xi, yi)
zi = interpolator(Xi, Yi)

# 处理插值后的NaN值,避免极值计算出错
zi_min = np.nanmin(zi)
zi_max = np.nanmax(zi)

fig = plt.figure()
ax = fig.subplots()

colormapList = ['blue', 'red']
colorThreshold = np.mean(z)

# 修正BoundaryNorm的边界:3个值划分2个区间
norm = colors.BoundaryNorm([zi_min, colorThreshold, zi_max], ncolors=2, clip=True)
cmap = colors.LinearSegmentedColormap.from_list('custom_cmap', colormapList, N=2)

# 使用contourf填充区域,而非contour绘制线条
contour_plot = ax.contourf(xi, yi, zi, norm=norm, cmap=cmap)

# 直接用contour_plot作为mappable,无需重新创建ScalarMappable
cbar = fig.colorbar(contour_plot, ax=ax)
# 设置刻度和标签,格式化数值避免过长小数
cbar.set_ticks([zi_min, colorThreshold, zi_max])
cbar.set_ticklabels([f'{zi_min:.2f}', f'{colorThreshold:.2f}', f'{zi_max:.2f}'])

plt.show()

关键修改说明

  • 替换contour为contourf:实现区域颜色填充,满足“低于阈值蓝色、高于阈值红色”的需求。
  • 修正BoundaryNorm边界:用[zi_min, colorThreshold, zi_max]作为边界,明确划分两个区间,确保颜色映射正确。
  • 复用contour_plot作为mappable:无需手动创建ScalarMappable,直接使用contourf返回的对象,保证colorbar与绘图的映射完全一致。
  • 格式化刻度标签:避免过长的小数显示,提升可读性。

内容的提问来源于stack exchange,提问作者Auguste Eclancher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:45:06