【问题标题】:PyCharm matplotlib interactive figures without blocking executionPyCharm matplotlib 交互式图形不阻塞执行
【发布时间】:2017-06-23 16:08:32
【问题描述】:

我阅读了很多关于此主题的堆栈溢出问题,但经过大量实验后,我无法弄清楚我的问题。

我在 Windows 7 上使用 PyCharm 2016.3.2(但我在 OSX 上遇到同样的问题),我的解释器是 Python 3.6 和 matplotlib 2.0.0 的最新版本的 Anaconda。

这是我试图实现的目标(也许我没有使用正确的方法,因为我试图重新创建我在 Octave/Matlab 中习惯的行为):

  1. 在弹出窗口中绘制一个图形
  2. 暂停我的脚本(input("press a key to continue"))
  3. 观察图形,然后按一个键继续脚本
  4. 计算其他东西
  5. 在同一个图上绘制新数据
  6. 暂停我的脚本(input("press a key to continue"))
  7. 观察图形,然后按一个键继续脚本

这是我的测试代码:

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

print('Plotting Data...')

plt.ion()
plt.figure(1)
plt.plot([1, 5, 10, 20], [1, 5, 10, 20])
plt.xlabel('x label')
plt.ylabel('y label')
plt.show()
plt.pause(0.0001)

input('Plotting Data done..., Press a key to continue')

plt.figure(1)
plt.plot([1, 5, 10, 20], [2, 10, 20, 40])
plt.show()
plt.pause(0.0001)

input('Program paused. Press enter to end.\n')

这是我想要的最接近的版本,当我将鼠标悬停在图上时,图是正确的但没有响应(plt.pause(0.0001) 会生成警告,但代码有效)。

我经常使用参数 (plt.ion() ; plt.pause() ; plt.show(block=False))。 大多数情况下,这会导致绘图窗口为空,或者我需要关闭窗口才能继续执行。

感谢您的帮助!

【问题讨论】:

  • 您不能同时在两个不同的事件循环中工作。为什么不能以正常方式绘制所有内容并使用窗口关闭作为程序继续的触发器?
  • 正常方式?如果我使用关闭窗口作为继续的触发器,即使我记得图(1),我也找不到在第一个元素之上绘制第二个元素的方法(没有重做 plt.plot 与第一个数据集)。但有时我只想做多个情节,让它们都打开,直到执行结束。谢谢!
  • @ImportanceOfBeingErnest 这篇文章正在查看相同的问题Similar question,它基本上使用相同的解决方法,但暂停(数字绘制正确但无响应)
  • 链接问题中接受的答案对您有用吗?在我的例子中,它的作用与此处相同:输入阻塞了窗口事件循环,从而变得无响应。
  • @ImportanceOfBeingErnest 你是对的,我有这种行为,情节是正确的,但在一个无响应的窗口中。我认为试图模仿 Matlab 的做法不是正确的方法。因此,我可以在非交互模式下执行此操作并等待所有数据,然后将所有内容绘制在一个图中(然后关闭它),或者如果我想在执行结束时查看所有图,则将它们保存在文件中。非常感谢您的帮助!

标签: python matplotlib pycharm


【解决方案1】:

一旦plt.show() 被调用,主循环就会被窗口接管。因此,一旦调用了input,主循环就会变得无响应。

您可以尝试停留在 GUI 循环中并在那里处理按键操作。

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

print('Plotting Data...')

fig, ax = plt.subplots()
ax.set_xlabel('x label')
ax.set_ylabel('y label')
i=[0]

def f1():
    ax.plot([1, 5, 10, 20], [1, 5, 10, 20])

def f2():
    ax.plot([1, 5, 10, 20], [2, 10, 20, 40])

def f3():
    ax.plot([1, 5, 10, 20], [5, 9, 17, 28])


def update(event=None):
    if i[0]==0: f1()
    if i[0]==1: f2()
    if i[0]==2: f3()
    fig.canvas.draw_idle()
    i[0]+=1
    print('Step {} done..., Press a key to continue'.format(i[0]))

fig.canvas.mpl_connect("key_press_event", update)    

update()
plt.show()

【讨论】:

  • 感谢您的回答。我正在熟悉 pyplot OO 合成器,并且必须更多地了解 darw_idle。
    这样做的另一种方法是再次调用一个封闭的绘图(要么重新显示它最初的样子,要么添加数据以显示除初始数据之外的新数据)但我还不明白该怎么做那
猜你喜欢
  • 2018-07-04
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 2012-07-30
  • 2017-10-26
  • 1970-01-01
  • 2019-10-30
  • 2018-04-28
相关资源
最近更新 更多