0

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 ?

alfavictor
  • 63
  • 9
  • Just to clarify: the labels using string the last part of the string, after the space, so only the 'ABC' or 'ABCD' part of the label. – alfavictor Jun 28 '16 at 12:12

2 Answers2

0

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]))
Adam Sosnowski
  • 1,126
  • 9
  • 7
  • Thank you, Adam. That's nice and compact. But it looks like you sort the list of integers (should be called 'handles'?) and then reorder the list of strings... what I'm trying to do is sort the list of strings first (using only the last part of the string, the 'ABC, ABCD, ABCDE' part ) and then reordering the other list accordingly. – alfavictor Jun 28 '16 at 12:15
  • Glad to help. You only need just need to change `key` function passed into `sorted`, much like you have done in your own solution. I will update solution after requirement clarification. – Adam Sosnowski Jun 28 '16 at 16:49
0

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.

alfavictor
  • 63
  • 9
  • Be careful here: the solution has quadratic run time due to nested loops on labels, where it only needs to be linearithmic. – Adam Sosnowski Jun 28 '16 at 16:54