图像上的 contourf 作为输入,如何剪裁成一个圆圈

contourf on an image as input, how to clip to a circle

python 3.8.10, ubuntu 20.04, vsc 我正在尝试在剪裁到圆形补丁后执行 contourf。似乎无法得到它。 补丁已正确应用,但我无法弄清楚如何制作轮廓。错误在轮廓线上:

float() argument must be a string or a number, not 'AxesImage'

def contour_calc(img):
    #img is np 1832x1832 greyscale 8 bit

    fig, ax = plt.subplots()
    im = ax.imshow(img)
    patch = patches.Circle((916, 916), radius=900, transform=ax.transData)
    im.set_clip_path(patch)
    ax.axis('off')

    #plt.show() # works perfectly, patch is applied

    contourf(im,levels=2, colors=['k','w'])

    plt.show()

完整错误跟踪:

Traceback (most recent call last):
  File "/home/cliff/Documents/vsc_projects/tychocam_main/mainApp/cloud_processing/contours.py", line 24, in contour_calc
    ax.contourf(im,levels=2, colors=['k','w'])
  File "/home/cliff/.local/lib/python3.8/site-packages/matplotlib/__init__.py", line 1412, in inner
    return func(ax, *map(sanitize_sequence, args), **kwargs)
  File "/home/cliff/.local/lib/python3.8/site-packages/matplotlib/axes/_axes.py", line 6271, in contourf
    contours = mcontour.QuadContourSet(self, *args, **kwargs)
  File "/home/cliff/.local/lib/python3.8/site-packages/matplotlib/contour.py", line 812, in __init__
    kwargs = self._process_args(*args, **kwargs)
  File "/home/cliff/.local/lib/python3.8/site-packages/matplotlib/contour.py", line 1441, in _process_args
    x, y, z = self._contour_args(args, kwargs)
  File "/home/cliff/.local/lib/python3.8/site-packages/matplotlib/contour.py", line 1476, in _contour_args
    z = ma.asarray(args[0], dtype=np.float64)
  File "/home/cliff/.local/lib/python3.8/site-packages/numpy/ma/core.py", line 7952, in asarray
    return masked_array(a, dtype=dtype, copy=False, keep_mask=True,
  File "/home/cliff/.local/lib/python3.8/site-packages/numpy/ma/core.py", line 2829, in __new__
    _data = np.array(data, dtype=dtype, copy=copy,
TypeError: float() argument must be a string or a number, not 'AxesImage'

您可以创建一个 numpy 掩码来过滤掉圆圈区域之外的所有内容:

from matplotlib import pyplot as plt
from matplotlib import patches
import numpy as np
from scipy.ndimage import gaussian_filter

# create a test image
img = gaussian_filter(np.random.rand(1832, 1832), 50)
img -= img.min()
img *= 255 / img.max()
img = img.astype(np.uint8)

# mask away everything outside the circle area
x, y = np.meshgrid(np.arange(img.shape[1]), np.arange(img.shape[0]))
xm, ym = 916, 916
rad = 900
img_ma = np.ma.array(img, mask=(x - xm) ** 2 + (y - ym) ** 2 > rad ** 2)

fig, ax = plt.subplots()
ax.contourf(img_ma, levels=2, colors=['crimson', 'gold'])
ax.axis('off')
ax.set_aspect('equal')  # show a circle as a circle, not as an ellipse
plt.show()