Pyplot: обновление окна imshow()

У меня есть два метода: generate_window(), который показывает изображение, и on_click(), который реагирует на щелчок по окну, показывающему изображение. Они выглядят так:

def generate_panel(img):
  plt.figure()
  ax = plt.gca()
  fig = plt.gcf()
  implot = ax.imshow(img)
  # When a colour is clicked on the image an event occurs
  cid = fig.canvas.mpl_connect('button_press_event', onclick)
  plt.show()

def onclick(event):
  if event.xdata != None and event.ydata != None:
    # Change the contents of the plt window here

В последней строке кода я хочу иметь возможность изменить изображение, отображаемое в окне plt, но я не могу заставить его работать. Я пробовал set_data() и draw() в разных местах, но это не сработало. Какие-либо предложения? Заранее спасибо.


person user3396592    schedule 16.02.2016    source источник


Ответы (1)


Вы также должны включить интерактивный режим с помощью plt.ion(), а затем просто вызвать plt.draw() после того, как ваша модификация должна работать.

NB: При использовании интерактивного режима вы должны указать аргумент block=True для plt.show(), чтобы предотвратить немедленное закрытие окна.

Эта модифицированная версия вашего примера должна отображать круг при каждом щелчке мыши:

from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import numpy as np


def generate_panel(img):
    plt.figure()
    ax = plt.gca()
    fig = plt.gcf()
    implot = ax.imshow(img)
    # When a colour is clicked on the image an event occurs
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    plt.show(block=True)


def onclick(event):
    if event.xdata is not None and event.ydata is not None:
        circle = plt.Circle((event.xdata,
                             event.ydata), 2, color='r')
        fig = plt.gcf()
        fig.gca().add_artist(circle)
        plt.draw()
        # Change the contents of the plt window here


if __name__ == "__main__":
    plt.ion()
    img = np.ones((600, 800, 3))
    generate_panel(img)
person tmms    schedule 16.02.2016
comment
Как бы вы реализовали это для подзаголовков matplotlib, то есть вы хотите обновить конкретный подзаговор при вызове определенного метода? - person user3396592; 24.03.2016
comment
Я не совсем уверен в этом, возможно, это зависит от используемого вами бэкэнда. Я считаю, что matplotlib отображает весь холст каждый раз, когда вы вызываете функцию draw(). Вы можете поместить разные оси/графики в разные фигуры/полости и выборочно обновить их с помощью fig_n.canvas.draw(). Другой способ - поместить все подзаголовки на один и тот же холст/рисунок и выборочно обновлять их данные, но всегда отображать весь холст (все подзаголовки). - person tmms; 24.03.2016