1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-matplotlib-user-guide-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
7.3.md 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 03:14 86b54d1

Обработка событий и выбор

Исходный текст: Event handling and picking

Переводчик: Фейлун

Протокол: CC BY-NC-SA 4.0

Matplotlib использует множество инструментов пользовательского интерфейса (wxpython, tkinter, qt4, gtk и macosx), чтобы поддерживать интерактивное перемещение и масштабирование графиков. У него есть набор API, который позволяет взаимодействовать с графиками через нажатия клавиш и движение мыши, и он «GUI-нейтрален», что очень полезно для разработчиков, так как им не нужно повторять большое количество кода для разных пользовательских интерфейсов. Хотя API обработки событий является GUI-нейтральным, оно основано на модели GTK, которая является первой моделью пользовательского интерфейса, поддерживаемой matplotlib. По сравнению со стандартными событиями GUI, события, которые запускаются, также более разнообразны и включают информацию о том, где произошло событие в matplotlib.axes.Axes. События также могут понимать систему координат matplotlib и сообщать о положении события в пикселях и координатах данных.

Подключение к событиям

Чтобы получать события, вам нужно написать функцию обратного вызова, а затем подключить вашу функцию к менеджеру событий, который является частью FigureCanvasBase. Вот простой пример, который печатает местоположение щелчка мышью и какую кнопку нажали:

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(np.random.rand(10))

def onclick(event):
    print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
          (event.button, event.x, event.y, event.xdata, event.ydata))

cid = fig.canvas.mpl_connect('button_press_event', onclick)

FigureCanvas метод mpl_connect() возвращает идентификатор соединения, который представляет собой просто целое число. Когда вы хотите разорвать соединение с обратным вызовом, просто вызовите:

fig.canvas.mpl_disconnect(cid)

Обратите внимание, что холст сохраняет только слабую ссылку на обратный вызов. Поэтому, если обратный вызов является методом класса, вам необходимо сохранить ссылку на экземпляр. В противном случае экземпляр будет собран сборщиком мусора, и обратный вызов исчезнет.

Вот список событий, к которым можно подключиться, и описание того, что происходит при возникновении события:

Событие Класс и описание
'button_press_event' MouseEvent — кнопка мыши была нажата
'button_release_event' MouseEvent — кнопка мыши отпущена
'draw_event' DrawEvent — холст рисует график
'key_press_event' KeyEvent — клавиша была нажата
'key_release_event' KeyEvent — клавиша отпущена
'motion_notify_event' MouseEvent — мышь перемещается
'pick_event' PickEvent — объект на холсте был выбран
'resize_event' ResizeEvent — размер холста графика изменился
'scroll_event' MouseEvent — колесо прокрутки мыши было прокручено
'figure_enter_event' LocationEvent — мышь вошла в новый график
'figure_leave_event' LocationEvent — мышь покинула график
'axes_enter_event' LocationEvent — мышь вошла в новую область осей
'axes_leave_event' LocationEvent — мышь покинула область осей

Свойства событий

Все события matplotlib наследуются от базового класса matplotlib.backend_bases.Event, который хранит следующие свойства:

  • name — имя события;
  • canvas — экземпляр FigureCanvas, который сгенерировал событие;
  • guiEvent — событие GUI, которое вызвало событие matplotlib.

Наиболее распространёнными событиями являются события нажатия/отпускания клавиш, нажатия/отпускания и перемещения мыши. Классы KeyEvent и MouseEvent, которые обрабатывают эти события, оба наследуют от LocationEvent, у которого есть следующие свойства:

  • x — позиция x, расстояние в пикселях от левого края холста;
  • y — позиция y, расстояние в пикселях от нижнего края холста;
  • inaxesAxes экземпляр, если мышь прошла через область осей.
  • xdata — координата x мыши в координатах данных;
  • ydata — координата y мыши в координатах данных.

Но давайте посмотрим на простой пример холста, в котором каждый раз, когда нажимается кнопка мыши, создаётся сегмент линии.

