Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I attach a pyplot function to a figure instance?

Previously, I had a problem with the interference between multiple Matplotlib figures. Finally i got tracked that to an issue that some pyplot functions do not attach to their figure instance but can be rendered in some other figure instances which are created in parallel.

Here is some example code:

from django.http import HttpResponse
from numpy import arange, meshgrid
from matplotlib.mlab import bivariate_normal

def show_chart(request):
    delta = 0.025
    x = arange(-3.0, 3.0, delta)
    y = arange(-2.0, 2.0, delta)
    X, Y = meshgrid(x, y)
    Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10.0 * (Z2 - Z1)

    from matplotlib.pyplot import figure, contour
    fig1 = figure(figsize=(4, 4), facecolor='white')
    contour(X, Y, Z)

    response = HttpResponse(content_type='image/png')
    fig1.savefig(response, format='png')
    fig1.clear()
    return response

The contour pyplot function in the example above can get rendered in fig1, but occasionally also in some other figure that is generated in parallel. That is very annoying. Is there any way to attach the contour pyplot function to fig1?

like image 870
Meilo Avatar asked Jan 10 '13 09:01

Meilo


People also ask

Can a function return a figure Python?

How to have a function return a figure in Python (using Matplotlib)? Set the figure size and adjust the padding between and around the subplots. Create x and y data points using numpy. Make a function plot(x, y) that creates a new figure or activate an existing figure using figure() method.

Which function Pyplot module is used to create a figure?

The plot() function of the pyplot module is used to create a figure.

What is Pyplot CLF ()?

The clf() function in pyplot module of matplotlib library is used to clear the current figure.


2 Answers

As a bit of explanation of what is going on here, matplotlib has two semi-independent interfaces; the state machine and the OO interface.

The state machine code is designed for working in an interactive shell (and mimics matlab's interface). It does this by wrapping the OO interface in a set of commands that keep track of what the current figure and axes are. When you use the command from matplotlib.pyplot (I suspect you have an from matploblib.pyplot import * in your code) in is more or less equivalent to doing gcf().gca().contour(...). When you create a new figure, it is automatically made current (which is what you want if you are using this in an iteractive shell) so the behavior you see is the 'correct' behavior. The state machine interface also has code in it to make sure figures get re-drawn when they need to, manage the gui event loops, etc (all the things you need to do to make the interactive interface work smoothly). As hayden mentioned in comments, running ipython --pylab will automatically run from matplotlib.pyplot import *, which gives you a very nice interactive shell.

The OO interface is designed for programmatic dealing with matplotlib. What it adds in verbosity (you now have to do most of the work of the state machine), it makes up for in clarity. In the OO model, most (maybe all) of the plotting functions are associated with Axes objects (doc) (as there can be more than one axes associated with a figure (ex subplots using gridspec).

An alternate way to solve your problem is

ax = fig1.gca()

which will grab the current axes from fig1, creating one if necessary. This may be helpful if you keep track of your figure objects, but not your axes objects and want to add another graph to the figure.

like image 199
tacaswell Avatar answered Oct 20 '22 06:10

tacaswell


You can create a subplot and than call the contour method of the subplot:

fig1 = figure(figsize=(4, 4), facecolor='white')
ax = fig1.add_subplot(111)
ax.contour(X, Y, Z)

plt.subplots makes it convenient to create a figure and subplots with a single call:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
like image 26
bmu Avatar answered Oct 20 '22 05:10

bmu