Skip to content

Commit

Permalink
DOC: image tutorial touch-up
Browse files Browse the repository at this point in the history
- expand some text regarding backend usage and IPython notebook plot
- improve style a bit (PEP 8)
- shorten array printout
- convert image resizing example to use PIL
  • Loading branch information
msarahan committed Nov 19, 2014
1 parent a43a2f9 commit 4daffe4
Showing 1 changed file with 65 additions and 87 deletions.
152 changes: 65 additions & 87 deletions doc/users/image_tutorial.rst
Expand Up @@ -41,13 +41,21 @@ Examples below will use the latter method, for clarity. In these
examples, if you use the %pylab method, you can skip the "mpimg." and
"plt." prefixes.

For those of you following along with the IPython Notebook, you'll want to
pay attention to whether you're using inline plotting or plotting in another
window. This is also called the "backend." For inline plotting, commands in
cells below the cell that outputs a plot will not affect the plot. For example,
changing the color map is not possible from cells below the cell that creates a plot.
However, for other backends, such as qt4, cells below those that create the plot
will change the plot - it is a live object in memory.

.. _importing_data:

Importing image data into Numpy arrays
===============================================

Plotting image data is supported by the `Pillow
<http://python-imaging.github.io/>`_). Natively, matplotlib only
Loading image data is supported by the `Pillow
<http://python-imaging.github.io/>`_ library. Natively, matplotlib only
supports PNG images. The commands shown below fall back on Pillow if the
native read fails.

Expand Down Expand Up @@ -79,39 +87,7 @@ And here we go...
[ 0.42745098, 0.42745098, 0.42745098],
[ 0.42745098, 0.42745098, 0.42745098]],

[[ 0.41176471, 0.41176471, 0.41176471],
[ 0.41176471, 0.41176471, 0.41176471],
[ 0.41176471, 0.41176471, 0.41176471],
...,
[ 0.42745098, 0.42745098, 0.42745098],
[ 0.42745098, 0.42745098, 0.42745098],
[ 0.42745098, 0.42745098, 0.42745098]],

[[ 0.41960785, 0.41960785, 0.41960785],
[ 0.41568628, 0.41568628, 0.41568628],
[ 0.41568628, 0.41568628, 0.41568628],
...,
[ 0.43137255, 0.43137255, 0.43137255],
[ 0.43137255, 0.43137255, 0.43137255],
[ 0.43137255, 0.43137255, 0.43137255]],

...,
[[ 0.43921569, 0.43921569, 0.43921569],
[ 0.43529412, 0.43529412, 0.43529412],
[ 0.43137255, 0.43137255, 0.43137255],
...,
[ 0.45490196, 0.45490196, 0.45490196],
[ 0.4509804 , 0.4509804 , 0.4509804 ],
[ 0.4509804 , 0.4509804 , 0.4509804 ]],

[[ 0.44313726, 0.44313726, 0.44313726],
[ 0.44313726, 0.44313726, 0.44313726],
[ 0.43921569, 0.43921569, 0.43921569],
...,
[ 0.4509804 , 0.4509804 , 0.4509804 ],
[ 0.44705883, 0.44705883, 0.44705883],
[ 0.44705883, 0.44705883, 0.44705883]],

