0

I'm running this code in a Jupyter notebook:

import matplotlib.pyplot as plt

def func():
    fig, ax = plt.subplots(1, 1)
    ax.plot([0,1], [0,1])
    return None

func()

The output displays the plot, even though it wasn't returned or used outside the function. Why is this, and how do I change this behavior?

shakedzy
  • 2,853
  • 5
  • 32
  • 62
  • 1
    There's some solutions to this here: https://stackoverflow.com/questions/18717877/prevent-plot-from-showing-in-jupyter-notebook – K.Cl Apr 19 '21 at 11:45

1 Answers1

1

pyplot maintains a global registry of figures (it is stashed in the call to plt.figure(...)) and IPython / Jupyter will make sure they get shown (as in most cases it is better to err on the side of showing plots you did not want than to not show plots you did want!). If you only need the figure inside of the function you can do:

from matplotlib.figure import Figure

def func():
    fig = Figure()
    ax = fig.subplots()
    ax.plot(...)
    fig.savefig('/tmp/output.png')
    return None

In this case pyplot will not keep a reference to your figure and it will be gargabe collected when the function returns.

This will work out of the box with mpl3.1+, for older version you will need to add

from matplotlib.backend_bases import FigureCanvasBase
FigureCanvasBase(fig)

after you create the figure.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • thanks, but I don't want the figure to be trashed, as it will be used in another paragraph in the notebook :/ – shakedzy Apr 20 '21 at 11:59
  • @shakedzy Can you please clarify your question with what you actually want then? I understood (incorrectly) that you did not want the figure to be available outside of the called function as you did not return it. – tacaswell Apr 20 '21 at 20:04
  • You are correct, it was a little misleading. In my actual case, the function returns the `ax` which is saved in a variable. The `ax` is then used in another paragraph. – shakedzy Apr 21 '21 at 10:27