10

I'm having trouble with matplotlib insisting on displaying a figure wnidow even when I haven't called show().

The function in question is:

def make_plot(df):
    fig, axes = plt.subplots(3, 1, figsize=(10, 6), sharex=True)
    plt.subplots_adjust(hspace=0.2)

    axes[0].plot(df["Date_Time"], df["T1"], df["Date_Time"], df["T2"])
    axes[0].set_ylabel("Temperature (C)")
    axes[0].legend(["T1", "T2"], bbox_to_anchor=(1.12, 1.1))
    axes[1].semilogy(df["Date_Time"], df["IGP"], df["Date_Time"], df["IPP"])
    axes[1].legend(["IGP", "IPP"], bbox_to_anchor=(1.12, 1.1))
    axes[1].set_ylabel("Pressure (mBar)")
    axes[2].plot(df["Date_Time"], df["Voltage"], "k")
    axes[2].set_ylabel("Voltage (V)")
    current_axes = axes[2].twinx()
    current_axes.plot(df["Date_Time"], df["Current"], "r")
    current_axes.set_ylabel("Current (mA)")
    axes[2].legend(["V"], bbox_to_anchor=(1.15, 1.1))
    current_axes.legend(["I"], bbox_to_anchor=(1.14, 0.9))

    plt.savefig("static/data.png")

where df is a dataframe created using pandas. This is supposed to be in the background of a web server, so all I want is for this function to drop the file in the directory specified. However, when it executes it does this, and then pulls up a figure window and gets stuck in a loop, preventing me from reloading the page. Am I missing something obvious?

EDIT: Forgot to add, I am running python 2.7 on Windows 7, 64 bit.

Magic_Matt_Man
  • 2,020
  • 3
  • 16
  • 16
  • 3
    You may want to check whether you're running in [interactive mode](http://matplotlib.org/faq/usage_faq.html#what-is-interactive-mode). –  Nov 17 '14 at 10:03
  • 2
    Also, what backend do you use? Have you picked a non-gui backend? –  Nov 17 '14 at 10:04
  • Hi @Evert. I did try using plt.ioff() to force interactive mode off, but that didn't help. Or rather, it allowed the code to run twice, instead of just once (generating two figure windows before getting stuck). Could you explain how I should choose a non-gui backend? – Magic_Matt_Man Nov 17 '14 at 11:33
  • Thank you. I chose "AGG" as the backend and now the function behaves exactly as expected. If you submit your answer formally, I can accept it and close the question. – Magic_Matt_Man Nov 17 '14 at 11:49

3 Answers3

22

Step 1

Check whether you're running in interactive mode. The default is non-interactive, but you may never know:

>>> import matplotlib as mpl
>>> mpl.is_interactive()
False

You can set the mode explicitly to non-interactive by using

>>> from matplotlib import pyplot as plt
>>> plt.ioff()

Since the default is non-interactive, this is probably not the problem.

Step 2

Make sure your backend is a non-gui backend. It's the difference between using Agg versus TkAgg, WXAgg, GTKAgg etc, the latter being gui backends, while Agg is a non-gui backend.

You can set the backend in a number of ways:

  • in your matplotlib configuration file; find the line starting with backend:

    backend: Agg
    
  • at the top of your program with the global matplotlib function use:

    matplotlib.use('Agg')
    
  • import the canvas directly from the correct backend; this is most useful in non-pyplot "mode" (OO-style), which is what I often use, and for a webserver style of use, that may in the end prove best (since this is a tad different than above, here's a full-blown short example):

    import numpy as np
    from matplotlib.figure import Figure
    from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
    figure = Figure()
    canvas = FigureCanvas(figure)
    axes = figure.add_subplot(1, 1, 1)
    axes.plot(x, np.sin(x), 'k-')
    canvas.print_figure('sine.png')
    
6

Perhaps just clear the axis, for example:

plt.savefig("static/data.png")
plt.close()

will not plot the output in inline mode. I can't work out if is really clearing the data though.

0

use below:

plt.rcParams['figure.subplot.hspace'] = 0.002

## The figure subplot parameters.  All dimensions are a fraction of the figure width and height.

#figure.subplot.left:   0.125  # the left side of the subplots of the figure
#figure.subplot.right:  0.9    # the right side of the subplots of the figure
#figure.subplot.bottom: 0.11   # the bottom of the subplots of the figure
#figure.subplot.top:    0.88   # the top of the subplots of the figure
#figure.subplot.wspace: 0.2    # the amount of width reserved for space between subplots,
                               # expressed as a fraction of the average axis width
#figure.subplot.hspace: 0.2    # the amount of height reserved for space between subplots,
                               # expressed as a fraction of the average axis height

instead of

plt.subplots_adjust(hspace=0.2)

reference urls:

Customizing Matplotlib with style sheets and rcParams

matplotlib.pyplot.subplots_adjust

Sean
  • 11
  • 2