mpl-gui 文档#
动机#
本项目是用于彻底改进 Matplotlib 在 pyplot 中提供的 GUI 事件循环管理工具的原型空间。
pyplot 模块目前提供两个关键但无关的功能:
提供一个状态完整(state-full)的隐式 API,其风格与 MATLAB 相似/受 MATLAB 启发
管理 Matplotlib 与 GUI 事件循环之间的交互,包括保持 Figure 活跃
虽然在命令行下工作时可能非常方便,但状态完整(state-full)的 API 可能会导致代码脆弱,以令人困惑的方式依赖于全局状态,尤其是在库代码中使用时。另一方面,matplotlib.pyplot
很好地向用户隐藏了他们正在开发 GUI 应用程序的事实,并与 IPython 一起处理了许多并行运行 GUI 应用程序和 Python 的细节。
示例#
如果您想确保此代码不秘密依赖于 pyplot,请运行
import sys
sys.modules['matplotlib.pyplot'] = None
这将阻止 pyplot 被导入!
显示#
API 的核心是 show
import mpl_gui as mg
from matplotlib.figure import Figure
fig1 = Figure(label='A Label!')
fig2 = Figure()
mg.show([fig1, fig2])
它将显示所有图形(figures)并阻塞,直到它们关闭。作为“显示”过程的一部分,将创建正确的 GUI 对象,将其放置在屏幕上,并运行宿主 GUI 框架的事件循环。
阻塞(或不阻塞)#
与 plt.ion
和 plt.ioff
类似,我们提供了 mg.ion()
和 mg.ioff()
,它们具有相同的语义。因此
import mpl_gui as mg
from matplotlib.figure import Figure
mg.ion()
print(mg.is_interactive())
fig = Figure()
mg.show([fig]) # will not block
mg.ioff()
print(mg.is_interactive())
mg.show([fig]) # will block!
与 plt.show
一样,您可以通过 block 关键字参数显式控制 mg.show
的阻塞行为
import mpl_gui as mg
from matplotlib.figure import Figure
fig = Figure(label='control blocking')
mg.show([fig], block=False) # will never block
mg.show([fig], block=True) # will always block
交互状态与 Matplotlib 共享,也可以通过 matplotlib.interactive
控制,并通过 matplotlib.is_interactive
查询。
Figure 和 Axes 创建#
与 matplotlib.pyplot
类似,我们也提供了 figure
、subplots
和 subplot_mosaic
import mpl_gui as mg
fig1 = mg.figure()
fig2, axs = mg.subplots(2, 2)
fig3, axd = mg.subplot_mosaic('AA\nBC')
mg.show([fig1, fig2, fig3])
如果 mpl_gui
处于“交互模式”下,则 mpl_gui.figure
、mpl_gui.subplots
和 mpl_gui.subplot_mosaic
将自动把新的 Figure 放在屏幕上的窗口中(但不会运行事件循环)。
FigureRegistry#
在上述示例中,用户有责任跟踪创建的 Figure
实例。如果用户没有直接或间接通过其子项保留对 fig
对象的硬引用,那么它将像任何其他 Python 对象一样被垃圾回收。虽然这在某些情况下(例如创建许多临时图形的脚本或函数)可能是有利的,但它失去了 matplotlib.pyplot
为您跟踪实例的便利性。为此,我们还提供了 FigureRegistry
import mpl_gui as mg
fr = mg.FigureRegistry()
fr.figure()
fr.subplots(2, 2)
fr.subplot_mosaic('AA\nBC')
fr.show_all() # will show all three figures
fr.show() # alias for pyplot compatibility
fr.close_all() # will close all three figures
fr.close('all') # alias for pyplot compatibility
因此,如果您只使用 pyplot API 的这一受限集,那么您可以更改
import matplotlib.pyplot as plt
更改为
import mpl_gui as mg
plt = mg.FigureRegistry()
并获得一个(大部分)可直接替换的方案。
此外,还有一个 FigureRegistry.by_label
辅助工具,它返回一个将 Figure 的标签映射到每个 Figure 的字典
import mpl_gui as mg
fr = mg.FigureRegistry()
figA = fr.figure(label='A')
figB = fr.subplots(2, 2, label='B')
fr.by_label['A'] is figA
fr.by_label['B'] is figB
FigureContext#
一个非常常见的用例是创建多个图形并在最后将它们一起显示。为了方便这一点,我们提供了一个 FigureRegistry
的子类,它可以作为上下文管理器使用,(在本地)跟踪创建的图形并在退出时显示它们
import mpl_gui as mg
with mg.FigureContext() as fc:
fc.subplot_mosaic('AA\nBC')
fc.figure()
fc.subplots(2, 2)
这将创建 3 个图形并在 __exit__
时阻塞。阻塞行为取决于 mg.is_interacitve()
(并遵循 mg.show
的行为,或者可以通过 block 关键字参数显式控制)。
选择 GUI 工具包#
mpl_gui
利用 Matplotlib 后端来实际提供 GUI 绑定。与 matplotlib.use
和 matplotlib.pyplot.switch_backend
类似,mpl_gui
提供了 mpl_gui.select_gui_toolkit
来选择使用的 GUI 工具包。select_gui_toolkit
具有与 pyplot
相同的回退行为,并将其状态存储在 rcParams["backend"]
中。mpl_gui
将与 matplotlib.pyplot
管理的 Figure 在同一进程中保持一致共存。