Получение данных из интерактивного сюжета matplotlib - PullRequest
0 голосов
/ 28 сентября 2018

Я пытаюсь использовать интерактивное построение графиков с помощью matplotlib для ручной корректировки автоматически генерируемых данных диаграммы рассеяния.(Программа пытается обнаружить пики в данных временных рядов и поставить точку на каждом из них, но в данных временных рядов есть некоторые артефакты, в которых пики обнаруживаются ненадлежащим образом.)

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

Код адаптирован отсюда: Интерактивно добавляйте и удаляйте точки разброса в matplotlib

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(16,4))
a_input = np.sin(range(100))*np.random.normal(20,10,100)
b_input = [ 5, 15, 25, 30, 40, 50, 75, 85]

a = plt.plot(range(len(a_input)),a_input,color='red')[0]
b = plt.scatter(b_input,a_input[b_input],color='grey',s=50,picker=5)
newpeaks = np.array([])

def add_or_remove_point(event):
    global a
    xydata_a = np.stack(a.get_data(),axis=1)
    xdata_a = a.get_xdata()
    ydata_a = a.get_ydata()
    global b
    xydata_b = b.get_offsets()
    xdata_b = b.get_offsets()[:,0]
    ydata_b = b.get_offsets()[:,1]
    global newpeaks

    #click x-value
    xdata_click = event.xdata
    #index of nearest x-value in a
    xdata_nearest_index_a = (np.abs(xdata_a-xdata_click)).argmin()
    #new scatter point x-value
    new_xdata_point_b = xdata_a[xdata_nearest_index_a]
    #new scatter point [x-value, y-value]
    new_xydata_point_b = xydata_a[new_xdata_point_b,:]

    if event.button == 1:
        if new_xdata_point_b not in xdata_b:

            #insert new scatter point into b
            new_xydata_b = np.insert(xydata_b,0,new_xydata_point_b,axis=0)
            #sort b based on x-axis values
            new_xydata_b = new_xydata_b[np.argsort(new_xydata_b[:,0])]
            #update b
            b.set_offsets(new_xydata_b)
            newpeaks = b.get_offsets()[:,0]
            plt.draw()
    elif event.button == 3:
        if new_xdata_point_b in xdata_b:
            #remove xdata point b
            new_xydata_b = np.delete(xydata_b,np.where(xdata_b==new_xdata_point_b),axis=0)
            #print(new_xdata_point_b)
            #update b
            b.set_offsets(new_xydata_b)
            newpeaks = b.get_offsets()[:,0]
        plt.draw()

    print(len(newpeaks))
    return newpeaks

fig.canvas.mpl_connect('button_press_event',add_or_remove_point)
plt.show()

Интересно, что b.get_offsets () делает обновлятьсявне функции, поэтому, если я переназначу newpeaks вручную в командной строке после завершения сценария, я получу правильные обновленные данные.Но если я помещу присваивание

newpeaks = b.get_offsets()[:,0]

после функции в сценарии, оно запускается первым и не обновляется при закрытии графика.Я хотел бы, чтобы он либо обновлялся автоматически, как только график закрывался, либо как-то обновлял глобальную переменную вместо того, чтобы делать это вручную.Любой совет приветствуется!

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