首页 > 解决方案 > 在 IPython 中抑制 Matplotlib 图例警告

问题描述

我正在创建一个包含大量数据的图并为其添加图例:

import matplotlib.pyplot as plt
import numpy as np

plt.plot(np.arange(100000), np.random.random((100000, 10)), label='data')
plt.legend()

当图例实际上在另一个线程中绘制时,这会生成一个警告(如预期的那样):

<matplotlib.legend.Legend at 0x1b5824d04c8>C:\Users\...\lib\site-packages\ipykernel\eventloops.py:106: UserWarning: Creating legend with loc="best" can be slow with large amounts of data.
  app.exec_()

我想压制这个特定的警告,所以我这样做

from warnings import filterwarnings
filterwarnings("ignore", category=UserWarning, module="matplotlib")

再次运行相同的绘图代码会产生相同的警告。

我该如何压制它?理想情况下,我想warnings.catch_warnings围绕对legend. 就像是

with warnings.catch_warnings():
    plt.legend()

Qt5agg原始命令使用后端在 spyder (ipython) 中以交互模式运行。plt.show()我还在一个普通的 python 控制台中运行了相同的命令:

__main__:1: UserWarning: Creating legend with loc="best" can be slow with large amounts of data.

运行filterwarnings("ignore", category=UserWarning, module="__main__") 有帮助,但仅限于非交互模式。在交互模式下,会发出以下警告:

C:\Users\...\lib\site-packages\pyreadline\console\console.py:514: UserWarning: Creating legend with loc="best" can be slow with large amounts of data.
  call_function(inputHookFunc, ())

这个问题似乎是 ipython 特有的。我在用

Python 3.8.3、IPython 7.16.1、matplotlib 3.2.2(和 numpy 1.18.5)

标签: pythonmatplotlibipythonwarnings

解决方案


这个答案显示了如何根据 OP 标题抑制图例警告。它没有解释如何在警告发出后临时捕获警告。如果您对后者感兴趣,那么以下是一种解决方法而不是答案。

根据源代码,如果使用默认位置(默认情况下),则会显示警告rcParams['legend.loc']'best'并且需要超过 1 秒才能找到最佳位置。如果您将位置明确设置为'best'不会发出警告。

在 Windows 上测试,IPython 和普通命令行(我不得不增加我机器上的数字):

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(1)
plt.plot(np.arange(1_000_000), np.random.random((1_000_000, 10)), label='data')
plt.legend(loc='best')
plt.show()

作为替代方案,您可以通过其消息(而不是module)永久抑制警告:

filterwarnings("ignore", 'Creating legend with loc="best" can be slow with large amounts of data.')

缺点是它是永久性的。我找不到通过使用上下文管理来暂时抑制警告的方法,因为上下文当然在图例位置计算发生之前很久就关闭了。
要将此更改恢复为警告过滤器列表,您可以在最终绘制图例warnings.filters = [w for w in warnings.filters if not w[1] or not re.match(w[1], 'Creating legend with loc="best" can be slow with large amounts of data.')]执行以下操作之一:或filterwarnings("default", 'Creating legend with loc="best" can be slow with large amounts of data.')


推荐阅读