Как мы можем установить порядок надписей легенды в python [duplicate]

Итак, я недавно возился с чем-то похожим на это, и я придумал следующее решение, которое использует способ ввода ввода, который отклоняет нежелательный файл, прежде чем он будет проверен любым логическим способом.

read_single_keypress() любезность https://stackoverflow.com/a/6599441/4532996

def read_single_keypress() -> str:
    """Waits for a single keypress on stdin.
    -- from :: https://stackoverflow.com/a/6599441/4532996
    """

    import termios, fcntl, sys, os
    fd = sys.stdin.fileno()
    # save old state
    flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
    attrs_save = termios.tcgetattr(fd)
    # make raw - the way to do this comes from the termios(3) man page.
    attrs = list(attrs_save) # copy the stored version to update
    # iflag
    attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
                  | termios.ISTRIP | termios.INLCR | termios. IGNCR
                  | termios.ICRNL | termios.IXON )
    # oflag
    attrs[1] &= ~termios.OPOST
    # cflag
    attrs[2] &= ~(termios.CSIZE | termios. PARENB)
    attrs[2] |= termios.CS8
    # lflag
    attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
                  | termios.ISIG | termios.IEXTEN)
    termios.tcsetattr(fd, termios.TCSANOW, attrs)
    # turn off non-blocking
    fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
    # read a single keystroke
    try:
        ret = sys.stdin.read(1) # returns a single character
    except KeyboardInterrupt:
        ret = 0
    finally:
        # restore old state
        termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
    return ret

def until_not_multi(chars) -> str:
    """read stdin until !(chars)"""
    import sys
    chars = list(chars)
    y = ""
    sys.stdout.flush()
    while True:
        i = read_single_keypress()
        _ = sys.stdout.write(i)
        sys.stdout.flush()
        if i not in chars:
            break
        y += i
    return y

def _can_you_vote() -> str:
    """a practical example:
    test if a user can vote based purely on keypresses"""
    print("can you vote? age : ", end="")
    x = int("0" + until_not_multi("0123456789"))
    if not x:
        print("\nsorry, age can only consist of digits.")
        return
    print("your age is", x, "\nYou can vote!" if x >= 18 else "Sorry! you can't vote")

_can_you_vote()

Здесь вы можете найти полный модуль здесь .

Пример:

$ ./input_constrain.py
can you vote? age : a
sorry, age can only consist of digits.
$ ./input_constrain.py 
can you vote? age : 23
your age is 23
You can vote!
$ _

Обратите внимание, что природа этой реализации заключается в том, что она закрывает stdin, как только считывается что-то, что не является цифрой. Я не попал в enter после a, но мне нужно было после чисел.

Вы можете объединить это с функцией thismany() в том же модуле, чтобы разрешить, скажем, три цифры.

26
задан CPBL 8 March 2014 в 04:35
поделиться

4 ответа

Порядок детерминирован, но часть частных кишок поэтому может быть изменена в любое время, см. код здесь (элементы self.* - это списки художников, которые были добавлены, следовательно [1]

Если вы хотите явно контролировать порядок элементов в вашей легенде, тогда соберите список обработчиков и меток, как вы это делали в ваше редактирование.

7
ответ дан tacaswell 21 August 2018 в 13:23
поделиться

Следующая функция ищет дескрипторы дескрипторов и меток и сортирует или частично сортирует их в соответствии с заданным списком (order):

def reorderLegend(ax=None,order=None,unique=False):
    """
    Returns tuple of handles, labels for axis ax, after reordering them to conform to the label order `order`, and if unique is True, after removing entries with duplicate labels.
    """
    if ax is None: ax=plt.gca()

    handles, labels = ax.get_legend_handles_labels()
    # sort both labels and handles by labels
    labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
    if order is not None: # Sort according to a given list (not necessarily complete)
        keys=dict(zip(order,range(len(order))))
        labels, handles = zip(*sorted(zip(labels, handles), key=lambda t,keys=keys: keys.get(t[0],np.inf)))
    if unique: # Keep only the first of each handle
        labels, handles= zip(*unique_everseen(zip(labels,handles), key = labels))
    ax.legend(handles, labels)

    return(handles, labels)
def unique_everseen(seq, key=None):
    seen = set()
    seen_add = seen.add
    return [x for x,k in zip(seq,key) if not (k in seen or seen_add(k))]

Функция в обновленной форме находится в cpblUtilities.mathgraph в http://github.com/cpbl

Цитаты: Кевин (эта страница) и Маркус Ярдерот ( Как удалить дубликаты из списка в сохраняя порядок? ).

1
ответ дан Community 21 August 2018 в 13:23
поделиться

Небольшое отклонение от некоторых других участников. Список order должен иметь ту же длину, что и количество элементов легенды, и задает новый порядок вручную.

handles, labels = plt.gca().get_legend_handles_labels()
order = [0,2,1]
plt.legend([handles[idx] for idx in order],[labels[idx] for idx in order])
5
ответ дан Ian Hincks 21 August 2018 в 13:23
поделиться

Вот быстрый фрагмент для сортировки записей в легенде. Предполагается, что вы уже добавили элементы графика с меткой, например, как

ax.plot(..., label='label1')
ax.plot(..., label='label2')

, а затем основной бит:

handles, labels = ax.get_legend_handles_labels()
# sort both labels and handles by labels
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
ax.legend(handles, labels)

Это всего лишь простая адаптация из кода, указанного в http://matplotlib.org/users/legend_guide.html

45
ответ дан kevin 21 August 2018 в 13:23
поделиться
  • 1
    Можно ли использовать натуральные сорта на этикетках? Вот начальная точка . – Agostino 16 June 2015 в 21:09
  • 2
    @kevin ты мой герой! – nye17 9 July 2015 в 04:18
  • 3
    легенда ...... хочет для этого ..... dary! – co9olguy 28 June 2017 в 20:05
Другие вопросы по тегам:

Похожие вопросы: