简体   繁体   English

在不阻塞控制台的情况下运行 matplotlib

[英]Run matplotlib without blocking the console

i try to make a dynamical plot in a method of a class.我尝试用 class 的方法制作动态 plot。 here is more or less the method这是或多或少的方法

def plot():
    axes = plt.gca(bock=False)
    ydata = []
    xdata = []

    axes.set_xlim(0, 200)
    axes.set_ylim(-1,1)
    line, = axes.plot(ydata, 'r-')

    i=0

    while True:

        xdata.append(i/10)
        ydata.append(np.sin(i/10))
        line.set_ydata(ydata)
        line.set_xdata(xdata)
        plt.draw()
        plt.pause(1e-17)
        i+=1
        plt.show()

The problem is the fact that it's an infinity loop and during this loop function, i can do nothing.问题是它是一个无限循环,在这个循环 function 期间,我无能为力。 i can't use my Ipython console.我不能使用我的 Ipython 控制台。 I would like make run this method without block the console.我想在不阻塞控制台的情况下运行此方法。 i arrived to do something like that using just print and threading but matplotlib dont support threading.我到达时只使用打印和线程来做类似的事情,但 matplotlib 不支持线程。 I tried using multiprocessing but that still block the console.我尝试使用多处理,但仍然阻塞控制台。 any options?有什么选择吗?

So there were many problems with this code.所以这段代码有很多问题。 First: that bock argument you passed to plt.gca() threw errors.首先:您传递给plt.gca()的那个bock参数引发了错误。 Second: plt.show() stops execution so the animation will not start.第二: plt.show()停止执行,因此 animation 不会启动。 To go around this problem you must trigger the animation after plt.show() was called.要围绕这个问题 go 必须在调用 plt.show() 后触发 animation。 One way to do it is making use of events.一种方法是利用事件。 You can read more about them here: https://matplotlib.org/3.2.1/users/event_handling.html Lastly, you can use a conditional and break to make sure the loop is not infinite.您可以在此处阅读有关它们的更多信息: https://matplotlib.org/3.2.1/users/event_handling.html最后,您可以使用条件和break来确保循环不是无限的。 Here is an example:这是一个例子:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
def plot(lim=100):
    """
    Parameters
    ----------
    lim -> int: Iteration where you want to stop
    """
    axes = plt.gca()#bock=False Was removed because it threw errors
    fig = plt.gcf()
    canvas = fig.canvas
    ydata = []
    xdata = []

    axes.set_xlim(0, 200)
    axes.set_ylim(-1,1)
    line, = axes.plot(xdata, ydata,'r-')

    #Now, we can't just start the loop because plt.show() will
    #Stop execcution. Instead we can make a trigger that starts
    #the loop. I will use a mouse event.
    def start_loop():
        i=0
        while True:
            xdata.append(i/10)
            ydata.append(np.sin(i/10))
            line.set_ydata(ydata)
            line.set_xdata(xdata)
            canvas.draw()
            canvas.flush_events()#This makes the updating less laggy
            plt.pause(1e-17)#Removable
            i+=1
            if i==lim:
                break
    canvas.mpl_connect("button_press_event",
                       lambda click: start_loop())
    #Click the plot to start the animation
    plt.show()
plot()

Furthermore, if you want faster execution, make use of blit or animation functions from matplotlib like FuncAnimation .此外,如果您想要更快的执行速度,请使用 matplotlib 中的blit或 animation 函数,例如FuncAnimation

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM