user2552108
user2552108

Reputation: 1150

Show OpenCV image in matplotlib's subplots

I am having troubles in showing OpenCV images in matplotlib's subplot

#Read random images from multiple directories
import random
animals = os.listdir('signs/train')
sample_images = []
for a in animals:
  dirname = 'signs/train/' + a
  files = random.sample(os.listdir(dirname), 5)
  files = [dirname + '/' + im for im in files]
  sample_images.extend(files)

del files, dirname,   animals
print(sample_images)

# Output: ['signs/train/rooster/00000327.jpg', 'signs/train/rooster/00000329.jpg', 'signs/train/rooster/00000168.jpg', ...,  'signs/train/rooster/00000235.jpg', 'signs/train/rooster/00000138.jpg']

#Read using OpenCV and show in matplotlib's subplots

fig, ax = plt.subplots(12, 5,figsize=(15,15), sharex=True)
for idx, si in enumerate(sample_images):
  i = idx % 5 # Get subplot row
  j = idx // 5 # Get subplot column
  image = cv2.imread(si)
  image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 
  image = cv2.resize(image, (64, 64))
  ax[i, j].plot(image)
plt.show()

I have checked that each image is successfully loaded and resized using opencv, but I don't know why I keep getting the following error when I plot them on matplotlib's subplot.


ValueError                                Traceback (most recent call last)

<ipython-input-56-38cc921c1724> in <module>()
     10   #image = Image.open(si)
     11   #print(type(image))
---> 12   ax[i, j].plot(image)
     13 plt.show()

3 frames

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py in _xy_from_xy(self, x, y)
    271         if x.ndim > 2 or y.ndim > 2:
    272             raise ValueError("x and y can be no greater than 2-D, but have "
--> 273                              "shapes {} and {}".format(x.shape, y.shape))
    274 
    275         if x.ndim == 1:

ValueError: x and y can be no greater than 2-D, but have shapes (64,) and (64, 64, 3)

EDIT I forgot to mention that I have tried testing on one image, and it works (even if it is JPG format and still uses RGB channels)

enter image description here

What am I doing wrong?

Upvotes: 2

Views: 19529

Answers (3)

dtlam26
dtlam26

Reputation: 1600

The intention of plot should only be apply to 2d data (eg. Grayscale image), when you add in a 3d image, you should apply it with imshow instead. Therefore, all you need to do is replacing ax[i, j].plot(image) with ax[i, j].imshow(image) and everything will be fine.

Upvotes: 0

wkzhu
wkzhu

Reputation: 1660

You are using ax.plot() incorrectly as it only plots y versus x data. The correct function is plt.imshow() which is matplotlib's built in function to display image data. The example below works and can be extended for your purposes.

import cv2 as cv
from matplotlib import pyplot as plt
image1 = cv.imread('image1.jpg')
image2 = cv.imread('image2.jpg')
plt.subplot(1, 2, 1)
plt.imshow(image1)
plt.subplot(1, 2, 2)
plt.imshow(image2)

Upvotes: 6

Thomas Kavanagh
Thomas Kavanagh

Reputation: 91

Referring to this post, which discusses images in matplotlib subplots, it seems that only PNG file types are supported.

See also the image tutorial linked in the same.

I believe the error is caused because the subplot only accepts two-dimensional images, and since the JPG has three color channels, matplotlib isn't sure which information to map to x & y dimensions.

Upvotes: 0

Related Questions