Pyplot Imshow Autozoom 剪掉不规则的 NaN 填充
Pyplot Imshow Autozoom to cut out Irregular NaN padding
我有以下代码
import matplotlib.pyplot as plt
import numpy as np
array = np.pad(np.random.rand(300,300),10,'constant', constant_values = nan)
fig, ax = plt.subplots()
l = ax.imshow(array, origin = 'lower')
plt.show()
如您所见,它绘制了一个图像,边缘周围有一个 NaN 边框。有没有办法让 Imshow 自动裁剪或自动缩放到没有 NaN 的绘图区域?
有一些注意事项。
Padding is Unequal:在这个例子中,padding 在所有边上都是相等的,但这不是我的真实数据,所以它不能假设每一边都有相同的 pad。
无法物理编辑数组:实际数据实际上是一个带有 WCS 坐标数据的天文 FITS 文件,因此使用 WCSAxesSubplot 系统,使用 plt.fig.add_subplot(projection = wcs)
命令,以及来自 astropy
,但没有办法很好地将其包含在我的示例代码中。 (就是说,如果有人能告诉我如何在常规 pyplot/matplotlib/imshow 中执行此操作,我有信心,我可以以某种方式将其传输过来。)真正的问题是我因此无法编辑原始数据数组以删除 NaN因为我的头文件(即参考像素)将不正确并且我的坐标将关闭。
NaNs 可能与图像边缘不对齐:未来的数据集可能会稍微旋转,甚至在图像的位之间有 NaNs 的字段。因此,我不能让它切掉我的图像的角或部分只是为了很好地适合其他部分。某些 NaN 可能在缩放后仍然需要可见。 (现在这不是什么大问题,因为我当前的数据集都有很好的、笔直的、轴平行的边缘)。
如果您能提供任何帮助,我们将不胜感激。我很乐意提供额外的信息。此外,一旦自动实现缩放,如果有人可以指出如何从图像中恢复当前缩放,那就太好了(因为它解决了一个不相关的问题)。
这应该有效:
mask = ~np.isnan(array)
x = np.flatnonzero(np.any(mask, axis = 0))
x = np.arange(x.min(), x.max() + 1)[:, None]
y = np.flatnonzero(np.any(mask, axis = 1))
y = np.arange(y.min(), y.max() + 1)
plt.imshow(array[x,y], origin = 'lower')
基本上只是用任何非nan
值构建行和列的奇特索引。
您可以确定 non-NaN 个元素的索引,如下所示
bound = np.argwhere(~np.isnan(array))
和 xlim
和 ylim
只是这些指数的 minima/maxima
plt.xlim(min(bound[:, 1]), max(bound[:, 1]))
plt.ylim(min(bound[:, 0]), max(bound[:, 0]))
要缩小,只需执行以下操作
shape = np.shape(array)
plt.xlim(0, shape[1]-1)
plt.ylim(0, shape[0]-1)
我有以下代码
import matplotlib.pyplot as plt
import numpy as np
array = np.pad(np.random.rand(300,300),10,'constant', constant_values = nan)
fig, ax = plt.subplots()
l = ax.imshow(array, origin = 'lower')
plt.show()
如您所见,它绘制了一个图像,边缘周围有一个 NaN 边框。有没有办法让 Imshow 自动裁剪或自动缩放到没有 NaN 的绘图区域?
有一些注意事项。
Padding is Unequal:在这个例子中,padding 在所有边上都是相等的,但这不是我的真实数据,所以它不能假设每一边都有相同的 pad。
无法物理编辑数组:实际数据实际上是一个带有 WCS 坐标数据的天文 FITS 文件,因此使用 WCSAxesSubplot 系统,使用
plt.fig.add_subplot(projection = wcs)
命令,以及来自astropy
,但没有办法很好地将其包含在我的示例代码中。 (就是说,如果有人能告诉我如何在常规 pyplot/matplotlib/imshow 中执行此操作,我有信心,我可以以某种方式将其传输过来。)真正的问题是我因此无法编辑原始数据数组以删除 NaN因为我的头文件(即参考像素)将不正确并且我的坐标将关闭。NaNs 可能与图像边缘不对齐:未来的数据集可能会稍微旋转,甚至在图像的位之间有 NaNs 的字段。因此,我不能让它切掉我的图像的角或部分只是为了很好地适合其他部分。某些 NaN 可能在缩放后仍然需要可见。 (现在这不是什么大问题,因为我当前的数据集都有很好的、笔直的、轴平行的边缘)。
如果您能提供任何帮助,我们将不胜感激。我很乐意提供额外的信息。此外,一旦自动实现缩放,如果有人可以指出如何从图像中恢复当前缩放,那就太好了(因为它解决了一个不相关的问题)。
这应该有效:
mask = ~np.isnan(array)
x = np.flatnonzero(np.any(mask, axis = 0))
x = np.arange(x.min(), x.max() + 1)[:, None]
y = np.flatnonzero(np.any(mask, axis = 1))
y = np.arange(y.min(), y.max() + 1)
plt.imshow(array[x,y], origin = 'lower')
基本上只是用任何非nan
值构建行和列的奇特索引。
您可以确定 non-NaN 个元素的索引,如下所示
bound = np.argwhere(~np.isnan(array))
和 xlim
和 ylim
只是这些指数的 minima/maxima
plt.xlim(min(bound[:, 1]), max(bound[:, 1]))
plt.ylim(min(bound[:, 0]), max(bound[:, 0]))
要缩小,只需执行以下操作
shape = np.shape(array)
plt.xlim(0, shape[1]-1)
plt.ylim(0, shape[0]-1)