331

I'm trying to display a grayscale image using matplotlib.pyplot.imshow(). My problem is that the grayscale image is displayed as a colormap. I need it to be grayscale because I want to draw on top of the image with color.

I read in the image and convert to grayscale using PIL's Image.open().convert("L")

image = Image.open(file).convert("L")

Then I convert the image to a matrix so that I can easily do some image processing using

matrix = scipy.misc.fromimage(image, 0)

However, when I do

figure()  
matplotlib.pyplot.imshow(matrix)  
show()

it displays the image using a colormap (i.e. it's not grayscale).

What am I doing wrong here?

9 Answers 9

522

The following code will load an image from a file image.png and will display it as grayscale.

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

fname = 'image.png'
image = Image.open(fname).convert("L")
arr = np.asarray(image)
plt.imshow(arr, cmap='gray', vmin=0, vmax=255)
plt.show()

If you want to display the inverse grayscale, switch the cmap to cmap='gray_r'.

Sign up to request clarification or add additional context in comments.

3 Comments

@jay: Per this doc string, "Note that any colormap listed here can be reversed by appending _r."
Warning matplotlib adjust pixel scale intensity if you do not want use: plt.imshow(im_gray,cmap='gray', vmin = 0, vmax = 255)
You don't need to convert the image to single channel convert("L") if the only thing you need is to show the image as gray cmap="gray" is what you need in imshow. I have similar example in OpenCV for single channel image, but you can open any RGB image and show it with cmap='gray'.
43

Try to use a grayscale colormap?

E.g. something like

imshow(..., cmap=pyplot.cm.binary)

For a list of colormaps, see http://scipy-cookbook.readthedocs.org/items/Matplotlib_Show_colormaps.html

Comments

31

import matplotlib.pyplot as plt

You can also run once in your code

plt.gray()

This will show the images in grayscale as default

im = array(Image.open('I_am_batman.jpg').convert('L'))
plt.imshow(im)
plt.show()

3 Comments

Which library are you using for gray() or grey() ?
@SherylHohman, it is gray... gray is standard American spelling and grey is British spelling for the same color.
@SherylHohman thats matplotlib, install with pip install matplotlib
18

I would use the get_cmap method. Ex.:

import matplotlib.pyplot as plt

plt.imshow(matrix, cmap=plt.get_cmap('gray'))

Comments

17

@unutbu's answer is quite close to the right answer.

By default, plt.imshow() will try to scale your (MxN) array data to 0.0~1.0. And then map to 0~255. For most natural taken images, this is fine, you won't see a different. But if you have narrow range of pixel value image, say the min pixel is 156 and the max pixel is 234. The gray image will looks totally wrong. The right way to show an image in gray is

from matplotlib.colors import NoNorm
...
plt.imshow(img,cmap='gray',norm=NoNorm())
...

Let's see an example:

this is the origianl image: original

this is using defaul norm setting,which is None: wrong pic

this is using NoNorm setting,which is NoNorm(): right pic

2 Comments

In Colab I get error when using NoNorm, however norm=None works
@AxelBregnsbo norm=NoNorm() works for me in colab
10

try this:

import pylab
from scipy import misc

pylab.imshow(misc.lena(),cmap=pylab.gray())
pylab.show()

1 Comment

there is no pylab.grey(), maybe it has been removed?
10

Use no interpolation and set to gray.

import matplotlib.pyplot as plt
plt.imshow(img[:,:,1], cmap='gray',interpolation='none')

Comments

3
plt.imshow(img[:,:,0], cmap='gray')

plt.imshow(img[:,:,1], cmap='gray')

plt.imshow(img[:,:,2], cmap='gray')

should work. But, the issue with this approach is that it is not true gray. It only changes one of RGB channel to gray.

look below.

from sklearn.datasets import load_sample_image
flower = load_sample_image("flower.jpg")

plt.subplot(1,4,1)
plt.imshow(flower)
plt.axis("off")
plt.title("Original")

# R level to gray
plt.subplot(1,4,2)
plt.imshow(flower[:,:,0], cmap='gray')
plt.axis("off")
plt.title("R to gray")


# G leval to gray
plt.subplot(1,4,3)
plt.imshow(flower[:,:,1], cmap='gray')
plt.axis("off")
plt.title("R to gray")

# B leval to gray
plt.subplot(1,4,4)
plt.imshow(flower[:,:,2], cmap='gray')
plt.axis("off")
plt.title("R to gray")

plt.show()

[Result images]

Comments

1

When the image has purple & yellow color.

change way of saving image:
plt.imsave(...., cmap='gray')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.