Подсветка соответствующих точек на соседних участках - PullRequest
1 голос
/ 15 января 2020

У меня проблема с выделением соответствующих точек на графиках в python с помощью matplotlib. Я попытался сделать это с помощью функции, которая считывает данные из графиков, когда я щелкаю мышью по точке (onpick). Затем я пытаюсь аннотировать эту информацию на других смежных участках. У меня проблема с использованием переменных из функции onpick в команде annotate. Я хотел бы использовать параметр ind из функции onpick в команде annotate, но python его не видит. Это функция onpick:

def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    global ind
    ind = event.ind
    print('x:', xdata[ind],'y:',ydata[ind])

Я вызываю функцию с помощью этой команды:

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

Аннотирование:

ax = plt.subplot2grid((lg, 2), (0, 0), colspan=2)
    ax.plot(t, mp, picker=1)
    ax.set_title('map')
    ax.annotate('here',(t[ind],mp[ind]),xytext=(0.8,0.9),
                arrowprops=dict(facecolor='grey',color='grey'))

Python окно команды показывает это:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\kubag\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/kubag/Desktop/pyton/wykres/wykres.py", line 78, in graph
    ax.annotate('here',(t[ind],mp[ind]),xytext=(0.8,0.9),arrowprops=dict(facecolor='grey',color='grey'))
NameError: name 'ind' is not defined

Весь код:

import matplotlib.pyplot as plt

t=range(10)
mp=range(10)
v=range(10)

def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    global ind
    ind = event.ind
    print('x:',int(xdata[ind]),'y:',int(ydata[ind]))
    global ind2
    ind2=int(ind)
    ax.annotate('miejsce', (t[ind2], mp[ind2]), xytext=(0.8, 0.9), arrowprops=dict(facecolor='grey'))

fig = plt.figure()
global ax
ax = plt.subplot2grid((1, 2), (0, 0))
ax.plot(t, mp, picker=1)

ax1 = plt.subplot2grid((1, 2), (0, 1))
ax1.plot(t, v, picker=1)

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

1 Ответ

0 голосов
/ 16 января 2020

Определить ind вне функции; недостаточно использовать global ind внутри, если только вы не можете гарантировать, что onpick будет вызываться до того, как будет использоваться ind.

Рассмотрим

def fun():
    global i
    i = 10
print(i)

Это вызывает ошибку

NameError: name 'i' is not defined

на линии print(i)

Однако

def fun():
    global i
    i = 10
fun()
print(i)

Работает отлично. Поэтому, если вы не можете гарантировать, что функция (fun) будет вызвана до того, как будет использована переменная (i), просто определите переменную вне функции:

i = 0
def fun():
    global i
    i = 10
print(i)

Таким образом i может использоваться независимо от того, была ли вызвана функция.

—-

Редактировать

Вызов

fig.canvas.draw()

должен быть внутри onpick и после ax.annotate вместо того, чтобы после подключения функции с

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

, иначе холст не будет обновляться после PickEvent. Так что onpick должно выглядеть так

def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    global ind
    ind = event.ind
    print('x:',int(xdata[ind]),'y:',int(ydata[ind]))
    global ind2
    ind2=int(ind)
    ax.annotate('miejsce', (t[ind2], mp[ind2]), xytext=(0.8, 0.9), 
                arrowprops=dict(facecolor='grey'))
    fig.canvas.draw()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...