358

I have created an array thusly:

import numpy as np
data = np.zeros( (512,512,3), dtype=np.uint8)
data[256,256] = [255,0,0]

What I want this to do is display a single red dot in the center of a 512x512 image. (At least to begin with... I think I can figure out the rest from there)

kmario23
  • 57,311
  • 13
  • 161
  • 150
jlswint
  • 3,683
  • 2
  • 16
  • 4
  • 1
    See also http://stackoverflow.com/questions/902761/saving-a-numpy-array-as-an-image although that one imposed the constraint that PIL could not be used. – Peter Hansen Apr 17 '10 at 18:01

11 Answers11

420

Use plt.imshow to create the figure, and plt.show to display it:

from matplotlib import pyplot as plt
plt.imshow(data, interpolation='nearest')
plt.show()

For Jupyter notebooks, add this line before importing matplotlib:

%matplotlib inline 

For interactive plots in Jupyter [demo], install ipyml pip install ipympl, then use:

%matplotlib widget 
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Steve Tjoa
  • 59,122
  • 18
  • 90
  • 101
  • 7
    This is more accurate than PIL. PIL rescales/normalizes the array values, whereas pyplot uses the actual RGB values as they are. – GaryO Jan 27 '13 at 14:08
  • 42
    Maybe good to know: If you want to display grayscale images, it is advisable to call `plt.gray()` once in your code to switch all following graphs to grayscale. Not what the OP wants but good to know nevertheless. – Cerno Feb 28 '17 at 12:21
  • 3
    How to save it? – user334639 Jul 22 '18 at 13:07
  • 4
    @Cerno Also, grayscale images should have shape(h, w) rather than (h, w, 1). You can use `squeeze()` to eliminate the third dimension: `plt.imshow(data.squeeze())` – Josiah Yoder Aug 28 '19 at 17:15
348

You could use PIL to create (and display) an image:

from PIL import Image
import numpy as np

