Sorting the handles and labels in python legend, based on part of the label strings

1.4k Views Asked by At

I've plotted some data on a chart in python and then used

handles, labels = ax0_1.get_legend_handles_labels()

to get the labels and handles. The labels I get are ordered like this:

A1 01-01-01 01 ABC
A1 01-01-01 01 ABCD
A1 01-01-01 01 ABCDE
A1 01-01-01 02 ABC
A1 01-01-01 02 ABCD
A1 01-01-01 02 ABCDE

... but what I need is to sort the labels AND the corresponding handles so that the order would be this:

A1 01-01-01 01 ABC
A1 01-01-01 02 ABC
A1 01-01-01 01 ABCD
A1 01-01-01 02 ABCD
A1 01-01-01 01 ABCDE
A1 01-01-01 02 ABCDE

I've tried several things, but so far ended up with only a headache.
Anybody know how this be done ?

2

There are 2 best solutions below

2
Adam Sosnowski On

Try sorting indexes by desired key first:

labels = [
    'A1 01-01-01 01 ABC',
    'A1 01-01-01 01 ABCD',
    'A1 01-01-01 01 ABCDE',
    'A1 01-01-01 02 ABC',
    'A1 01-01-01 02 ABCD',
    'A1 01-01-01 02 ABCDE'
]

handles = range(len(labels))

sorted_indexes = sorted(range(len(labels)), key=lambda i: labels[i].split()[-1])
sorted_labels1 = [labels[i] for i in sorted_indexes]
sorted_handles = [handles [i] for i in sorted_indexes]

Just for fun: a little more obscure, but shorter solution:

sorted_labels, sorted_handles = zip(*sorted(zip(labels, handles),               
                                            key=lambda (label, handle): label.split()[-1]))
1
alfavictor On

After a lot experimentation, and using Adam Sosnowski's idea as inspiration, I've found a way of doing it:

    indexes =[]
    for l in labels:
        indexes.append(labels.index(l))
    sorted_labels = sorted(labels, key = lambda string: string.split()[-1])
    sorted_indexes = []
    for i, l in enumerate(labels):
        for j in range(len(labels)):
         if labels[i] == sorted_labels[j]:  
            sorted_indexes.append(j)
    sorted_handles = [handles [i] for i in sorted_indexes]
    handles =sorted_handles
    labels = sorted_labels

Granted, this is not the most elegant code, but it works. I'll try to develop a more compact code later.