如何在Jupyter笔记本中临时(局部)更改Matplotlib后端以供函数使用,而不影响全局后端?

4
  • 目标:

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

我一直在运行%matplotlib qt,然后在运行该函数之后立即运行%matplotlib inline。但是,我不想费心这两行额外的代码,特别是因为%matplotlib inline必须在单独的单元格中运行。这容易出现用户错误 - 如果用户忘记运行该单元格,则后端将卡在Qt5Agg中。

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

请注意,我正在Windows上编码,但我必须确保笔记本在所有操作系统上都能正常工作。

  • 我到目前为止尝试过的方法:

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

import matplotlib.pyplot as plt

@plt.rc_context({'backend': 'Qt5Agg'})
def function(foo):
    ...
    return None

这个函数的背景被设置了,但是Matplotlib却没有使用它!如果我在函数内部打印后端(backend),它会告诉我这是Qt5Agg,而我正在下面看着一个内联图。可以通过rc_context有效地更改其他参数。我可以轻松地更改像'lines.linestyle'这样的东西,图形将反映出这些更改。只有在处理后端时,Matplotlib拒绝使用我设置的值。

接下来,我尝试在rcParams字典中更改'backend'值(这会全局更改后端,并非本地,但我还是尝试了一下)。它导致了类似的情况,即值已在字典中更改,但Matplotlib仍然使用内联后端。我还尝试过使用switch_backendmatplotlib.use,但两者都无法可靠地工作。此外,它们也应该全局更改后端,因此不适合我的用途。在我发现的所有方法中,魔法是唯一正确更改后端的方式。

  • 总结:
  1. 除非使用魔法,否则我无法可靠地更改Matplotlib的后端。
  2. 魔法以全局方式设置后端,而不是在函数内部本地设置。
  3. 我需要本地更改后端,仅适用于一个函数。
  4. Matplotlib不会使用rc_context中的后端。

P.S. - 这是我的第一篇帖子,如果我没有提供所有有用的信息,请见谅。如果您需要更多信息,请告诉我。

1个回答

2

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

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

在我的Windows计算机上,它完美地工作。我可以使用默认的关闭按钮关闭图形窗口,也可以通过使用Matplotlib小部件传递plt.close()来关闭。在这两种情况下,后端都会切换回内联。


谢谢分享。我处于同样的情况。顺便问一下,你尝试过rc_context了吗? - Delosari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接