Нарисуйте линию из двух точек, нажатых на экран сюжета, затем удалите художников - PullRequest
2 голосов
/ 11 мая 2019

Я хочу, чтобы этот код позволял мне щелкать по экрану графика в двух разных позициях, наносить «X» на каждую щелчковую координату, а затем рисовать линию между ними.После этого, если я снова нажму на экран графика, я хочу, чтобы код удалял разбросанные по «X» и линии.Приведенный ниже код имеет проблему с удалением линии (работает для удаления скаттеров).Он продолжает возвращать UnboundLocalError: локальную переменную 'l', на которую ссылается перед присваиванием.Может кто-нибудь объяснить мне, почему при таком подходе метод remove () работает для точечного графика, а не для линейного?Спасибо!

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3], [10,20,30])
p_arts = []
px, py = [], []

def onclick(event):
    if len(p_arts) < 2:
        p = ax.scatter(event.xdata, event.ydata)
        p_arts.append(p)
        px.append(event.xdata)
        py.append(event.ydata)
        if len(p_arts) == 2:
            l = ax.plot(px, py)
    else:
        p_arts[0].remove()
        p_arts[1].remove()
        p_arts.clear()
        px.clear()
        py.clear()
        l.remove()
    fig.canvas.draw()

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

1 Ответ

1 голос
/ 11 мая 2019

Сначала давайте посмотрим, что означает ошибка.

Она появляется в строке l.remove() и означает, что переменная l определена где-то в вашей функции, , но в момент вызова remove, еще не определено .

Обратите внимание, что l является локальной переменной, что означает, что один экземпляроно создается при вызове вашей функции и впоследствии уничтожается;он не передается между вызовами.

Тогда ясно, что, поскольку l определен только в ветви if, если берется ветвь else, мы столкнемся с ошибкой, поскольку дляэтот конкретный вызов onclick, l не существует.

Решение состоит в том, чтобы просто добавить его к p_arts, как вы делаете для художника scatterplot.Я также немного очистил бы код следующим образом:

def onclick(event):
    if len(p_arts) == 0:
        # plot first scatter
        scatter_artist = ax.scatter(event.xdata, event.ydata)
        p_arts.append(scatter_artist)

    elif len(p_arts) == 1:
        # plot second scatter and line
        scatter_artist = ax.scatter(event.xdata, event.ydata)
        p_arts.append(scatter_artist)
        line_artist = ax.plot([event.xdata], [event.ydata])[0]
        p_arts.append(line_artist)

    else:
        # remove everything
        for artist in p_arts:
            artist.remove()

    fig.canvas.draw()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...