Skip to content

[Bug]: legend no longer works with itertools.chain #30078

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jonnybolton16 opened this issue May 19, 2025 · 2 comments · Fixed by #30079
Closed

[Bug]: legend no longer works with itertools.chain #30078

jonnybolton16 opened this issue May 19, 2025 · 2 comments · Fixed by #30079

Comments

@jonnybolton16
Copy link

jonnybolton16 commented May 19, 2025

Bug summary

Calling plt.legend(...) with arguments of type <class 'itertools.chain'> no longer works, and raises TypeError: object of type 'itertools.chain' has no len(). This used to work - some update to the source code seems to have caused this bug.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np
import itertools

def flip(items, ncol):
    return itertools.chain(*[items[i::ncol] for i in range(ncol)])

x = np.arange(-2*np.pi, 2*np.pi, 0.1)
ax = plt.subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')

handles, labels = ax.get_legend_handles_labels()
plt.legend(flip(handles, 2), flip(labels, 2), loc=9, ncol=2)

plt.grid('on')
plt.show()

Actual outcome

Traceback (most recent call last):
File "", line 1, in
File "C:\Users\jonny\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\matplotlib\pyplot.py", line 3628, in legend
return gca().legend(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\jonny\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\matplotlib\axes_axes.py", line 337, in legend
self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\jonny\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\matplotlib\legend.py", line 462, in init
if len(handles) < 2:
^^^^^^^^^^^^
TypeError: object of type 'itertools.chain' has no len()

Expected outcome

For the legend to be correctly applied, as previously.

Additional information

No response

Operating system

No response

Matplotlib Version

3.10.3

Matplotlib Backend

tkagg

Python version

No response

Jupyter version

No response

Installation

pip

@rcomer
Copy link
Member

rcomer commented May 19, 2025

We used to explicitly cast to list right before the length check, but that was removed in #24811 on the grounds it was then redundant. However we have since removed the loop that created the list in #28874.

The original decision to cast to list goes way back.

@tacaswell tacaswell added this to the v3.10.4 milestone May 19, 2025
@tacaswell
Copy link
Member

👍 we should put the cast to list back in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants