Issue
I am creating a plot with a large amount of data and adding a legend to it:
import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.arange(100000), np.random.random((100000, 10)), label='data')
plt.legend()
This generates a warning (as expected), when the legend actually gets drawn in another thread:
<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_()
I would like to suppress this specific warning, so I do
from warnings import filterwarnings
filterwarnings("ignore", category=UserWarning, module="matplotlib")
Running the same plotting code again produces the same warning.
How do I suppress it? Ideally, I would like to use warnings.catch_warnings
around the call to legend
. Something like
with warnings.catch_warnings():
plt.legend()
The original commands were run in interactive mode in spyder (ipython) using a Qt5agg
backend. I also ran the same commands followed by plt.show()
in a plain python console:
__main__:1: UserWarning: Creating legend with loc="best" can be slow with large amounts of data.
Running filterwarnings("ignore", category=UserWarning, module="__main__")
helps, but only in non-interactive mode. In interactive mode, the
following warning is issued:
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, ())
The issue seems to be ipython specific. I am using
Python 3.8.3, IPython 7.16.1, matplotlib 3.2.2 (, and numpy 1.18.5)
Solution
This answer shows how to suppress the legend warning as per the OP heading. It doesn't explain how to temporarily catch the warning once it has been issued. If you're interested in the latter than the following is more a workaround than an answer.
According to the source code the warning is shown if the default loaction is used (from rcParams['legend.loc']
which is 'best'
by default) and it takes more than 1 sec to find the best location. If you explicitly set the location to 'best'
no warning will be issued.
Tested on Windows, both IPython and plain command line (I had to increase the number on my machine):
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()
As an alternative you could permanently suppress the warning by its message (instead of module):
filterwarnings("ignore", 'Creating legend with loc="best" can be slow with large amounts of data.')
The drawback is that it's permanent. I couldn't find a way to suppress the warning temporarily by using a context manage as the context of course closes long before the legend position calculation takes place.
To revert this change to the warnings filters list you can do one of the following after the legend is finally drawn: 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.')]
or filterwarnings("default", 'Creating legend with loc="best" can be slow with large amounts of data.')
.
Answered By - Stef
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.