Skip to content

[Bug]: Figures fail to redraw with IPython #23042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ahesford opened this issue May 13, 2022 · 8 comments · Fixed by #23057
Closed

[Bug]: Figures fail to redraw with IPython #23042

ahesford opened this issue May 13, 2022 · 8 comments · Fixed by #23057
Milestone

Comments

@ahesford
Copy link

Bug summary

A regression between release versions 3.5.1 and 3.5.2 causes figures to fail to redraw after an initial plot is added using the pyplot interface in an interactive IPython session. This has been observed with both pyplot.plot and pyplot.tripcolor. The figure will show the first plot drawn, but subsequent calls to pyplot.plot and pyplot.tripcolor fail to update an on-screen figure until pyplot.draw is invoked. This has been observed with IPython versions 8.3.0 (current) and 8.2.0.

Both the Qt5 and Tk backends exhibit the same issues.

Code for reproduction

# Install matplotlib and ipython in a virtualenv
python3 -m venv ~/mpl.venv
. ~/mpl.venv/bin/activate
pip install matplotlib ipython

# Make sure to start with a clean config
mv ~/.ipython ~/.ipython.backup
mv ~/.config/matplotlib .config/matplotlib.backup

# Run `pylab`
ipython --pylab=tk

# ... the following are commands issues in the ipython prompt
plot(arange(10))
plot(-arange(10))
draw()

Actual outcome

  1. After the first plot command, a figure appears with a y = x line shown.
  2. After the second plot command, the figure does not update.
  3. After the draw command, the figure updates to show both the y = x and y = -x lines.

Expected outcome

  1. After the first plot command, a figure appears with a y = x line shown. (This is as expected.)
  2. After the second plot command, the figure updates with the addition of a y = -x line. (This is the deviation.)
  3. The draw command should produce no visible change in the figure.

Additional information

This regression has been bisected to commit f937b0a.

The testbed is a current Void Linux system running Python 3.10.4, including the system python3-tkinter package for a GUI. (As noted above, this bug is also present with the Qt5 backend.) All packages were installed in a virtual environment. The output of pip freeze is:

asttokens==2.0.5
backcall==0.2.0
cycler==0.11.0
decorator==5.1.1
executing==0.8.3
fonttools==4.33.3
ipython==8.3.0
jedi==0.18.1
kiwisolver==1.4.2
matplotlib==3.6.0.dev155+gf937b0ab5e
matplotlib-inline==0.1.3
numpy==1.22.3
packaging==21.3
parso==0.8.3
pexpect==4.8.0
pickleshare==0.7.5
Pillow==9.1.0
prompt-toolkit==3.0.29
ptyprocess==0.7.0
pure-eval==0.2.2
Pygments==2.12.0
pyparsing==3.0.9
python-dateutil==2.8.2
setuptools-scm==6.4.2
six==1.16.0
stack-data==0.2.0
tk==0.1.0
tomli==2.0.1
traitlets==5.2.0
wcwidth==0.2.5

(Note that the funny matplotlib version comes from a local git repo checked out to the problematic commit.)

Operating system

Void Linux x86_64

Matplotlib Version

3.5.2

Matplotlib Backend

TkAgg, Qt5Agg

Python version

3.10.4

Jupyter version

None

Installation

pip

@tacaswell
Copy link
Member

On the bright side, there is a very easy fix, an explicit call to ion (aka plt.ion aka matplotlib.pyplot.ion()) will fix the behavior.

I suspect that this is more fallout from deferring actually loading the backend until it is actually needed.

@tacaswell tacaswell added this to the v3.5.3 milestone May 13, 2022
@tacaswell
Copy link
Member

@ahesford Thank you for reporting this and sorry we broke this.

Please forgive my last message if it came across as too terse.

@ahesford
Copy link
Author

No worries. I'm glad there's a simple workaround. In the meantime, I reverted the version shipped in Void pending a release with a permanent fix.

@oscargus
Copy link
Member

I'm not really sure how the backend solution works with the --pylab=tk switch, but it seems like a solution would be to do ion as part of that as the backend is actually selected then.

@ahesford
Copy link
Author

I can confirm that ion resolves the issue. Should IPython assume responsibility for activating interactive mode when importing matplotlib, or should matplotlib attempt to figure out whether to enable interactive mode by default by some suitable means?

@tacaswell
Copy link
Member

This is something that has historically been done by IPython (it is a side effect of --pylab (who's use is discouraged but we are never going to deprecate it)). However, with #22005 we delayed resolving and configuring the backend until it is actually needed (which is the first time you create a Figure, could actually be pushed back to "first time you show a figure", but that is off in https://github.com/matplotlib/mpl-gui land).

There is something going wrong in the (brittle) dance between IPython and Matplotlib. Given that it is as change on the mpl side that broke this I assume it it our fault and can (and should) fix it, but we still need to sort out why which will likely require chasing through the code on both sides. It is complicated because both side have extensive "work with old versions of the other" code.

Related, I observed in some cases at NSLS-II that if we had pylab = auto in the IPython config files we saw a similar issue (it was a bit worse, the input hook did not get installed 😱 ) and this was with earlier version of the 3.5 series.

@harripj
Copy link

harripj commented May 17, 2022

I am also experiencing this, and plt.ion() fixed it for me. Thanks for the suggestion @tacaswell!

It would be nice if this line was not necessary as I will have to update all of my notebooks!

tacaswell added a commit to tacaswell/matplotlib that referenced this issue May 17, 2022
closes matplotlib#23042

In matplotlib#22005 we change `pyplot` so that at import time we do not force a switch of
the backend and install the repl displayhook.

However, this meant that in some cases (primarily through `ipython --pylab`) to
end up with a session where `install_repl_displayhook` had never been called.
tacaswell added a commit to tacaswell/matplotlib that referenced this issue May 17, 2022
closes matplotlib#23042

In matplotlib#22005 we change `pyplot` so that at import time we do not force a switch of
the backend and install the repl displayhook.

However, this meant that in some cases (primarily through `ipython --pylab`) to
end up with a session where `install_repl_displayhook` had never been called.
tacaswell added a commit to tacaswell/matplotlib that referenced this issue May 17, 2022
closes matplotlib#23042

In matplotlib#22005 we change `pyplot` so that at import time we do not force a switch of
the backend and install the repl displayhook.

However, this meant that in some cases (primarily through `ipython --pylab`) to
end up with a session where `install_repl_displayhook` had never been called.
tacaswell added a commit to tacaswell/matplotlib that referenced this issue May 18, 2022
closes matplotlib#23042

In matplotlib#22005 we change `pyplot` so that at import time we do not force a switch of
the backend and install the repl displayhook.

However, this meant that in some cases (primarily through `ipython --pylab`) to
end up with a session where `install_repl_displayhook` had never been called.

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
@oscargus
Copy link
Member

@harripj see #11283 for a discussion about having ion on by default.

andrew-fennell pushed a commit to andrew-fennell/matplotlib that referenced this issue Jun 14, 2022
closes matplotlib#23042

In matplotlib#22005 we change `pyplot` so that at import time we do not force a switch of
the backend and install the repl displayhook.

However, this meant that in some cases (primarily through `ipython --pylab`) to
end up with a session where `install_repl_displayhook` had never been called.

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants