Closed
Description
Bug summary
When passing non-str loc
values to legend
, validation is not performed. So even for invalid inputs, errors are raised only when we call show()
Code for reproduction
>>> import matplotlib.pyplot as plt
>>> import matplotlib as mpl
>>> xs, ys = [1,2,3], [2,3,1]
>>> fig, ax = plt.subplots(3)
>>> ax[0].scatter(xs, ys, label='loc-tuple-arg')
<matplotlib.collections.PathCollection object at 0x0000019D4099ED60>
>>> ax[0].legend(loc=(1.1, .5, 1.1, "abc"))
<matplotlib.legend.Legend object at 0x0000019D4099EF10>
>>> plt.show()
Actual outcome
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Me\anaconda3\envs\MPL\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\Me\anaconda3\envs\MPL\lib\tkinter\__init__.py", line 814, in callit
func(*args)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\_backend_tk.py", line 251, in idle_draw
self.draw()
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 10, in draw
super().draw()
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\backend_agg.py", line 405, in draw
self.figure.draw(self.renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 74, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\figure.py", line 3071, in draw
mimage._draw_list_compositing_images(
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\axes\_base.py", line 3107, in draw
mimage._draw_list_compositing_images(
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\legend.py", line 641, in draw
bbox = self._legend_box.get_window_extent(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\offsetbox.py", line 354, in get_window_extent
px, py = self.get_offset(w, h, xd, yd, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\offsetbox.py", line 291, in get_offset
return (self._offset(width, height, xdescent, ydescent, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\legend.py", line 617, in _findoffset
fx, fy = self._loc
ValueError: too many values to unpack (expected 2)
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Me\anaconda3\envs\MPL\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\Me\anaconda3\envs\MPL\lib\tkinter\__init__.py", line 814, in callit
func(*args)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\_backend_tk.py", line 251, in idle_draw
self.draw()
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 10, in draw
super().draw()
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\backends\backend_agg.py", line 405, in draw
self.figure.draw(self.renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 74, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\figure.py", line 3071, in draw
mimage._draw_list_compositing_images(
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\axes\_base.py", line 3107, in draw
mimage._draw_list_compositing_images(
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
return draw(artist, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\legend.py", line 641, in draw
bbox = self._legend_box.get_window_extent(renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\offsetbox.py", line 354, in get_window_extent
px, py = self.get_offset(w, h, xd, yd, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\offsetbox.py", line 291, in get_offset
return (self._offset(width, height, xdescent, ydescent, renderer)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\legend.py", line 617, in _findoffset
fx, fy = self._loc
ValueError: too many values to unpack (expected 2)
Expected outcome
Errors should be raised when invalid arguments are passed to loc
. Similar to what we get when we pass an invalid string value as shown:
>>> ax[0].legend(loc="abcd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\axes\_axes.py", line 307, in legend
self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\_api\deprecation.py", line 454, in wrapper
return func(*args, **kwargs)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\legend.py", line 470, in __init__
loc = _api.check_getitem(self.codes, loc=loc)
File "C:\Users\Me\anaconda3\envs\MPL\lib\site-packages\matplotlib\_api\__init__.py", line 190, in check_getitem
raise ValueError(
ValueError: 'abcd' is not a valid value for loc; supported values are 'best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center'
Additional information
- Do you know why this bug is happening?
matplotlib/lib/matplotlib/legend.py
Lines 608 to 615 in ab7917a
No validation is done when setting values for _loc_real
. We do check strings on line 473, which is why we don't face this issue there.
Operating system
Windows
Matplotlib Version
3.6.2
Matplotlib Backend
'TkAgg'
Python version
3.9.7
Jupyter version
No response
Installation
pip