简体   繁体   中英

plt.show() is empty when the plt.plot() calls are done in other cells

Context

I have to write a Jupyter notebook for a physics assignement, and I have to draw some graph showing the evolution of some quantities etc...

I have to explain almost each line of code I write by alternating between code and Markdown cells each time, including the plot() calls, which is where my problem comes from. In very simple terms, I have something like :


My code

We first import the matplotlib.pyplot module :

from matplotlib import pyplot as plt

Next, we creates lists of values from the data :

# making up stuff
x_values = range(10)
doubles = [x * 2 for x in x_values]
squares = [x**2 for x in x_values]

We first plot the curve for doubles :

%matplotlib inline

plt.plot(x_values, doubles, color='red', label='x * 2')

It shows the graph for the doubles (and only for the doubles)

Then we plot squares :

%matplotlib inline

plt.plot(x_values, squares, color='red', label='x^2')

It shows the graph for the squares (and only for the squares)

And, finally, we configure our graph and show it :

%matplotlib inline

plt.xlabel("x")
plt.ylabel("f(x)")
plt.ylim(0, 50)
plt.xlim(0, 11)
plt.legend()
plt.grid(True)
plt.show()

It shows an empty graph, with the labels, grid and limits set right, but no curve or legend at all


Expected

The last cells shows a graph with the two curves and the legend and all the stuff I configured

What happens/My problem

The last cells shows an empty graph with no curve or legend

What I've Tried

However, if I try to put the plot() calls in the last cell, with all the other stuff, I do get the expected graph, with the curves, legend, etc... But I cannot do that with my actual assignement, unfortunately :/

I also tried almost every value for the %matplotlib inline line, I tried multiple cells, multiple placements, etc... And it doesn't solve my problem

By googling a bit, it seems like the first line of a notebook behaves a bit differently in regards to matplotlib and all that, but this isn't nearly the first cell in my notebook, so it can't be that.

Honestly, I have no idea why that happens. I think I read somewhere that pyplot works as a sort of state-machine, so maybe the fact that it spreads over multiple lines is making it confused, but for other things (labels, style, etc...) it works as expected, so I'm clueless right now.

So I guess my question is : is this normal behaviour, is it a bug, or am I just missing something ?

EDIT : It seems like using fig, ax = plt.subplots(1, 1) and then plotting on ax works, but the problem is that it adds complexity that I cannot easily explain, that it is rather clunky, and that it doesn't answer "Why does it work when it's in the same cell, but not when the lines are in different cells ?"

If you do not want to use fig and ax , then a (maybe not very elegant) solution but easier to explain would be to edit the last cell as following:

plt.plot(x_values, doubles, x_values, squares)

instead of

plt.plot()

This is normal behavior for the Jupyter Notebook. It expects all the commands for one plot to be in the same cell, and then when the cell ends, it renders the plot. That's why you don't need plt.show() . By the way, you only need the IPython magic command %matplotlib inline once per notebook, unless you want to switch between different display modes.

To annotate every line of plotting commands, you could of course just use Python comments within the cell. If you have to use Markdown, a simple workaround is to enumerate the command lines by number comments, or just set notes at certain important lines, and then refer to these numbers in the next Markdown cell.

Note that this annotation problem is not specific to plots. For example, how would you annotate every line of a function definition? The whole definition has to be in one cell.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM