Reputation: 25093
By default Matplotlib orders the entries in the legend by column, e.g.,
In [48]: from matplotlib.pyplot import subplots, show
...: f, ax = subplots(figsize=(6, 2), constrained_layout=True)
...: for i in range(1, 10):
...: ax.plot((0,1),(0,1), label=str(i))
...: ax.legend(ncol=4, loc=3)
...: show()
but I'd like better to have the entries listed by rows, like
1 2 3 4
5 6 7 8
9
I could reorder the handles and labels and invoke ax.legend
passing the reordered lists (I'll post that as an answer if requested in comments) but I'd like to know if there is a more direct and straightforward way to instruct Matplotlib to do as I want, so that I don't have to copy and paste the reorder solution in 50% of the Matplotlib scripts I'll write…
Upvotes: 2
Views: 1966
Reputation: 25093
You can get the lists of handles to artists and the labels using the Axes method get_legend_handles_labels
, then you call legend
passing the reordered lists.
To reorder the lists, we observe that
legend
places in the first column the first elements in the lists, then proceeds with the following columns/items,ncol
) except the last one, moreover in each column the increment betweeen items must equal ncol
.That said, it is possible to generate a sublist for each column using slicing, the length of the column is automatically the right one..., and eventually use sum
to join the sub lists in the reordered one.
In [59]: from matplotlib.pyplot import subplots, show
...: reorder = lambda l, nc: sum((l[i::nc] for i in range(nc)), [])
...:
...: f, ax = subplots(figsize=(6, 2), constrained_layout=True)
...: for i in range(1, 10):
...: ax.plot((0,1),(0,1), label=str(i))
...: h, l = ax.get_legend_handles_labels()
...: ax.legend(reorder(h, 4), reorder(l, 4), ncol=4, loc=3)
...: show()
A few years later...
Slightly more compact in its usage when calling legend
reorder=lambda hl,nc:(sum((lis[i::nc]for i in range(nc)),[])for lis in hl)
...
h_l = ax.get_legend_handles_labels()
ax.legend(*reorder(h_l, 4), ncol=4)
(but you must remember to unpack the values returned by reorder
).
Upvotes: 1