I’ve always struggled with the
plt.imshow() method of Python’s matplotlib library. To help you and I master it, I’ve written the most in-depth resource about it on the web.
As a bonus resource, you can play my walkthrough video that takes you through all the code in this article:
To show an image in matplotlib, first read it in using
plt.imread(), then display it with
import matplotlib.pyplot as plt cat_img = plt.imread('Figures/cat.jpeg') plt.imshow(cat_img)
To turn the (annoying) axis ticks off, call
cat_img = plt.imread('Figures/cat.jpeg') plt.axis('off') plt.imshow(cat_img)
Much better! But there is a lot more you can do than just show images. Let’s look at how this works in more detail.
Matplotlib Imshow Example
When you display an in image in matplotlib, there are 2 steps you need to take: first you read the image and then you show it.
You read in the image using
plt.imread() and pass it a string. I have the images stored in a directory called Figures, so I first write
Figures/ followed by the name of the image with its file extension –
cat.jpeg. If your images are stored in your current working directory, you can omit
I store the output of
plt.imread() in a variable with a descriptive name because you need to pass this to
plt.imshow(). So, the first line is
cat_img = plt.imread('Figures/cat.jpeg').
Images are made up of pixels and each pixel is a dot of color. The cat image is 1200×800 pixels. When an image is loaded into a computer, it is saved as an array of numbers. Each pixel in a color image is made up of a Red, Green and Blue (RGB) part. It can take any value between 0 and 255 with 0 being the darkest and 255 being the brightest. In a grayscale image, each pixel is represented by just a single number between 0 and 1. If a pixel is 0, it is completely black, if it is 1 it is completely white. Everything in between is a shade of gray.
So, if the cat image was black and white, it would be a 2D numpy array with shape
(800, 1200). As it is a color image, it is in fact a 3D numpy array (to represent the three different color channels) with shape
(800, 1200, 3).
Note that Numpy writes image sizes is the opposite way to matplotlib and the ‘real world’. Numpy is from the world of mathematics and matrices where you always write the number of rows (height) first followed by the columns (width). If you need a quick NumPy refresher, check out my in-depth NumPy tutorial on this blog.
Matplotlib bases its image functions on the ‘real world’ and so displays the width first followed by the height.
Let’s look at the type and size of
cat_img = plt.imread('Figures/cat.jpeg') print(type(cat_img)) # <class 'numpy.ndarray'> print(cat_img.shape) # (800, 1200, 3) <class 'numpy.ndarray'> (800, 1200, 3)
Once you’ve read your image into a numpy array, it’s time to display it using
plt.imshow(). This is similar to
plt.show() which you call at the end of any matplotlib plot. However, unlike
plt.show(), you must pass the image you want to display as an argument. This is helpful if you have read in multiple images but only want to display a certain number of them.
I’m not sure why but, by default, all images are shown with axis ticks and labels. This can be quite annoying, so call
plt.axis('off') to remove them.
However, ticks and labels can be helpful if you only want to select part of the image. By using them as guides, I’ll slice
cat_img to just get the head of our cute kitten.
# Slicing found by using axis ticks and lables on image above cat_head = cat_img[150:450, 275:675, :] plt.imshow(cat_head)
The above image is a jpeg but you can also display other types of image files such as pngs.
# A png image snow_img = plt.imread('Figures/snowboarder.png') plt.axis('off') plt.imshow(snow_img)
You can display gifs but it is slightly more complicated to do so and so is outside the scope of this article. If you read in and show a gif using the above steps, matplotlib will just show one of its frames.
janice = plt.imread('Figures/janice.gif') plt.axis('off') plt.imshow(janice)
Matplotlib Imshow Grayscale
You can turn any color image into a grayscale image in matplotlib. Since grayscale images are 2D numpy arrays, use slicing to turn your 3D array into a 2D one.
cat_img = plt.imread('Figures/cat.jpeg') # Turn 3D array into 2D by selecting just one of the three dimensions grayscale_cat = cat_img[:, :, 0]
If you write
cat_img[:, :, 1] or
cat_img[:, :, 2] you will get different arrays but the final image will still look the same. This is because grayscale images just care about the relative difference of intensity between each pixel and this is the same over each RGB channel.
Let’s plot it and see what happens.
Don’t worry, you haven’t done anything wrong! You created a grayscale image but matplotlib applied a colormap to it automatically. This happens even if you pick the second or third dimension in your
To make it grayscale, set the
cmap keyword argument to
plt.axis('off') plt.imshow(grayscale_cat, cmap='gray')
Perfect! Now you can easily turn any color image into a grayscale one in matplotlib. But there are many more colors you can choose from. Let’s look at all the colormaps in detail.
Matplotlib Imshow Colormap
There are many different colormaps you can apply to your images. Simply pass the name to the
cmap keyword argument in
plt.imshow() and you’re good to go. I recommend you play around with them since most of the names won’t mean anything to you on first reading.
The default colormap is viridis. Let’s explicitly apply it to our cat image.
# Turn cat_img into a 2D numpy array colored_cat = cat_img[:, :, 0] plt.axis('off') plt.imshow(colored_cat, cmap='viridis')
I could write a whole article on colormaps – in fact, the creator of Seaborn did. It’s a fascinating topic. Choosing the right one can make your plot incredible and choosing a bad one can ruin it.
For beginners, matplotlib recommends the
Perceptually Uniform Sequential colormaps as they work well and are easy on the eyes. Here’s a list of them all.
percp_uniform_seq_cmaps = ['viridis', 'plasma', 'inferno', 'magma', 'cividis']
You’ve already seen
viridis, so let’s display the others on a 2×2 grid (if you don’t know how to make subplots in matplotlib check out my article).
fig, axes = plt.subplots(nrows=2, ncols=2) cmaps = ['plasma', 'inferno', 'magma', 'cividis'] for ax, cmap in zip(axes.flat, cmaps): ax.imshow(colored_cat, cmap=cmap) ax.set(title=cmap) ax.axis('off') plt.show()
The colormaps are quite similar and easy to look at. They don’t distort the image and the highs and lows can still be seen.
Here are some other colormaps I’ve randomly chosen. Note how odd some of them are, especially
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=plt.figaspect(1/2)) cmaps = ['jet', 'binary', 'RdYlGn', 'twilight', 'Pastel1', 'flag'] for ax, cmap in zip(axes.flat, cmaps): ax.imshow(colored_cat, cmap=cmap, label=cmap) ax.set(title=cmap) ax.axis('off') plt.show()
Matplotlib Imshow Colorbar
If your image has a colormap applied to it, you may want to tell the reader what each color means by providing a colorbar. Use
plt.colorbar() to add one.
plt.imshow(colored_cat, cmap='hot') plt.axis('off') plt.colorbar()
Remember that every value in an array representing a colored image is a number between 0 and 255 and so the colorbar reflects this.
Note that I called
plt.imshow() on the first line. Unlike
plt.show(), you can modify images after calling
plt.imshow() and the changes will be applied to the output.
Matplotlib Imshow Size
As with every
Figure in matplotlib, you can manually set the
Figure‘s size. Simply call
plt.figure() at the top and set the
figsize argument. You can either set it to a specific size in inches or set the aspect ratio:
plt.figure(figsize=(8, 6))– 8 inches wide, 6 inches tall
plt.figure(figsize=plt.figaspect(2))– aspect ratio of 2, i.e. twice as tall as it is wide.
Note: the default figsize can be found by calling
plt.rcParams['figure.figsize'] and is
(6.4, 4.8) inches.
Let’s see what happens when we modify the
Figure size of our cat image.
# 1 inch wide x 1 inch tall...? plt.figure(figsize=(1, 1)) cat_img = plt.imread('Figures/cat.jpeg') plt.axis('off') plt.imshow(cat_img)
This is certainly smaller than the original. But it doesn’t look like it is 1×1 inches – it’s clearly wider that it is tall. But it looks like one of the sides is correct which is better than nothing.
Let’s try to make it 1 inch wide and 3 inches tall.
# 1 inch wide x 3 inches tall...? plt.figure(figsize=(1, 3)) cat_img = plt.imread('Figures/cat.jpeg') plt.axis('off') plt.imshow(cat_img)
Now the image hasn’t changed at all. What’s going on?
When you resize images in most programs like Microsoft Word or Google Sheets, they maintain their original height/width ratios. This is called preserving the aspect ratio of the image and is usually a very good thing. It ensures that pixels in the image are not distorted when you resize them. This is also the default behavior in matplotlib.
If you actually want to distort the image and to fill up the entire space available in the
Figure, change the
aspect keyword argument in
There are only two possible values for
- ‘equal’ – (default) preserves the aspect ratio, i.e. the side lengths of the pixels are equal (square)
- ‘auto’ – does not preserve the aspect ratio
Let’s look at the same examples as above but set
# 1 inch wide x 1 inch tall (definitely) plt.figure(figsize=(1, 1)) cat_img = plt.imread('Figures/cat.jpeg') plt.axis('off') plt.imshow(cat_img, aspect='auto')
Great! Now, the image is clearly 1×1 inches but it has come at the expense of slight image distortion.
Let’s distort it even further.
# 1 inch wide x 3 inches tall (definitely) plt.figure(figsize=(1, 3)) cat_img = plt.imread('Figures/cat.jpeg') plt.axis('off') plt.imshow(cat_img, aspect='auto')
Perfect! Clearly the image is distorted but now you know how to do it.
Note the default aspect value can be changed for all images by setting
plt.rcParams['image.aspect'] = 'auto'.
Now you know the basics of displaying images with matplotlib.
You understand why you need to first read images in from a file and store them as a numpy array (NumPy tutorial here) before displaying them with
plt.imshow(). You know how to read in different types of image files (hint – if it’s a still image, it’s the same process regardless of the file type!).
If you want to set a specific colormap, you use the
cmap keyword argument and you can also turn your color image to a grayscale one. Finally, you can add a colorbar and change the size of your image to be anything you want.
There are some more advanced topics to learn about such as interpolation, adding legends and using log scales for your axes but I’ll leave them for another article.
Where To Go From Here?
Do you wish you could be a programmer full-time but don’t know how to start?
Check out the pure value-packed webinar where Chris – creator of Finxter.com – teaches you to become a Python freelancer in 60 days or your money back!
It doesn’t matter if you’re a Python novice or Python pro. If you are not making six figures/year with Python right now, you will learn something from this webinar.
These are proven, no-BS methods that get you results fast.
This webinar won’t be online forever. Click the link below before the seats fill up and learn how to become a Python freelancer, guaranteed.
WordPress conversion from imshow.ipynb by nb2wp v0.3.1