Home > front end >  contourf on an image as input, how to clip to a circle
contourf on an image as input, how to clip to a circle

Time:03-08

python 3.8.10, ubuntu 20.04, vsc I am trying to do a contourf after clipping to a circle patch. Can't seem to get it. The patch is applied correctly, but I have not been able to figure out how to do the contour. error is on contour line:

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()

Full error trace:

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'

CodePudding user response:

You could create a numpy mask to filter away everything outside the circle area:

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()

plt.contourf on an image, masking a circle

  • Related