[[ 0.44313726, 0.44313726, 0.44313726],
[ 0.4509804 , 0.4509804 , 0.4509804 ],
[ 0.4509804 , 0.4509804 , 0.4509804 ],
Expand Down Expand Up @@ -163,8 +139,7 @@ plot from the prompt.
img = mpimg.imread('../_static/stinkbug.png')
imgplot = plt.imshow(img)

You can also plot any numpy array - just remember that the datatype
must be float32 (and range from 0.0 to 1.0) or uint8.
You can also plot any numpy array.

.. _Pseudocolor:

Expand All @@ -190,26 +165,24 @@ This is array slicing. You can read more in the `Numpy tutorial

.. sourcecode:: ipython

In [7]: imgplot = plt.imshow(lum_img)
In [7]: plt.imshow(lum_img)

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img = mpimg.imread('../_static/stinkbug.png')
lum_img = img[:,:,0]
lum_img = img[:, :, 0]
plt.imshow(lum_img)

Now, with a luminosity image, the default colormap (aka lookup table,
Now, with a luminosity (2D, no color) image, the default colormap (aka lookup table,
LUT), is applied. The default is called jet. There are plenty of
others to choose from. Let's set some others using the
:meth:`~matplotlib.image.Image.set_cmap` method on our image plot
object:
others to choose from.

.. sourcecode:: ipython

In [8]: imgplot.set_cmap('hot')
In [8]: plt.imshow(lum_img, cmap="hot")

.. plot::

Expand All @@ -221,20 +194,33 @@ object:
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('hot')

Note that you can also change colormaps on existing plot objects using the
:meth:`~matplotlib.image.Image.set_cmap` method:

.. sourcecode:: ipython

In [9]: imgplot.set_cmap('spectral')
In [9]: imgplot = plt.imshow(lum_img)
In [10]: imgplot.set_cmap('spectral')

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img = mpimg.imread('../_static/stinkbug.png')
lum_img = img[:,:,0]
lum_img = img[:, :, 0]
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('spectral')

.. note::

However, remember that in the IPython notebook with the inline backend,
you can't make changes to plots that have already been rendered. If you
create imgplot here in one cell, you cannot call set_cmap() on it in a later
cell and expect the earlier plot to change. Make sure that you enter these
commands together in one cell. plt commands will not change plots from earlier
cells.

There are many other colormap schemes available. See the `list and
images of the colormaps
<../examples/color/colormaps_reference.html>`_.
Expand All @@ -245,19 +231,20 @@ Color scale reference
------------------------

It's helpful to have an idea of what value a color represents. We can
do that by adding color bars. It's as easy as one line:
do that by adding color bars.

.. sourcecode:: ipython

In [10]: plt.colorbar()
In [11]: imgplot = plt.imshow(lum_img)
In [12]: plt.colorbar()

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img = mpimg.imread('../_static/stinkbug.png')
lum_img = img[:,:,0]
lum_img = img[:, :, 0]
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('spectral')
plt.colorbar()
Expand All @@ -280,7 +267,7 @@ image data, we use the :func:`~matplotlib.pyplot.hist` function.

.. sourcecode:: ipython

In[10]: plt.hist(lum_img.flatten(), 256, range=(0.0,1.0), fc='k', ec='k')
In [13]: plt.hist(lum_img.ravel(), bins=256, range=(0.0, 1.0), fc='k', ec='k')

.. plot::

Expand All @@ -289,20 +276,23 @@ image data, we use the :func:`~matplotlib.pyplot.hist` function.
import numpy as np
img = mpimg.imread('../_static/stinkbug.png')
lum_img = img[:,:,0]
plt.hist(lum_img.flatten(), 256, range=(0.0,1.0), fc='black', ec='black')
plt.hist(lum_img.flatten(), 256, range=(0.0, 1.0), fc='k', ec='k')

Most often, the "interesting" part of the image is around the peak,
and you can get extra contrast by clipping the regions above and/or
below the peak. In our histogram, it looks like there's not much
useful information in the high end (not many white things in the
image). Let's adjust the upper limit, so that we effectively "zoom in
on" part of the histogram. We do this by calling the
on" part of the histogram. We do this by passing the clim argument to
imshow. You could also do this by calling the
:meth:`~matplotlib.image.Image.set_clim` method of the image plot
object.
object, but make sure that you do so in the same cell as your plot
command when working with the IPython Notebook - it will not change
plots from earlier cells.

.. sourcecode:: ipython

In[11]: imgplot.set_clim(0.0,0.7)
In [14]: imgplot = plt.imshow(lum_img, clim=(0.0, 0.7))

.. plot::

Expand Down Expand Up @@ -340,25 +330,23 @@ only keeping a select few. Now when we plot it, that data gets blown
up to the size on your screen. The old pixels aren't there anymore,
and the computer has to draw in pixels to fill that space.

We'll use the Pillow library that we used to load the image also to resize
the image.

.. sourcecode:: ipython

In [8]: from PIL import Image
In [9]: img = Image.open('stinkbug.png') # Open image as Pillow image object
In [10]: rsize = img.resize((img.size[0]/10,img.size[1]/10)) # Use Pillow to resize
In [11]: rsizeArr = np.asarray(rsize) # Get array back
In [12]: imgplot = plt.imshow(rsizeArr)
In [15]: import Image
In [16]: img = Image.open('../_static/stinkbug.png')
In [17]: resized = img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
In [18]: imgplot = plt.imshow(img)

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from PIL import Image
import Image
img = Image.open('../_static/stinkbug.png') # opens the file using Pillow - it's not an array yet
rsize = img.resize((img.size[0]/10,img.size[1]/10)) # resize the image
rsizeArr = np.asarray(rsize)
lum_img = rsizeArr[:,:,0]
imgplot = plt.imshow(rsizeArr)
img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
imgplot = plt.imshow(img)

Here we have the default interpolation, bilinear, since we did not
give :func:`~matplotlib.pyplot.imshow` any interpolation argument.
Expand All @@ -367,37 +355,27 @@ Let's try some others:

.. sourcecode:: ipython

In [10]: imgplot.set_interpolation('nearest')
In [19]: imgplot = plt.imshow(resized, interpolation="nearest")

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from PIL import Image
img = Image.open('../_static/stinkbug.png') # opens the file using Pillow - it's not an array yet
rsize = img.resize((img.size[0]/10,img.size[1]/10)) # resize the image
rsizeArr = np.asarray(rsize)
lum_img = rsizeArr[:,:,0]
imgplot = plt.imshow(rsizeArr)
imgplot.set_interpolation('nearest')
import matplotlib.pyplot as plt
import Image
img = Image.open('../_static/stinkbug.png') # opens the file using Pillow - it's not an array yet
img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
imgplot = plt.imshow(img, interpolation="nearest")

.. sourcecode:: ipython

In [10]: imgplot.set_interpolation('bicubic')
In [20]: imgplot = plt.imshow(resized, interpolation="bicubic")

.. plot::

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from PIL import Image
img = Image.open('../_static/stinkbug.png') # opens the file using Pillow - it's not an array yet
rsize = img.resize((img.size[0]/10,img.size[1]/10)) # resize the image
rsizeArr = np.asarray(rsize)
lum_img = rsizeArr[:,:,0]
imgplot = plt.imshow(rsizeArr)
imgplot.set_interpolation('bicubic')
import matplotlib.pyplot as plt
import Image
img = Image.open('../_static/stinkbug.png') # opens the file using Pillow - it's not an array yet
img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
imgplot = plt.imshow(img, interpolation="bicubic")

Bicubic interpolation is often used when blowing up photos - people
tend to prefer blurry over pixelated.

0 comments on commit 4daffe4

Please sign in to comment.