Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Featurizers for machine learned models.
4"""
5import sys
6import io
7import os
8import urllib.request
9from PIL import Image
12def plot_gallery_images(imgs, texts=None, width=4, return_figure=False,
13 ax=None, folder_image=None, **figure):
14 """
15 Plots a gallery of images using :epkg:`matplotlib`.
17 @param imgs list of images (filename, urls or :epkg:`Pillow` objects),
18 @param texts text to display (if None, print ``'img % i'``)
19 @param width number of images on the same line (unused if *imgs* is a matrix)
20 @param figure additional parameters when the figure is created
21 @param return_figure return the figure as well as the axes
22 @param ax None or existing axes, it should have the same
23 shape of *imgs*
24 @param folder_image image paths may be relative to some folder,
25 in that case, they should be relative to
26 this folder
27 @return axes or (figure, axes) if *return_figure* is True
29 .. image:: gal.jpg
31 See also notebook :ref:`searchimageskerasrst` or
32 :ref:`searchimagestorchrst` for an example.
33 *imgs* can also be a matrix to force the function to
34 use the same coordinates.
35 """
36 if "plt" not in sys.modules:
37 import matplotlib.pyplot as plt # pylint: disable=C0415
39 if hasattr(imgs, 'shape') and len(imgs.shape) == 2:
40 height, width = imgs.shape
41 if ax is not None and ax.shape != imgs.shape:
42 raise ValueError( # pragma: no cover
43 "ax.shape {0} != imgs.shape {1}".format(ax.shape, imgs.shape))
44 imgs = imgs.ravel()
45 if texts is not None:
46 texts = texts.ravel()
47 else:
48 height = len(imgs) // width
49 if len(imgs) % width != 0:
50 height += 1
52 if ax is None:
53 if 'figsize' not in figure:
54 figure['figsize'] = (12, height * 3)
55 fig, ax = plt.subplots(height, width, **figure)
56 elif return_figure:
57 raise ValueError( # pragma: no cover
58 "ax is specified and return_figure is True")
60 for i, img in enumerate(imgs):
61 if img is None:
62 continue
63 y, x = i // width, i % width
64 if height == 1:
65 ind = x
66 elif width == 1:
67 ind = y
68 else:
69 ind = y, x
71 if isinstance(img, str):
72 if "//" in img:
73 # url
74 with urllib.request.urlopen(img) as response:
75 content = response.read()
76 try:
77 im = Image.open(io.BytesIO(content))
78 except OSError as e: # pragma: no cover
79 raise RuntimeError(
80 "Unable to read image '{}'.".format(img)) from e
81 else:
82 # local file
83 if folder_image is not None:
84 im = Image.open(os.path.join(folder_image, img))
85 else:
86 im = Image.open(img)
87 else:
88 im = img
89 if hasattr(im, 'size'):
90 ax[ind].imshow(im)
91 if texts is None:
92 t = "img %d" % i
93 else:
94 t = texts[i]
95 ax[ind].text(0, 0, t)
96 ax[ind].axis('off')
98 for i in range(len(imgs), width * height):
99 y, x = i // width, i % width
100 if height == 1:
101 ind = x
102 else:
103 ind = y, x
104 ax[ind].axis('off')
106 if return_figure:
107 return fig, ax
108 return ax