Matplotlib绘图中屏蔽特定值、色条适配及相关报错问题求助
解决Matplotlib tricontourf绘制xarray气象数据的常见问题
1. 解决掩码后z与x/y长度不一致的报错
tricontourf要求x、y、z为长度相同的一维数组,直接对z使用掩码数组会导致内部三角化时长度不匹配。正确做法是同步过滤x、y、z中不符合阈值的元素:
import xarray as xr import matplotlib.pyplot as plt import numpy as np # 加载xarray数据 ds = xr.open_dataset('your_tqc_data.nc') tqc = ds['TQC'] # 将数据展平为一维 x = tqc.lon.values.flatten() y = tqc.lat.values.flatten() z = tqc.values.flatten() # 过滤阈值(如0.2)以上的数据 threshold = 0.2 valid_idx = z >= threshold x_valid = x[valid_idx] y_valid = y[valid_idx] z_valid = z[valid_idx]
2. 让vmin/vmax生效
确保在调用tricontourf时明确指定vmin/vmax参数,且使用过滤后的有效数据(或正确的掩码数组):
fig, ax = plt.subplots(figsize=(10, 6)) # 使用过滤后的数据,指定vmin为阈值,vmax为数据最大值 contour_plot = ax.tricontourf( x_valid, y_valid, z_valid, vmin=threshold, vmax=np.nanmax(z_valid), cmap='viridis' )
如果使用掩码数组,需确保z是numpy.ma.MaskedArray,同时指定vmin:
z_masked = np.ma.masked_less(z, threshold) contour_plot = ax.tricontourf( x, y, z_masked, vmin=threshold, cmap='viridis', extend='min' # 必须设置,否则set_under不生效 )
3. 正确使用cmap.set_under屏蔽低值
若需保留所有数据点但屏蔽阈值以下的值,需配合extend='min'和vmin参数:
cmap = plt.get_cmap('viridis') # 设置阈值以下的值为白色(或透明:'none') cmap.set_under('white') fig, ax = plt.subplots(figsize=(10, 6)) contour_plot = ax.tricontourf( x, y, z_masked, vmin=threshold, cmap=cmap, extend='min' )
- 必须设置
extend='min',否则色条不会显示低值的标记,且set_under的颜色不会应用到数据点 vmin需与屏蔽阈值一致,确保小于该值的点被识别为"under"
4. 精确匹配colorbar与图高度
使用mpl_toolkits.axes_grid1的make_axes_locatable,无需手动调整shrink参数:
from mpl_toolkits.axes_grid1 import make_axes_locatable fig, ax = plt.subplots(figsize=(10, 6)) contour_plot = ax.tricontourf(x_valid, y_valid, z_valid, vmin=threshold, cmap='viridis') # 分割主轴,创建与主图高度一致的色条轴 divider = make_axes_locatable(ax) # size设置色条宽度,pad设置色条与主图的间距 cax = divider.append_axes("right", size="5%", pad=0.1) # 添加色条到新建的轴 fig.colorbar(contour_plot, cax=cax) plt.show()
完整示例代码
方式1:过滤无效数据(推荐,性能更优)
import xarray as xr import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.axes_grid1 import make_axes_locatable # 加载数据 ds = xr.open_dataset('tqc_data.nc') tqc = ds['TQC'] threshold = 0.2 # 展平并过滤数据 x = tqc.lon.values.flatten() y = tqc.lat.values.flatten() z = tqc.values.flatten() valid_idx = z >= threshold x_valid, y_valid, z_valid = x[valid_idx], y[valid_idx], z[valid_idx] # 绘图 fig, ax = plt.subplots(figsize=(10, 6)) contour = ax.tricontourf( x_valid, y_valid, z_valid, vmin=threshold, vmax=np.nanmax(z_valid), cmap='viridis' ) # 创建匹配高度的色条 divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.1) fig.colorbar(contour, cax=cax, label='Total Column Cloud Water (TQC)') ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') ax.set_title('TQC Distribution (≥0.2)') plt.show()
方式2:使用掩码数组保留所有点
import xarray as xr import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.axes_grid1 import make_axes_locatable # 加载数据 ds = xr.open_dataset('tqc_data.nc') tqc = ds['TQC'] threshold = 0.2 # 展平并创建掩码数组 x = tqc.lon.values.flatten() y = tqc.lat.values.flatten() z = tqc.values.flatten() z_masked = np.ma.masked_less(z, threshold) # 设置颜色映射 cmap = plt.get_cmap('viridis') cmap.set_under('white') # 绘图 fig, ax = plt.subplots(figsize=(10, 6)) contour = ax.tricontourf( x, y, z_masked, vmin=threshold, cmap=cmap, extend='min' ) # 创建匹配高度的色条 divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.1) fig.colorbar(contour, cax=cax, label='Total Column Cloud Water (TQC)') ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') ax.set_title('TQC Distribution (Values <0.2 masked)') plt.show()
内容的提问来源于stack exchange,提问作者Louschmuh
相关产品推荐
相关产品推荐

