如何临时(本地)更改 Jupyter Notebook 中函数的 Matplotlib 后端,而不影响全局后端?

apa*_*ito 5 python matplotlib ipython jupyter jupyter-notebook

  • 目标:

我正在编写一个在 Jupyter 笔记本中使用Qt5Agg后端的函数。笔记本的其余部分主要使用内联。该函数使用 matplotlib 小部件生成交互式绘图,我想让它在单独的窗口中工作。笔记本的其余部分会生成一堆数字,有时在一个单元格中生成数百个数字,为​​了提高效率,必须内联生成这些数字。

我在%matplotlib qt运行该函数之前和%matplotlib inline运行该函数之后立即运行。但是,我不想打扰这两条额外的线路,特别是因为%matplotlib inline必须在单独的单元中运行。它很容易出现用户错误 - 如果用户忘记之后运行该单元,后端将卡在 Qt5Agg 中。

我想通过在函数中添加一些代码来临时更改后端。这将具有使该功能更加兼容的额外优点。我可以将它转移到其他笔记本上,它会使用 Qt5Agg 按预期工作,并且不会干扰该笔记本的其余部分使用的任何后端(内联或其他)。

请注意,我在 Windows 上进行编码,但我必须确保笔记本电脑可以在所有操作系统上运行。

  • 到目前为止我已经尝试过:

我能想到的最明显的解决方案是使用装饰器设置临时 rc 上下文......

import matplotlib.pyplot as plt

@plt.rc_context({'backend': 'Qt5Agg'})
def function(foo):
    ...
    return None
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,这为后端设置了一个上下文,但 Matplotlib 不使用它!如果我从函数内打印后端,它会告诉我它是 Qt5Agg,而我则盯着它下面的内联图。其他参数可以使用 有效更改rc_context。我可以轻松地更改诸如此类的内容'lines.linestyle',并且情节将反映这些更改。只有当涉及到后端时,Matplotlib 拒绝使用我设置的值。

接下来我尝试更改字典'backend'中的值rcParams(这会全局更改后端,而不是本地更改,但我还是尝试了)。这会导致类似的情况,即字典中的值发生更改,但 Matplotlib 继续使用内联后端。我也尝试过使用switch_backendand matplotlib.use,但它们都不能可靠地工作。此外,他们还应该在全球范围内更改后端,因此不适合我的使用。到目前为止我发现的所有方法中,魔法是正确更改后端的唯一方法。

  • 概括:
  1. 如果不使用魔法,我无法让 Matplotlib 可靠地更改后端。
  2. Magic 在全局设置后端,而不是在函数内本地设置。
  3. 我需要在本地更改后端,仅用于一项功能。
  4. Matplotlib 不会使用rc_context.

PS - 这是我的第一篇文章,如果我没有提供所有有用的信息,我深表歉意。如果您需要更多信息,请告诉我。

apa*_*ito 2

我发现切换到 PyQt 并返回内联的最佳方法是通过'close_event'in mpl_connect。以下是我所做的概述:

def function(foo):
    #Switches to qt interactive backend
    %matplotlib qt
    ...
    fig = plt.figure(...)
    ...
    def on_close(event):
        %matplotlib inline
    fig.canvas.mpl_connect('close_event', on_close) #Switches backend to inline when the figure closes
    ...
    return None
Run Code Online (Sandbox Code Playgroud)

它在我的 Windows 机器上完美运行。我可以使用默认关闭按钮或使用plt.close()Matplotlib 小部件来关闭图形窗口。在这两种情况下,后端都会切换回内联。