matplotlib / ipympl

Matplotlib Jupyter Integration
https://matplotlib.org/ipympl/
BSD 3-Clause "New" or "Revised" License
1.59k stars 225 forks source link

matplotlib 3.7 brakes plotting #524

Open trackhacs opened 1 year ago

trackhacs commented 1 year ago

Describe the issue

i do first plot in cell, than try to plot a second plot in a new cell, each starting with "%matplotlib widget".

matplotlib 3.6.x : both cells have separate independent plots matplotlib 3.7.x: the plot from second cell gets added to the plot of first cell, only one plot as whole is generated. If I try to add this plot to the output tab - the plots completely disappear without any error message.

Versions

jupyterlab: 3.5.x and 3.6.x - didnt make a difference ipympl: 0.8.x and 0.9.2 - didnt make a difference

I am not sure if this is the right place for this, since this is linked to matplotlib though.

ianhi commented 1 year ago

@trackhacs thanks for reporting - happily this is already fixed by https://github.com/matplotlib/ipympl/pull/517. If you upgrade to ipympl version 0.9.3 then it should work

trackhacs commented 1 year ago

I just tried it - and unfortunately the problem still with:

matplotlib: 3.7.1 ipympl: 0.9.3

the difference now is, that the same plot is shown below each cell, but still containing the plotted information from both cells.

edit: downgrading to matplotlib 3.6.3 solves this issue again.

ianhi commented 1 year ago

Can you please post a screenshot of what you mean?

trackhacs commented 1 year ago

interesting. could not reproduce it on linux with ipympl 0.9.2 / 0.9.3 and matplotlib 3.7.1.

will try later on windows.

trackhacs commented 1 year ago

so this is on windows. however in this case with only on plot. before it also plotted this plot below the second input cell - so the same plot but twice.

ipympl 0.9.3 matplotlib 3.7.1

image001

trackhacs commented 1 year ago

maybe to add. on windows the plots are done in different venv than jupyter.

ianhi commented 1 year ago

Ah ok that's helpful thank you! I think matplotlib is actually behaving in the way it's supposed to here, but it can be really confusing at first especially if you are coming from the inline backend. Formerly when you reloaded the backend with %matplotlib widget then the matplotlib would reset the list of active active figures, it seems matplotlib no longer does that.

This is important because you are relying on the special case of there being no active figures to display them when you called plot. When you call plot with no open figures then matplotlib oepns and displays the figure. However, if there is already an open figure then plot will plot to what ever axis is the current axis (as returned by plt.gca()).

The fix is to be more explicit about figure creation and which axis you are plotting to.

so I would do it like this:

fig, ax = plt.subplots()
ax.plot([1,2,3,4])

and then you can make a new figure

fig, ax = plt.subplots()
ax.plot([4,3,2,1])

This is basically the same issue as https://github.com/matplotlib/ipympl/issues/171 and #60. So it's clear that at very least we need better documentation of this.

ianhi commented 1 year ago

I found where I'd explained this more thoroughly before: https://github.com/matplotlib/ipympl/issues/248#issuecomment-666705506

trackhacs commented 1 year ago

going to read #248

however - using jupyter notbook/lab since its creation - i am really used to that matplotlib keeps the current plot and that automatically creates a new one below the new cell - freezing the first interactive plot into an inline.

this used to be default behavior:

image

so this new behavior actually would be a regression for me, sadly.

also over the years i got really scared to update jupyter - it always ended up in a couple of days not being able to plot - guess thats the price for the fast pace of development. ;)

trackhacs commented 1 year ago

to get more concrete:

with < 3.6.x %matplotlib would create a new plot. with 3.7.1 %matplotlib does not create a new plot.

following picture shows 3.6.1 how it behaves if %matplotlib is not called in the new cell.

image

ianhi commented 1 year ago

So I think the change in behavior comes from this PR on matplotlib: https://github.com/matplotlib/matplotlib/pull/22005

Also note that I'm sure that the way you were relying on the behavior of %matplotlib widget was never intended as a use case to be relied on.

But hope is not lost

I think you can have the behavior you want again by replacing the %matplotlib widget with figure() and then you should have the behavior you are looking for

trackhacs commented 1 year ago

thx for feedback - will experiment and stay with 3.6.x till than.

LukasMueller187 commented 1 year ago

Also stumbled upon this, was also expecting the behavior @trackhacs was expecting. Runnning the same cell twice makes the plot disappear, unlike in version 3.6.x