Python: Matplotlib 交互模式绘图
Interactive figures
https://matplotlib.org/stable/users/explain/interactive.html#interactive-figures
When working with data, interactivity can be invaluable. The pan/zoom and mouse-location tools built into the Matplotlib GUI windows are often sufficient, but you can also use the event system to build customized data exploration tools.
Matplotlib ships with backends binding to several GUI toolkits (Qt, Tk, Wx, GTK, macOS, JavaScript) and third party packages provide bindings to kivy and Jupyter Lab. For the figures to be responsive to mouse, keyboard, and paint events, the GUI event loop needs to be integrated with an interactive prompt. We recommend using IPython (see below).
The pyplot
module provides functions for explicitly creating figures that include interactive tools, a toolbar, a tool-tip, and key bindings:
pyplot.figure
- Creates a new empty
Figure
or selects an existing figure pyplot.subplots
- Creates a new
Figure
and fills it with a grid ofAxes
pyplot
has a notion of "The Current Figure" which can be accessed through pyplot.gcf
and a notion of "The Current Axes" accessed through pyplot.gca
. Almost all of the functions in pyplot
pass through the current Figure
/ Axes
(or create one) as appropriate.
Matplotlib keeps a reference to all of the open figures created via pyplot.figure
or pyplot.subplots
so that the figures will not be garbage collected. Figure
s can be closed and deregistered from pyplot
individually via pyplot.close
; all open Figure
s can be closed via plt.close('all')
.
See also
For more discussion of Matplotlib's event system and integrated event loops:
Interactive mode
pyplot.ion |
Enable interactive mode. |
pyplot.ioff |
Disable interactive mode. |
pyplot.isinteractive |
Return whether plots are updated after every plotting command. |
pyplot.show |
Display all open figures. |
pyplot.pause |
Run the GUI event loop for interval seconds. |
Interactive mode controls:
- whether created figures are automatically shown
- whether changes to artists automatically trigger re-drawing existing figures
- when
pyplot.show()
returns if given no arguments: immediately, or after all of the figures have been closed
If in interactive mode:
- newly created figures will be displayed immediately
- figures will automatically redraw when elements are changed
pyplot.show()
displays the figures and immediately returns
If not in interactive mode:
- newly created figures and changes to figures are not displayed until
pyplot.show()
is calledpyplot.pause()
is calledFigureCanvasBase.flush_events()
is called
pyplot.show()
runs the GUI event loop and does not return until all the plot windows are closed
Jupyter Notebook / JupyterLab
Note
To get the interactive functionality described here, you must be using an interactive backend. The default backend in notebooks, the inline backend, is not. backend_inline
renders the figure once and inserts a static image into the notebook when the cell is executed. Because the images are static, they can not be panned / zoomed, take user input, or be updated from other cells.
To get interactive figures in the 'classic' notebook or Jupyter lab, use the ipympl backend (must be installed separately) which uses the ipywidget framework. If ipympl
is installed use the magic:
%matplotlib widget
to select and enable it.
If you only need to use the classic notebook, you can use
%matplotlib notebook
which uses the backend_nbagg
backend provided by Matplotlib; however, nbagg does not work in Jupyter Lab.
在Jupyter Notebook中,默认的inline backend只能渲染figure一次,并将生成的图片插入到notebook中。因为生成的图片是静态的,所以不能随着figure上面元素的变化而更新。
造成的困扰是,当希望查看一段代码的中间过程时,figure可能会被自动渲染;而在查看最终结果时,figure不会再次被渲染,导致不输出结果。
解决的办法是,希望查看一段代码的中间过程时,在代码的前面使用matplotlib.pyplot.ioff()关闭交互模式绘图,并在代码的后面使用matplotlib.pyplot.show()显示figure。
例:
交互模式正常情况下:
In: import matplotlib.pyplot as plt fig, ax = plt.subplots() ln, = ax.plot(range(5)) ln.set_color('orange') Out:
交互模式下希望查看中间过程时:
In: import matplotlib.pyplot as plt fig, ax = plt.subplots() Out: In: ln, = ax.plot(range(5)) ln.set_color('orange') plt.show() Out: # 什么也没有
关闭交互模式,查看中间过程。
查看结果时需要plt.show():
In: import matplotlib.pyplot as plt plt.ioff() # 关闭交互模式 fig, ax = plt.subplots() plt.isinteractive() # 查看是否是交互模式 Out: False In: ln, = ax.plot(range(5)) ln.set_color('orange') plt.show() Out:
注:
不知是否是Jupyter Notebook的bug,在重启Notebook内核后,第一次执行plt.ioff()时无效,plt.isinteractive()输出为True。再次执行plt.ioff()才能关闭交互模式,plt.isinteractive()输出为False。
GUIs + Jupyter
ipympl
GUI backends in a Jupyter Notebook. If you are running your Jupyter kernel locally, the GUI window will spawn on your desktop adjacent to your web browser. If you run your notebook on a remote server, the kernel will try to open the GUI window on the remote computer. Unless you have arranged to forward the xserver back to your desktop, you will not be able to see or interact with the window. It may also raise an exception.PyCharm, Spyder, and VSCode
Many IDEs have built-in integration with Matplotlib, please consult their documentation for configuration details.