朱莉娅与Pyplot - 窗口锁定

3

你好,

我正在使用Julia中的PyPlot包,并且遇到了一个问题,但是没有找到解决方案。

基本上,我想在迭代计算期间更新绘图窗口。(我不使用Atom的绘图面板,而是使用带有交互式缩放、平移等控件的外部类似于matplotlib的绘图窗口。)

我的代码大致如下:

import PyPlot
const plt = PyPlot
ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)
...
while (x < y)
    ... calculation of x and y...
    ax1.plot(x)
    ax2.plot(y)
end

这个程序大致按照预期工作:一开始打开一个窗口,里面包含所有子图但没有曲线。一旦计算开始,它会绘制出我的曲线,我就可以看到它们了。目前为止,一切都很好。然而,在计算进行过程中,窗口会被锁定,我无法使用“交互式”工具。一旦迭代完成,它将更新绘图,并执行在“锁定”期间输入的任何操作。但实际上,这就像是在得到响应之前停顿了10秒钟(或更长时间,取决于迭代需要多长时间)。

有没有办法让窗口在计算运行时保持响应,还是这是一个内置的冻结,无法预防?

感谢任何提示,如果这是重复问题,请原谅。

最好, pohly

1个回答

3

如果我正确理解了您的问题,您可以使用pause函数之一的方法:

help?> plt.pause

Pause for *interval* seconds.

If there is an active figure, it will be updated and displayed before the
pause, and the GUI event loop (if any) will run during the pause.

This can be used for crude animation.  For more complex animation, see
:mod:`matplotlib.animation`.

Notes
-----
This function is experimental; its behavior may be changed or extended in a
future release.

以下是一个示例代码:

import PyPlot

const plt = PyPlot

ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)

x = rand(1)
y = rand(1)
for i in 1:100
    push!(x, rand())
    push!(y, rand())
    ax1.plot(x)
    ax2.plot(y)
    plt.pause(0.01)
end

您希望的是这个吗?

编辑

如果您的计算较为复杂,可以使用多线程来获取所需结果。以下是一个示例(函数f计算量较大,应在单独的线程中运行):

import PyPlot

function f()
    for i in 1:10^9 # just run some expensive task
        rand()
    end
    return rand()
end

const plt = PyPlot

ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)

x = rand(1)
y = rand(1)
for i in 1:10
    t = Threads.@spawn f()
    push!(x, fetch(t))
    push!(y, rand())
    ax1.plot(x)
    ax2.plot(y)
    plt.pause(0.0001)
end

你好,我认为这个方向是正确的,但并不是真正的解决方案。我尝试了你的建议,当然可以使用plt.pause(2),这样我就有2秒钟来玩弄我的图表,但是这会锁定计算。因此,要么是Julia在计算,而绘图窗口无响应,要么是绘图窗口响应,而在Julia中运行的计算被冻结。我想要的是Julia在计算时将数据发送到Pyplot,但不会在此过程中锁定绘图窗口。 - pohly
1
我已经添加了一个示例,展示如何为计算创建一个单独的线程。只需确保使用至少2个线程启动Julia即可。现在,即使在单独的线程中进行计算,图形也将保持响应。 - Bogumił Kamiński

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接