Reputation: 287
I have dataset which consists of 50 images of size 8 x 8 flattened into arrays of size 64. Using the function imshow
of matplotlib.pyplot
(plt) to visualize the first 16 images (in a 4x4 grid) of the dataset.
I tried the following code:
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(50,64) #this will simulate my data
fig=plt.figure(figsize=(8, 8))
for i in range(16):
img = np.reshape(data[i:(i+1)],(8,8))
fig.add_subplot(4, 4, i)
plt.imshow(img)
plt.show()
this is the traceback:
<ipython-input-207-7af8d2013358> in plot_first_digits()
13
14 img = np.reshape(X[i:(i+1)],(8,8))
---> 15 fig.add_subplot(4, 4, i)
16 plt.imshow(img)
17
~/anaconda3/lib/python3.8/site-packages/matplotlib/figure.py in add_subplot(self, *args, **kwargs)
1417 self._axstack.remove(ax)
1418
-> 1419 a = subplot_class_factory(projection_class)(self, *args, **kwargs)
1420
1421 return self._add_axes_internal(key, a)
~/anaconda3/lib/python3.8/site-packages/matplotlib/axes/_subplots.py in __init__(self, fig, *args, **kwargs)
63 else:
64 if num < 1 or num > rows*cols:
---> 65 raise ValueError(
66 f"num must be 1 <= num <= {rows*cols}, not {num}")
67 self._subplotspec = GridSpec(
ValueError: num must be 1 <= num <= 16, not 0
<Figure size 576x576 with 0 Axes>
Upvotes: 0
Views: 1663
Reputation: 2630
From your script, we can see that the error is due to the call to plt.add_subplot()
with i = 0
at the first iteration (this function only accepts positive integer arguments).
fig.add_subplots
import matplotlib.pyplot as plt
import numpy as np
# simulate data
data = np.random.rand(50, 64)
# create figure
fig = plt.figure(figsize=(8, 8))
# loop over images
for i in range(16):
print(i)
img = np.reshape(data[i : (i + 1)], (8, 8))
fig.add_subplot(4, 4, i + 1)
plt.imshow(img)
# save image
plt.savefig("subplot_image")
The output image looks like:
plt.subplots
(more pythonic)The following solution produces the same image by directly iterating the subplots generated the plt.subplots()
, and the elements of the data
matrix.
# create figure
fig, axes = plt.subplots(4, 4, figsize=(8, 8))
# loop over images
for ax, img in zip(axes.ravel(), data):
ax.imshow(img.reshape(8, 8))
# save image
plt.savefig("subplot_image")
Upvotes: 1
Reputation: 223
Try using Image Grid
as follows:
from mpl_toolkits.axes_grid1 import ImageGrid
def show_images(images):
fig = plt.figure(figsize=(12., 12.))
grid = ImageGrid(fig, 111, nrows_ncols=(1, len(images)),axes_pad=0.1)
for ax, im in zip(grid, images):
ax.axis('off')
ax.imshow(im, cmap="gray")
sample_negative = ~sample1
show_images([sample1, sample_negative])
Pay close attention to the constructor. You are passing your figure, number of rows and columns how you wish to align your images. In the example above, I've aligned all images in a single row. Here is how the output looks like:
Upvotes: 1