Print what you pass to imshow(): print(type(img), getattr(img, "shape", None)). If it is
None, the image failed to load (check the path; cv2.imread does not raise errors) or you assigned the
result of an in-place method such as thumbnail(). If it is a string, open the file first.
Cause 1: cv2.imread returned None
cv2.imread() never raises an exception for a missing or unreadable file; it returns None, and the error
surfaces later in imshow(). We ran this with matplotlib 3.11:
import matplotlib
matplotlib.use("Agg")
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("photos/IMG_0001.jpg") # wrong path: cv2.imread returns None, no error
plt.imshow(img)
TypeError: Image data of dtype object cannot be converted to float
Older matplotlib versions word it as TypeError: Image data can not convert to float; it is the same problem.
Cause 2: passing a path instead of an image
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
plt.imshow("photo.jpg") # a path, not an image
TypeError: Image data of dtype <U9 cannot be converted to float
Here the dtype in the message is <U9, a 9-character string: the file name.
Cause 3: assigning the result of an in-place method
thumbnail(), paste() and ImageDraw methods modify the image and return None:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from PIL import Image
img = Image.open("photo.jpg")
img = img.thumbnail((400, 400)) # thumbnail() returns None
plt.imshow(img)
TypeError: Image data of dtype object cannot be converted to float
Fixes
Fail early, with a clear message, when an image did not load:
import matplotlib
matplotlib.use("Agg")
from pathlib import Path
import cv2
import matplotlib.pyplot as plt
path = Path("photos/img_1.jpg")
img = cv2.imread(str(path))
if img is None:
raise FileNotFoundError(f"could not read {path.resolve()}")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # also convert BGR -> RGB for correct colours
plt.savefig("ok.png")
print("shown", img.shape)
shown (1067, 1600, 3)
And keep in-place calls on their own line:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from PIL import Image
img = Image.open("photo.jpg")
img.thumbnail((400, 400)) # in place, no assignment
plt.imshow(img)
plt.savefig("ok.png")
print("shown", img.size)
shown (400, 267)
Cause 4: an array of arrays with different shapes
Stacking images of different sizes into one NumPy array gives an object array, which imshow() also
rejects. Show the images one at a time, or resize them to the same shape first:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
frames = [np.array(Image.open("photo.jpg").resize((40, 27))), np.array(Image.open("portrait.jpg").resize((27, 40)))]
batch = np.empty(len(frames), dtype=object) # what you get from frames of different sizes
batch[:] = frames
print(batch.dtype, batch.shape)
plt.imshow(batch)
object (2,)
Traceback (most recent call last):
...
TypeError: Image data of dtype object cannot be converted to float
For everything about displaying images (Jupyter, Tkinter, greyscale colour maps), see displaying a PIL image.
Related
The outputs and images on this page are the real results of running every example with Pillow 12.3.0 on Python 3.13 (Linux) on 2026-10-15. Every example is also re-run automatically on macOS (Darwin 25.6.0, Pillow 12.3.0), Linux (Linux 6.17.0-1022-azure, Pillow 12.3.0), Windows (Windows 2025Server, Pillow 12.3.0); the line under each example shows the result per operating system. The DejaVu Sans font files sit next to each script so font examples behave the same everywhere. Sample photos: NASA/Sam Lott, public domain. Spotted something wrong? Tell us.