matplotlib — интерактивный выбор точек или местоположений?

#matplotlib

#matplotlib

Вопрос:

В R есть функция locator , похожая на Matlab ginput , где вы можете щелкнуть мышью по фигуре и выбрать любую координату x, y. Кроме того, существует вызываемая функция, в identify(x,y) которой, если вы зададите ей набор точек x, y, которые вы нанесли на график, а затем щелкните по рисунку, он вернет индекс точки x, y, которая находится ближе всего (в пределах регулируемого допуска) к выбранному вами местоположению (или несколькиминдексы, если выбрано несколько точек). Есть ли такая функциональность в Matplotlib?

Комментарии:

1. FWIW: есть также iselect() в iplots пакете (для R). Это обобщение: оно включает в себя связывание и чистку. То же самое можно сделать с помощью get(,'BrushData') функции в Matlab.

2. Правильно, и Rggobi тоже. Но я не знал о возможностях Matlab для этого — в последний раз я интенсивно использовал его еще во времена версии 6.5. Похоже, с тех пор он стал модным.

3. Необычный и дорогой. Стоимость R также утроилась за последнее десятилетие, но она остается выгодной. 🙂

Ответ №1:

Возможно, вы захотите использовать событие выбора :

 fig = figure()
ax1 = fig.add_subplot(111)
ax1.set_title('custom picker for line data')
line, = ax1.plot(rand(100), rand(100), 'o', picker=line_picker)
fig.canvas.mpl_connect('pick_event', onpick2)
 

Допуск, установленный параметром выбора там:

 line, = ax1.plot(rand(100), 'o', picker=5)  # 5 points tolerance
 

Комментарии:

1. Обновленный учебник для pick_event

Ответ №2:

 from __future__ import print_function
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from matplotlib.text import Text
from matplotlib.image import AxesImage
import numpy as np
from numpy.random import rand

if 1:
    fig, ax = plt.subplots()
    ax.set_title('click on points', picker=True)
    ax.set_ylabel('ylabel', picker=True, bbox=dict(facecolor='red'))
    line, = ax.plot(rand(100), 'o', picker=5)

    def onpick1(event):
        if isinstance(event.artist, Line2D):
            thisline = event.artist
            xdata = thisline.get_xdata()
            ydata = thisline.get_ydata()
            ind = event.ind
            print 'X=' str(np.take(xdata, ind)[0]) # Print X point
            print 'Y=' str(np.take(ydata, ind)[0]) # Print Y point

    fig.canvas.mpl_connect('pick_event', onpick1)
 

Комментарии:

1. Если вы импортируете функцию печати из future, вам нужно добавить ограничения: print(‘X=’ str(np.take(xdata, ind)[0]))

Ответ №3:

Вау, сколько лет прошло! Теперь matplotlib также поддерживается ginput функция, которая имеет почти тот же API, что и Matlab. Так что больше нет необходимости взламывать mpl-connect и так далее! (https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.ginput.html ) Например,,

 plt.ginput(4)
 

позволит пользователю выбрать 4 точки.

Комментарии:

1. Существует ли также эквивалент для identify(x, y) ? Или лучше, возможность вызывать что-то вроде ginput() , например, Line2D объекта?

2. @James Paul Mason я не знаком с этим, и, возможно, вы можете выполнить поиск или открыть новый вопрос 🙂

Ответ №4:

Это ginput() удобный инструмент для выбора координат x, y любой случайной точки из отображаемого окна, однако эта точка может не принадлежать отображаемым данным. Для выбора координат точки по x, y из построенных данных эффективным инструментом по-прежнему является использование 'pick_event' property with mpl_connect в качестве примера, приведенного в документации. Например:

 import matplotlib.pyplot as plt 
import numpy as np
from numpy.random import rand

fig, ax = plt.subplots()
ax.plot(rand(100), rand(100), picker=3)
# 3, for example, is tolerance for picker i.e, how far a mouse click from
# the plotted point can be registered to select nearby data point/points.

def on_pick(event):
    global points
    line = event.artist
    xdata, ydata = line.get_data()
    print('selected point is:',np.array([xdata[ind], ydata[ind]]).T)

cid = fig.canvas.mpl_connect('pick_event', on_pick)
 

Последняя строка выше соединит график с 'pick_event' и координаты ближайших точек графика будут продолжать печататься после каждого щелчка мыши на графике, чтобы завершить этот процесс, нам нужно использовать mpl_disconnect как:

 fig.canvas.mpl_disconnect(cid)