sebo
sebo

Reputation: 1664

How to add more items to the matplotlib legend?

When I encountered this problem a couple hours ago I thought it'd only take a few minutes of googling to resolve, but here I am.

I plot all my values using a single plt.bar() call:

plt.bar(range(len(vals)), vals, width=1, color=colors)

This creates a bar graph where the bars are color coded. When I try to create a legend, it only displays one color along with one label. So for example doing this:

labels = ['Group 1', 'Group 2', 'Group 3']
plt.legend(labels,
   loc='best',
   ncol=3)

Only shows 'Group 1' on the legend along with one of the many bar colors. How can I add more items to the legend?

I know that this issue is because I am assigning multiple colors in a single plot, but that is the cleanest solution for that part in this case.

Resources I found suggested using "ax.get_legend_handles_labels()", but that returns two empty lists for me.

EDIT:

@falsetru, Here is a code sample which describes the issue after applying your solution. I included all the relevant parts.

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

items= ['item1','item2','item3']           #item names
vals = [1, 2, 3]                           #values to be plotted
groups = [['item1','item2'], ['item3']]    #defines item groupings

colors = [''] * len(items)
color_space = iter(cm.Paired(np.linspace(0, 1, len(groups))))
for c in groups:
    col = next(color_space)
    for l in c:
        i = items.index(l)
        colors[i] = col

for i, (val, c) in enumerate(zip(vals, colors)):
    plt.bar([i], [val], width=1, color=c)

labels = ['Group 1', 'Group 2']
plt.legend(labels, loc='best')

plt.show()

This is the output, but I'd like group 2 to show the next color. enter image description here

Upvotes: 3

Views: 7665

Answers (1)

falsetru
falsetru

Reputation: 369274

Group the vals (y values), indices (x values) as you did to groups:

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

indices = [[1, 3], [2], [4]]               # <-----
vals = [[1, 2.5], [1.5], [3.5]]            # <-----
labels = ['Group 1', 'Group 2', 'Group 3']

color_space = iter(cm.Paired(np.linspace(0, 1, len(vals))))
for xs, ys, label in zip(indices, vals, labels):
    col = next(color_space)
    plt.bar(xs, ys, width=1, color=col, label=label)

plt.legend(loc='best')
plt.show()

enter image description here

Upvotes: 4

Related Questions