Home > Net >  How to change order and grouping of entries in a matplotlib legend?
How to change order and grouping of entries in a matplotlib legend?

Time:01-17

This is what my legend looks like right now:

enter image description here

I want it to look like this:

enter image description here

My code:

ax = cars.plot.barh(stacked=True)
ax.invert_yaxis()
plt.legend(loc="center", ncols=4)

I tried adding the line plt.plot(0, np.zeros([1, 3]), '.', ms=0, label='fake') and ax.plot(0, np.zeros([1, 3]), '.', ms=0, label='fake') but the result is this:

enter image description here

The entries labelled "fake" should be added from the back. I can then change the label from "fake" to "" to create empty entries.

CodePudding user response:

I don't think that is explicitly supported. You can work around it by adding additional, fake entries to the legend (in your case 3). Consider:

import numpy as np
import matplotlib.pyplot as plt

plt.figure()

# Actual data
for i in range(13):
    plt.plot(np.random.random(), np.random.random(), '.', label=chr(ord('A')   i))

# Fake data, for the legend
plt.plot(0, np.zeros([1, 3]), '.', ms=0, label=' ')

plt.legend(ncol=4)
plt.show()  # or plt.savefig('figname.png')

Here I've used a marker size (ms) of 0, ensuring that the plotted fake data points will not appear on either the plot nor the legend.

CodePudding user response:

You could add some dummy legend handles to fill up the empty space:

from matplotlib import pyplot as plt

labels = 'abcdefghijklm'
for i, label in enumerate(labels):
    plt.bar([i], (i   1) ** 2, color=plt.cm.turbo_r(i / len(labels)), label=label)
handles, labels = plt.gca().get_legend_handles_labels()
dummy_handle = plt.Rectangle((0, 0), 0, 0, color='none', label='')
plt.legend(handles=handles   3*[dummy_handle], ncol=4)
plt.show()

legend with 4 filled-up columns

  • Related