prompt-toolkit / ptpython

A better Python REPL
BSD 3-Clause "New" or "Revised" License
5.22k stars 278 forks source link

[bug] cannot support matplotlib's interactive mode #485

Open Freed-Wu opened 2 years ago

Freed-Wu commented 2 years ago

Related issue: https://github.com/matplotlib/matplotlib/issues/24968

Reproduce Procedures

ptpython --config-file=/dev/null
from matplotlib import pyplot as plt
import numpy as np
import matplotlib as mpl
t = np.arange(0., 5., 0.2)
mpl.use('qt5agg')
plt.ion()
plt.plot(t, t, t, t**2, t, t**3)

The screen will be blank and crash.

However, if

python

then input the same python code. matplotlib will work normally.

This example refer to https://matplotlib.org/stable/tutorials/introductory/usage.html#what-is-interactive-mode.

Environment

❯ uname -r
5.14.14-arch1-1
❯ has python ptpython
✓ python 3.9.7
✓ ptpython 3.0.19
❯ python -c 'print(__import__("matplotlib").__version__)'
3.4.3
Freed-Wu commented 2 years ago

This is another example:

# Use qt5agg by default
from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.plot(range(3))
fig.show()

In python, a window will be opened normally. In ptpython, the result is matplotlib is not responding and window collapsed.

ssiegel commented 3 days ago

I have no idea what the consequences of the change in https://github.com/ssiegel/ptpython/commits/matplotlib-interactive are (changing from in_thread=True to in_thread=False in particular), so I won't open a pull request for now. But it seems to work fine for me. Also on the linked branch is a second commit that integrates the PySide6 Qt event loop, so the QtAgg Backend can be used interactively as well.

We need to run the (Tkinter, Qt) event loops from the main thread because that's where Matplotlib creates the GUI. It should be possible to run the event loops while prompt_toolkit.application.Application.run(in_thread=True) is doing its job in a separate thread. But unfortunately the call is blocking, so to do anything on the main thread we would have to change that function.