w, h = 512, 512
data = np.zeros((h, w, 3), dtype=np.uint8)
data[0:256, 0:256] = [255, 0, 0] # red patch in upper left
img = Image.fromarray(data, 'RGB')
img.save('my.png')
img.show()
Dan H
  • 14,044
  • 6
  • 39
  • 32
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 7
    It seems that there is a bug. You create array with size `(w,h,3)`, but it should be `(h,w,3)`, because indexing in PIL differs from indexing in numpy. There is related question: http://stackoverflow.com/questions/33725237/image-fromarray-changes-size – fdermishin Dec 06 '15 at 18:57
  • 1
    @user502144: Thanks for pointing out my error. I should have created an array of shape `(h,w,3)`. (It's now fixed, above.) The length of the first axis can be thought of as the number of rows in the array, and the length of the second axis, the number of columns. So `(h, w)` corresponds to an array of "height" `h` and "width" `w`. `Image.fromarray` converts this array into an image of height `h` and width `w`. – unutbu Dec 06 '15 at 20:47
  • 6
    `img.show()` don't work in ipython notebook.`img_pil = Image.fromarray(img, 'RGB') display(img_pil.resize((256,256), PIL.Image.LANCZOS))` – mrgloom Jun 11 '19 at 10:15
  • 1
    @unutbu this method seems to distort images ... https://stackoverflow.com/questions/62293077/why-is-pils-image-fromarray-distorting-my-image-color – Ludovico Verniani Jun 09 '20 at 22:58
  • 1
    Having `Image.fromarray(...)` as the last expression of a cell sufficed to display the image for me in Google Colab. No need to write to a file or call `.show()`. – raphinesse Oct 27 '20 at 12:33
  • How can i use matrix data in html for showing image. – Amarnath Reddy Surapureddy Nov 03 '22 at 10:59
51

Note: both these APIs have been first deprecated, then removed.

Shortest path is to use scipy, like this:

# Note: deprecated in v0.19.0 and removed in v1.3.0
from scipy.misc import toimage
toimage(data).show()

This requires PIL or Pillow to be installed as well.

A similar approach also requiring PIL or Pillow but which may invoke a different viewer is:

# Note: deprecated in v1.0.0 and removed in v1.8.0
from scipy.misc import imshow
imshow(data)
Peter Hansen
  • 21,046
  • 5
  • 50
  • 72
  • So this method is incompatible with python 3.5...? – Chris Feb 05 '16 at 23:48
  • @bordeo, why would it be incompatible with 3.5? It just an import and a couple of function calls. – Peter Hansen Feb 06 '16 at 15:32
  • PIL is incompatible with 3.5 (won't install) – Chris Feb 06 '16 at 17:19
  • 1
    Ftr: you can shorten this further by directly using [`scipy.misc.imshow(data)`](http://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.imshow.html#scipy.misc.imshow). – dtk Aug 21 '16 at 13:56
  • 8
    `toimage` was deprecated in scipy-1.0.0 and removed in 1.2.0, in favor of Pillow’s `Image.fromarray`. – Sid Aug 13 '19 at 15:48
  • 1
    `scipy.misc.imshow()` is deprecated. Use `matplotlib.pyplot.imshow(data)` instead. Also, in IPython, you need to run `matplotlib.pyplot.show()` to show the image display window. – kbridge4096 Apr 09 '22 at 21:26
18

How to show images stored in numpy array with example (works in Jupyter notebook)

I know there are simpler answers but this one will give you understanding of how images are actually drawn from a numpy array.

Load example

from sklearn.datasets import load_digits
digits = load_digits()
digits.images.shape   #this will give you (1797, 8, 8). 1797 images, each 8 x 8 in size

Display array of one image

digits.images[0]
array([[ 0.,  0.,  5., 13.,  9.,  1.,  0.,  0.],
       [ 0.,  0., 13., 15., 10., 15.,  5.,  0.],
       [ 0.,  3., 15.,  2.,  0., 11.,  8.,  0.],
       [ 0.,  4., 12.,  0.,  0.,  8.,  8.,  0.],
       [ 0.,  5.,  8.,  0.,  0.,  9.,  8.,  0.],
       [ 0.,  4., 11.,  0.,  1., 12.,  7.,  0.],
       [ 0.,  2., 14.,  5., 10., 12.,  0.,  0.],
       [ 0.,  0.,  6., 13., 10.,  0.,  0.,  0.]])

Create empty 10 x 10 subplots for visualizing 100 images

import matplotlib.pyplot as plt
fig, axes = plt.subplots(10,10, figsize=(8,8))

Plotting 100 images

for i,ax in enumerate(axes.flat):
    ax.imshow(digits.images[i])

Result:

enter image description here

What does axes.flat do? It creates a numpy enumerator so you can iterate over axis in order to draw objects on them. Example:

import numpy as np
x = np.arange(6).reshape(2,3)
x.flat
for item in (x.flat):
    print (item, end=' ')
Yaakov Saxon
  • 308
  • 2
  • 7
Hrvoje
  • 13,566
  • 7
  • 90
  • 104
8
import numpy as np
from keras.preprocessing.image import array_to_img
img = np.zeros([525,525,3], np.uint8)
b=array_to_img(img)
b
Sivasai
  • 89
  • 1
  • 2
7

Using pillow's fromarray, for example:

from PIL import Image
from numpy import *

im = array(Image.open('image.jpg'))
Image.fromarray(im).show()
user3322286
  • 99
  • 1
  • 3
5

Using pygame, you can open a window, get the surface as an array of pixels, and manipulate as you want from there. You'll need to copy your numpy array into the surface array, however, which will be much slower than doing actual graphics operations on the pygame surfaces themselves.

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
2

For example your image is in an array names 'image'

All you do is

plt.imshow(image)
plt.show

This will display an array in the form of an image Also, dont forget to import PLT

1

Supplement for doing so with matplotlib. I found it handy doing computer vision tasks. Let's say you got data with dtype = int32

from matplotlib import pyplot as plot
import numpy as np

fig = plot.figure()
ax = fig.add_subplot(1, 1, 1)
# make sure your data is in H W C, otherwise you can change it by
# data = data.transpose((_, _, _))
data = np.zeros((512,512,3), dtype=np.int32)
data[256,256] = [255,0,0]
ax.imshow(data.astype(np.uint8))
user140536
  • 144
  • 1
  • 7
0

The Python Imaging Library can display images using Numpy arrays. Take a look at this page for sample code:

EDIT: As the note on the bottom of that page says, you should check the latest release notes which make this much simpler:

http://effbot.org/zone/pil-changes-116.htm

ars
  • 120,335
  • 23
  • 147
  • 134
0

this could be a possible code solution:

from skimage import io
import numpy as np
data=np.random.randn(5,2)
io.imshow(data)
Zig Razor
  • 3,381
  • 2
  • 15
  • 35
Aman Bagrecha
  • 406
  • 4
  • 9