Skip to content

Commit a499643

Browse files
timhoffmmeeseeksmachine
authored andcommitted
Backport PR matplotlib#29773: DOC: Improve interactive figures guide / Blocking input
1 parent 465d984 commit a499643

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

galleries/users_explain/figure/interactive_guide.rst

+41-37
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Interactive figures and asynchronous programming
1111

1212
Matplotlib supports rich interactive figures by embedding figures into
1313
a GUI window. The basic interactions of panning and zooming in an
14-
Axes to inspect your data is "baked in" to Matplotlib. This is
14+
Axes to inspect your data is available out-of-the-box. This is
1515
supported by a full mouse and keyboard event handling system that
1616
you can use to build sophisticated interactive graphs.
1717

@@ -23,6 +23,21 @@ handling system <event-handling>`, `Interactive Tutorial
2323
`Interactive Applications using Matplotlib
2424
<http://www.amazon.com/Interactive-Applications-using-Matplotlib-Benjamin/dp/1783988843>`__.
2525

26+
27+
GUI events
28+
==========
29+
30+
All GUI frameworks (Qt, Wx, Gtk, Tk, macOS, or web) have some method of
31+
capturing user interactions and passing them back to the application, but
32+
the exact details depend on the toolkit (for example callbacks in Tk or
33+
the ``Signal`` / ``Slot`` framework in Qt). The Matplotlib :ref:`backends
34+
<what-is-a-backend>` encapsulate the details of the GUI frameworks and
35+
provide a framework-independent interface to GUI events through Matplotlib's
36+
:ref:`event handling system <event-handling>`. By connecting functions
37+
to the event handling system (see `.FigureCanvasBase.mpl_connect`), you can
38+
interactively respond to user actions in a GUI toolkit agnostic way.
39+
40+
2641
Event loops
2742
===========
2843

@@ -58,19 +73,6 @@ depending on the library, by methods with names like ``exec``,
5873
``run``, or ``start``.
5974

6075

61-
All GUI frameworks (Qt, Wx, Gtk, tk, macOS, or web) have some method of
62-
capturing user interactions and passing them back to the application
63-
(for example ``Signal`` / ``Slot`` framework in Qt) but the exact
64-
details depend on the toolkit. Matplotlib has a :ref:`backend
65-
<what-is-a-backend>` for each GUI toolkit we support which uses the
66-
toolkit API to bridge the toolkit UI events into Matplotlib's :ref:`event
67-
handling system <event-handling>`. You can then use
68-
`.FigureCanvasBase.mpl_connect` to connect your function to
69-
Matplotlib's event handling system. This allows you to directly
70-
interact with your data and write GUI toolkit agnostic user
71-
interfaces.
72-
73-
7476
.. _cp_integration:
7577

7678
Command prompt integration
@@ -81,16 +83,16 @@ lets us interactively send code to the interpreter and get results
8183
back. We also have the GUI toolkit that runs an event loop waiting
8284
for user input and lets us register functions to be run when that
8385
happens. However, if we want to do both we have a problem: the prompt
84-
and the GUI event loop are both infinite loops that each think *they*
85-
are in charge! In order for both the prompt and the GUI windows to be
86+
and the GUI event loop are both infinite loops and cannot run in
87+
parallel. In order for both the prompt and the GUI windows to be
8688
responsive we need a method to allow the loops to "timeshare" :
8789

88-
1. let the GUI main loop block the python process when you want
89-
interactive windows
90-
2. let the CLI main loop block the python process and intermittently
91-
run the GUI loop
92-
3. fully embed python in the GUI (but this is basically writing a full
93-
application)
90+
1. **Blocking the prompt**: let the GUI main loop block the python
91+
process when you want interactive windows
92+
2. **Input hook integration**: let the CLI main loop block the python
93+
process and intermittently run the GUI loop
94+
3. **Full embedding**: fully embed python in the GUI
95+
(but this is basically writing a full application)
9496

9597
.. _cp_block_the_prompt:
9698

@@ -108,24 +110,26 @@ Blocking the prompt
108110
backend_bases.FigureCanvasBase.stop_event_loop
109111

110112

111-
The simplest "integration" is to start the GUI event loop in
112-
"blocking" mode and take over the CLI. While the GUI event loop is
113-
running you cannot enter new commands into the prompt (your terminal
114-
may echo the characters typed into the terminal, but they will not be
115-
sent to the Python interpreter because it is busy running the GUI
116-
event loop), but the figure windows will be responsive. Once the
117-
event loop is stopped (leaving any still open figure windows
118-
non-responsive) you will be able to use the prompt again. Re-starting
119-
the event loop will make any open figure responsive again (and will
120-
process any queued up user interaction).
113+
The simplest solution is to start the GUI event loop and let it run
114+
exclusively, which results in responsive figure windows. However, the
115+
CLI event loop will not run, so that you cannot enter new commands.
116+
We call this "blocking" mode. (Your terminal may echo the typed characters,
117+
but they will not yet be processed by the CLI event loop because the Python
118+
interpreter is busy running the GUI event loop).
119+
120+
It is possible to stop the GUI event loop and return control to the CLI
121+
event loop. You can then use the prompt again, but any still open figure
122+
windows are non-responsive. Re-starting the GUI event loop will make these
123+
figure responsive again (and will process any queued up user interaction).
124+
121125

122-
To start the event loop until all open figures are closed, use
123-
`.pyplot.show` as ::
126+
The typical command to show all figures and run the GUI event loop
127+
exclusively until all figures are closed is ::
124128

125-
pyplot.show(block=True)
129+
plt.show()
126130

127-
To start the event loop for a fixed amount of time (in seconds) use
128-
`.pyplot.pause`.
131+
Alternatively, you can start the GUI event loop for a fixed amount of time
132+
using `.pyplot.pause`.
129133

130134
If you are not using `.pyplot` you can start and stop the event loops
131135
via `.FigureCanvasBase.start_event_loop` and

0 commit comments

Comments
 (0)