0

The function in the code snippet below should create a simple matplotlib figure and return it.

import matplotlib.pyplot as plt
import numpy as np


def random_figure():
    fig, axes = plt.subplots(2, 1, squeeze=True)
    for ax in axes:
        ax.plot(*np.random.rand(10, 2))
    return fig

What I don't understand is that the figure it is drawn more often than expected:

  • If I store the return value with my_fig = random_figure(), it is still drawn.

  • If I just run random_figure(), it is shown twice:

enter image description here

Is this a setting in matplotlib I'm unaware of?

I'm using jupyter notebook in vscode, if that's relevant.


PS, my expectation is that it behave like the function

def random_number():
    return np.random.rand()

which outputs nothing when the return value is stored with my_num = random_number().

ElRudi
  • 2,122
  • 2
  • 18
  • 33
  • Is there any additional configuration in your jupyter notebbok, like `%matplotlib inline`? – nonDucor Jun 24 '22 at 17:23
  • No, I only run the above code – ElRudi Jun 24 '22 at 17:31
  • vscode's `settings.json` has a few jupyter-settings, but nothing that seems related – ElRudi Jun 24 '22 at 17:33
  • 1
    Ok I tried a bit more and `%matplotlib inline` has no effect, but `%matplotlib widget` indeed returns the expected number of plots. So I guess that's it. Still confused as to why the initial behaviour would make sense – ElRudi Jun 24 '22 at 17:53

1 Answers1

0

You are observing it printing twice because of the REPL-like design of the final referenced item of each Jupyter cell, see first two sentences here. In Jupyter this limits it to showing it once:

import matplotlib.pyplot as plt
import numpy as np


def random_figure():
    fig, axes = plt.subplots(2, 1, squeeze=True)
    for ax in axes:
        ax.plot(*np.random.rand(10, 2))
    return fig
random_figure();

Remember the end of a cell is special because of the REPL design for it. That is why you can just put a variable on the final line of a cell and get the value back without needing print(my_variable).
The code block above works because the last things the cell sees is ; which returns nothing.
With what you had, it returns the plot and so it shows it yet again after it's made it.

With my_fig = random_figure() you don't see it twice because what is returned by random_figure() gets consumed by the assignment.

The trick with adding the ; is often used to suppress object codes of plots (things that like <Figure size 432x288 with 0 Axes>') and sometimes more from showing up in addition to your plot in the output area, see example here, in particular Kynan's comment here explaining why it works.

Wayne
  • 6,607
  • 8
  • 36
  • 93