Saving a chart as a numpy array and warping it using skimage

cheatsheet
matplotlib
numpy
Author

Teresa Kubacka

Published

August 3, 2022

Sometimes we may want to create an image with plotting API of matplotlib, but then apply a transform that only works for numpy arrays (for example, skimage’s warps). This is how you do it:

import matplotlib.pyplot as plt 
import numpy as np
%matplotlib inline

Let’s generate an example chart:

x = [1,2,3]
bars = [10,15,12]

f, ax = plt.subplots(dpi=100)
# when using plt.subplots, the canvas and renderer get created automatically 
ax.bar(x, bars);

Export the figure to a numpy array

Method 1 src

s, (width, height) = f.canvas.print_to_buffer()
rgba = np.frombuffer(s, np.uint8).reshape((height, width, 4))
plt.imshow(rgba, aspect='equal');

print(type(rgba))
print(rgba.shape)
<class 'numpy.ndarray'>
(400, 600, 4)

Method 2 src

rgba = np.asarray(f.canvas.buffer_rgba())
plt.imshow(rgba);

print(type(rgba))
print(rgba.shape)
<class 'numpy.ndarray'>
(400, 600, 4)

Remove the alpha channel in a numpy array (RGBA->RGB)

To remove the alpha channel it’s enough to run: src

rgb = rgba[:,:,:3]

The resulting chart is the same (our transparency is anyway white)

plt.imshow(rgb);

Both methods respect the dpi set when creating the figure using plt.subplots

Warping images using skimage

Now we can warp the image:

from skimage.transform import swirl

swirled = swirl(rgb, rotation=0, strength=30, radius=120)
f, ax = plt.subplots(ncols = 2, figsize=(10,4))

ax[0].imshow(rgb, aspect='equal')
ax[0].set_title('original')

ax[1].imshow(swirled, aspect='equal')
ax[1].set_title('warped')

[a.axis('off') for a in ax];

More on skimage transforms: https://scikit-image.org/docs/stable/api/skimage.transform.html