Запустите matplotlib, не блокируя консоль - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь сделать динамический сюжет в методе класса. вот более или менее метод

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()

Проблема в том, что это бесконечность l oop, и во время этой функции l oop я ничего не могу сделать. Я не могу использовать свою консоль I python. Я бы хотел запустить этот метод без блокировки консоли. я прибыл, чтобы сделать что-то подобное, используя только печать и потоки, но matplotlib не поддерживает потоки. Я пробовал использовать многопроцессорность, но это все еще блокирует консоль. любые варианты?

1 Ответ

0 голосов
/ 19 июня 2020

Значит, с этим кодом было много проблем. Во-первых: аргумент bock, который вы передали в plt.gca(), вызывал ошибки. Во-вторых: plt.show() останавливает выполнение, поэтому анимация не запускается. Чтобы go обойти эту проблему, вы должны запустить анимацию после вызова plt.show (). Один из способов сделать это - использовать события. Вы можете узнать о них больше здесь: https://matplotlib.org/3.2.1/users/event_handling.html Наконец, вы можете использовать условное выражение и break, чтобы убедиться, что l oop не бесконечно. Вот пример:

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()

Кроме того, если вы хотите более быстрое выполнение, используйте blit или функции анимации из matplotlib, например FuncAnimation.

...