How to convert a matplotlib figure to a numpy array or a PIL image

Description

For manipulating a figure build with matplotlib, it is sometimes requested to convert it in a format understandable by other python libraries. This can be useful for using scipy image filters or manually adding annotations for example.

Prerequisites

Language
  • PYTHON >=2.5
Libraries
  • matplotlib >=0.99.0
  • numpy >=1.2.1
  • PIL (Python Imaging Library) >=0.1.6
Probably supported by earlier versions, but not tested. Building a matplotlib figure To begin with, we will need a figure to convert. The following code produces a simple cardinal sine plot.
import matplotlib.pyplot
import numpy
 
# Generate a figure with matplotlib</font>
figure = matplotlib.pyplot.figure(  )
plot   = figure.add_subplot ( 111 )
 
# draw a cardinal sine plot
x = numpy.arange ( 0, 100, 0.1 )
y = numpy.sin ( x ) / x
plot.plot ( x, y )
Now, if you run the command
matplotlib.pyplot.show()
You will obtain the widget :
1D Plot of a Cardinal Sine, with frame decorations

REM If you obtain an message like :
.../python2.5/lib/python2.5/site-packages/matplotlib/backends/__init__.py:41: UserWarning: 
Your currently selected backend, 'agg' does not support show().
Please select a GUI backend in your matplotlibrc file
It means that your matplotlib installation is not configured to use a interactive frame. Instead of using the show command, you can dump the figure to an image file and open it externally :
matplotlib.pyplot.savefig ( "./my_img.png" )
Conversion to a numpy array of RGBA values Now we have a figure, we can transform it in a numpy array of RGBA values with the function :
import numpy
 
def fig2data ( fig ):
    """
    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGBA values
    """
    # draw the renderer
    fig.canvas.draw ( )
 
    # Get the RGBA buffer from the figure
    w,h = fig.canvas.get_width_height()
    buf = numpy.fromstring ( fig.canvas.tostring_argb(), dtype=numpy.uint8 )
    buf.shape = ( w, h,4 )
 
    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
    buf = numpy.roll ( buf, 3, axis = 2 )
    return buf
Conversion to a PIL image At this point, we just have to convert the numpy array to a PIL Image to end the conversion. This is managed by the function
import Image
 
def fig2img ( fig ):
    """
    @brief Convert a Matplotlib figure to a PIL Image in RGBA format and return it
    @param fig a matplotlib figure
    @return a Python Imaging Library ( PIL ) image
    """
    # put the figure pixmap into a numpy array
    buf = fig2data ( fig )
    w, h, d = buf.shape
    return Image.fromstring( "RGBA", ( w ,h ), buf.tostring( ) )
This will return a PIL Image that you can open for example with
im = fig2img ( figure )
im.show()

 

More news

Highlights

AERIS/ICARE was migrated his good old FTP server to SFTP

For security reason, we are abandoning the FTP protocol in favor of SFTP on our distribution server. Depending of the way you are using this service, you can have to change the commands you are used to. Note that not all applications support the SFTP protocol, and some additional tools may need to be installed […]

01.03.2024

Tutorials

Reading a NetCDF file with Python, Matlab and R

Language/Format: MATLAB
Description: This page gives pieces of code to read data in a NetCDF file
Author(s): Aminata NDIAYE (ICARE)

15.12.2015

Tutorials

Writing an HDF file with C, FORTRAN, Python, MATLAB and R

Language/Format: Fortran,MATLAB,Python
Description: This page gives pieces of code to write data in an HDF4 file
Author(s): Nicolas PASCAL, Nicolas THOMAS, Aminata NDIAYE (CARE )

15.10.2014

Search