Создание новых графиков для получения пользовательского ввода в цикле и сохранение другого открытым для обновления статистики с помощью matplotlib

#python #matplotlib

#python #matplotlib

Вопрос:

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

В частности:

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

Поскольку программа, которую я делаю, имеет несколько классов ( PlotA созданных одним классом и PlotB другим), я обобщу ее с помощью этого простого конвейера:

 for new input X from folder:
    plotA(X)  # new plot is created for an input X, user clicks on subplots in plotA
    update_plotB()
 

где:

 def plotA(X):
    # do computation on X
    fig, ax = plt.subplots(nrows..., ncols=..., figsize=(...))
    ...plotting stuff...
    plt.show()
 

и

 def update_plotB():
    fig, ax = plt.subplots(num='plotB', ncols=..., nrows=..., figsize=...)  # I set an ID for plotB
    for row, col:
         ax[row, col].plot(...)   # update the statistics in each subplot
    plt.show()
 

Поэтому я хочу, чтобы PlotA для каждого нового ввода создавался новый, блокирующий программу до тех пор, пока пользователь сам не закроет график, после чего подзаголовки PlotB обновляются / перерисовываются с новыми ответами.

Что я пробовал до сих пор (после прочтения множества тем на SO):

(1) Использование plt.ion()

Я помещаю plt.ion() в начало программы. Но в итоге все графики были показаны сразу, не блокируя программу для ввода пользователем PlotA (код выполняется слишком быстро, программа заканчивается до того, как я смогу увидеть что-либо на графике).

(2) Использование plt.show(block=False) в update_plotB()

Это работает нормально только один раз (то PlotB есть отображается без блокировки на 1-й итерации), но затем PlotB блокируется на всех следующих итерациях, что я нахожу действительно странным, но не знаю почему.

(3) Замена plt.show() на update_plotB plt.draw() или plt.pause(0.05) (без plt.ion() )

PlotB блокирует выполнение до тех пор, пока я его не закрою, затем PlotB на каждой итерации создается новое.


Надеюсь, я объяснил это достаточно ясно. Заранее большое вам спасибо!