Python: как сказать ginput для matplotlib принимать координаты только от определенных осей (если на рисунке несколько) - PullRequest
0 голосов
/ 20 февраля 2020

Я пишу небольшой сценарий, который поможет мне создать набор данных, вырезав изображения размером 64x64 из больших изображений. Он будет работать таким образом, если щелкнуть увеличенное отображаемое изображение, контур 64x64 будет наложен на изображение (в виде прямоугольного пятна). Он будет иметь кнопку отмены. У меня есть функции обрезки в отдельном скрипте, этот код предназначен только для интерфейса, поэтому я просто нарисовал простой график синуса. Проблема заключается в том, что после нажатия кнопки отмены, plt.ginput () возвращает координаты, соответствующие тому, в каком месте кнопки я нажал (что необходимо определить, чтобы иметь кнопку), в то время как он не должен ничего возвращать. Вот код (я решил прокомментировать его, потому что у людей на других форумах возникли проблемы с его пониманием):

    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.patches import Rectangle
    from matplotlib.widgets import Button

    # the undo function
    def remove_last(self):
        global points
        global rectangles
        shp = np.shape(points)
        if shp[0] > 1:
            points = np.delete(points, -1, 0)
            rectangles[-1].remove()
            rectangles.pop()
        elif shp[0] == 1:
            points = np.empty((0,2))
            rectangles[-1].remove()
            rectangles = []
            print(np.shape(points), points[-1,:])
    ##
    # setting up axes, plotting
    t = np.arange(10)
    # initializing figure and axes, where the sine graph is plotted
    fig, ax = plt.subplots()
    # initializing axes for the undo button
    axbtn = plt.axes([0.7, 0.01, 0.1, 0.075])
    # initializing the button
    btn = Button(axbtn, 'btn')
    btn.on_clicked(remove_last)
    # plotting
    ax.plot(t, np.sin(t))
    plt.gca().set_aspect('equal')

    # initializations
    rectangles = []
    points = np.empty((0,2))
    # not sure why i included this flag lol
    # first = 1
    # comparing xy and xy_prev in the loop prevents from clicking at the same point twice, as the end goal is to have an
    # array of different xy pairs, around which 64x64 images will be cropped from some some larger images for further
    # processing
    # That is why i need to initialize xy_prev as nan (i could've also chosen some negative coordinates or anything that
    # would be outside of the predicted range of the larger image)
    xy_prev = (float('nan'), float('nan'))
    while(True):
        # plt.sca(ax)
        # The problem is that the next line of code will produce an xy pair even when I click on the undo button and a
        # rectangle will be displayed on the axes where the sine plot is.
        xy = plt.ginput(1, timeout=-1)
        if xy_prev != xy:
            # appending the xy pairs and rectangles to their respective arrays/lists
            points = np.append(points, [xy[0]], axis=0)
            rectangles.append(Rectangle((xy[0][0]-0.5, xy[0][1]-0.5), 1, 1, fill='', color='r'))
            # displaying the rectangles
            ax.add_patch(rectangles[-1])
        xy_prev = xy
        # first = 0

Я уже некоторое время безуспешно пытаюсь наладить поиск, поэтому любая помощь будет очень полезной. оценили. То, что я нашел, было функцией Matlab, называемой getpts (ax), так что я мог бы изучить это, однако я бы хотел go полностью с python.

...