Open petercorke opened 2 years ago
@petercorke, the issue you're encountering is indeed an inconsistency in behavior between the inline and notebook/ipympl/widget (let's call it widget from now on) backends.
Unfortunately, it's not completely trivial to fix. The problem is that, in order to achieve a "good user experience" in each case, over the years we had to make slightly different decisions:
plot(x)
"just works" in a cell by itself, giving you a plot you can see immediately, without having to muck around with creating/managing figures, etc. It also tries to make it so that, if in the next cell you type plot(y)
, you now see y
plotted by itself, without x
polluting that figure (x
and y
may be totally unrelated and not make any sense if on the same figure).To achieve both of these goals, the inline backend aggressively closes figures once it's done displaying them, so you don't get "cross-cell side effects".
On the other hand, the widget one leaves them alone, for you to manage manually, so you can decide which ones you want to be interactive and which not.
Now, I don't think this state of affairs is ideal, but I've never sat down with enough time to see how to have a better experience across the two (keep in mind, the widget backend didn't exist when the inline behavior was designed, which was pre-jupyter notebook, back in 2010 for the IPython qt console).
It's possible there's a better long-term solution that @tacaswell or others have come up with. I know this is a nag for many, myself included.
But in the meantime, may I suggest you use this pattern instead. For the inline backend, when you need to manage your figures persistently (keep them alive across cells):
fig, ax = plt.subplots(...)
# do what you need with figure and axis objects
#...
fig # last line to display a figure
and you can use the same code with the widget backend. The only thing you need to do in this case is manually close figures you don't need anymore. But otherwise it's reasonably clean code that, while a bit more verbose, works well for both backends.
I hope this helps!
BTW @petercorke - there's a longer discussion of this very topic in this issue on the ipympl repo, which you might find useful.
I have one notebook cell that creates a 3D axes, which I want to plot into in the next cell.
With the inline backend
we see that the "current plot" has been forgotten, and
plt.gca()
creates a new 2D plot.With the notebook backend
The behaviour is different
and
plt.gca()
remembers the 3D plot across the cell boundaries.Expected behaviour
The same in both cases, ideally the remembering the current plot across the cell boundary. I'm not sure which behaviour is "correct" but the difference is a problem when I'm running code in an ipython kernel from a client.