from matplotlib import pyplot as plt

class LineBuilder:
    def __init__(self, line):
        self.line = line
        self.xs = list(line.get_xdata())
        self.ys = list(line.get_ydata())
        self.cid = line.figure.canvas.mpl_connect('button_press_event', self)

    def __call__(self, event):
        print('click', event)
        if event.inaxes!=self.line.axes: return
        self.xs.append(event.xdata)
        self.ys.append(event.ydata)
        self.line.set_data(self.xs, self.ys)
        self.line.figure.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click to build line segments')
line, = ax.plot([0], [0])  # empty line
linebuilder = LineBuilder(line)

plt.show()

Мы только что использовали MouseEvent, который является LocationEvent, поэтому мы можем получить доступ к данным и пиксельным координатам в event.x и event.xdata. Помимо свойств LocationEvent, он имеет:

  • button — нажатая кнопка, None, 1, 2, 3, 'up', 'down' ('up', 'down' используется для событий прокрутки);
  • key — нажатая клавиша, None, любой символ, 'shift', 'win' или 'control'.

Упражнение по созданию перетаскиваемого прямоугольника

Напишите класс перетаскиваемого прямоугольника, инициализированный экземпляром Rectangle, который можно перетащить, но его положение x, y изменяется при перетаскивании. Подсказка: вам нужно сохранить исходное положение xy прямоугольника и сохранить позицию щелчка мыши в пиксельных координатах при нажатии. При нажатии кнопки мыши проверьте, произошёл ли щелчок внутри вашего прямоугольника (см. matplotlib.patches.Rectangle.contains()), и сохраните исходное положение прямоугольника xy и координаты щелчка мыши. В обратном вызове события движения вычислите смещение deltax и deltay движения мыши и добавьте эти приращения к сохранённому исходному прямоугольнику и перерисуйте его. В событии отпускания кнопки просто сбросьте все данные о нажатой кнопке на None.

Здесь решение:

import numpy as np
import matplotlib.pyplot as plt

class DraggableRectangle:
    def __init__(self, rect):
        self.rect = rect
        self.press = None

    def connect(self):
        'connect to all the events we need'
        self.cidpress = self.rect.figure.canvas.mpl_connect(
            'button_press_event', self.on_press)
        self.cidrelease = self.rect.figure.canvas.mpl_connect(
            'button_release_event', self.on_release)
        self.cidmotion = self.rect.figure.canvas.mpl_connect(
            'motion_notify_event', self.on_motion)

    def on_press(self, event):

...
``` **Вычислить среднее значение и стандартное отклонение для 100 массивов данных и построить график зависимости среднего значения от стандартного отклонения. При нажатии на точку (μ, σ) отобразить исходные данные из массива, которые сформировали эти значения.**

Решение задачи:
```py
"""
вычислить среднее значение и стандартное отклонение для 100 наборов данных и построить график зависимости среднего от стандартного отклонения.
При нажатии на одну из точек μ, σ отобразить исходный временной ряд из набора данных, который сформировал эти значения.
"""
import numpy as np
import matplotlib.pyplot as plt

X = np.random.rand(100, 1000)
xs = np.mean(X, axis=1)
ys = np.std(X, axis=1)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('нажмите на точку, чтобы построить временной ряд')
line, = ax.plot(xs, ys, 'o', picker=5)  # 5 точек допуска

def onpick(event):
    if event.artist!=line: return True
    N = len(event.ind)
    if not N: return True

    figi = plt.figure()
    for subplotnum, dataind in enumerate(event.ind):
        ax = figi.add_subplot(N,1,subplotnum+1)
        ax.plot(X[dataind])
        ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]),
                transform=ax.transAxes, va='top')
        ax.set_ylim(-0.5, 1.5)
    figi.show()
    return True

fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-matplotlib-user-guide-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-matplotlib-user-guide-zh.git
oschina-mirror
wizardforcel-matplotlib-user-guide-zh
wizardforcel-matplotlib-user-guide-zh
master