Xarray绘制稀疏数据时如何避免插值并屏蔽空白区域?
Xarray用pcolormesh处理不连续坐标轴绘图的解决方案
Xarray的坐标感知特性是它的核心优势——和imshow只按行列索引绘图不同,它会基于数据的真实维度坐标来渲染。但用pcolormesh(Xarray绘图默认后端)处理带不连续坐标轴的二维数据时,会自动在坐标间隙插值填充,这在很多场景下不是我们想要的结果。
举个实际场景的示例代码:
import numpy as np import xarray as xr x = np.random.randn(1000, 100) # 构造分段不连续的y坐标:0.0-0.1、1.0-1.1……99.0-99.1 y = np.hstack([np.arange(0, .1, 0.01) + i for i in range(100)]) z = np.linspace(0, 20, 100) da = xr.DataArray(x.T, dims=("z", "y"), coords={"y": y, "z": z}) # 截取y在1-4区间的数据绘图 da.sel(y=slice(1, 4)).plot()
这段代码里的y维度是分段断开的,绘图时pcolormesh会在分段间隙(比如0.1到1.0之间)自动插值填充空白。我们的需求是:不用重采样、也不用在y维度补NaN,直接屏蔽这些无数据的空白区域,只保留有数据的分段部分。
这里要明确两个点:
imshow解决不了这个问题,它无法识别坐标轴的跳跃,只会按行列位置平铺渲染(这是它的设计逻辑,不是bug)。pcolormesh的插值是基于坐标信息填充间隙,而imshow仅把行列索引当作颜色块的位置依据。
要实现只显示有数据区域的效果,核心是让pcolormesh仅在数据存在的坐标区间内绘制网格。可以通过手动构造网格边界的方式实现,具体代码如下:
import matplotlib.pyplot as plt # 截取目标y区间的数据 da_sub = da.sel(y=slice(1, 4)) y_vals = da_sub.y.values z_vals = da_sub.z.values # 找到y坐标的分段分界点(突变位置) split_indices = np.where(np.diff(y_vals) > 0.1)[0] + 1 # 把y坐标拆分成独立的分段 y_segments = np.array_split(y_vals, split_indices) # 初始化绘图 fig, ax = plt.subplots() # 遍历每个分段单独绘制 for seg in y_segments: # 获取当前分段对应的数据集 seg_data = da_sub.sel(y=seg).values # 构造当前分段的y方向边界(每个数据点对应网格左边界,最后追加右边界) y_edges = np.concatenate([seg, [seg[-1] + (seg[1]-seg[0])]]) # 构造z方向边界 z_edges = np.concatenate([z_vals, [z_vals[-1] + (z_vals[1]-z_vals[0])]]) # 绘制当前分段的网格 ax.pcolormesh(y_edges, z_edges, seg_data, shading='flat') # 设置标签和色bar ax.set_xlabel('y') ax.set_ylabel('z') plt.colorbar(ax.collections[0], ax=ax) plt.show()
这样处理后,绘图只会展示有数据的分段区域,不会在间隙处进行不必要的插值填充。
内容的提问来源于stack exchange,提问作者3dSpatialUser
相关产品推荐
相关产品推荐

