Обновление графика для цикла в функции - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь вызвать функцию, как в примере ниже, и построить график во время выполнения кода.Реальные значения, которые я получаю как y-данные, на самом деле не являются случайными числами, но дело в том, что мне бы хотелось, чтобы они обновлялись в реальном времени.График в моем примере кода ниже просто пустой и не обновляется.

import numpy as np
import matplotlib.pyplot as plt
import random as rnd
import time

initial_time = time.time()

def multiple_runs(number_of_runs):
    x_data, y_data = [], []
    fig, ax = plt.subplots()
    sc = ax.scatter(x_data, y_data)
    plt.draw()

    for i in range(0, number_of_runs):
        x_data.append(i+1)
        y_data.append(rnd.randint(0,100))
        sc.set_offsets(np.c_[x_data, y_data])
        fig.canvas.draw_idle()
        plt.pause(0.1)

        print ('Total time after run number ' + str(i+1) + ': ' + str(time.time() - initial_time))

multiple_runs(100)

ОБНОВЛЕНИЕ: Спасибо @ImportanceOfBeingErnest, я получил код для работы.Однако моя проблема сейчас заключается в том, что фигура закрывается, как только она закончена, есть ли способ сохранить ее открытой?Я пытался использовать plt.waitforbuttonpress(), но я получаю странную ошибку от QTimer, не знаю, как и почему.Это мой рабочий пример кода:

import numpy as np
import matplotlib.pyplot as plt
import random as rnd
import time

initial_time = time.time()

def multiple_runs(number_of_runs):
    x_data, y_data = [], []
    x_data2, y_data2 = [], []
    fig, ax = plt.subplots(2, sharex = True)
    sc = ax[0].scatter(x_data, y_data)
    sc2 = ax[1].scatter(x_data2, y_data2)
    ax[0].set(xlim=(0,100), ylim=(0,100))
    ax[1].set(xlim=(0,100), ylim=(0,100))
    plt.draw()

    for i in range(0, number_of_runs):
        x_data.append(i+1)
        y_data.append(rnd.randint(0,100))
        x_data2.append(i+1)
        y_data2.append(rnd.randint(0,100))
        sc.set_offsets(np.c_[x_data, y_data])
        sc2.set_offsets(np.c_[x_data2, y_data2])
        fig.canvas.draw_idle()
        plt.pause(0.1)

        print ('Total time after run number ' + str(i+1) + ': ' + str(time.time() - initial_time))

multiple_runs(100)

ОБНОВЛЕНИЕ2: Я пытался использовать FuncAnimation, но получаю ошибку TypeError: update() missing 2 required positional arguments: 'y' and 'y2'.Мне все еще нужно использовать for-loop, потому что в моем реальном коде я использую предыдущие значения y, чтобы вычислить следующие значения y.Это мой пример кода, который дает мне ошибку;

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random as rnd
import time

initial_time = time.time()

def multiple_runs(number_of_runs):
    x_data, y_data = [], []
    x_data2, y_data2 = [], []
    fig, ax = plt.subplots(2, sharex = True)
    sc = ax[0].scatter(x_data, y_data)
    sc2 = ax[1].scatter(x_data2, y_data2)
    ax[0].set(xlim=(0,100), ylim=(0,100))
    ax[1].set(xlim=(0,100), ylim=(0,100))

    def update(i, y, y2):
        x_data.append(i+1)
        y_data.append(y)
        x_data2.append(i+1)
        y_data2.append(y2)
        sc.set_offsets(np.c_[x_data, y_data])
        sc2.set_offsets(np.c_[x_data2, y_data2])
        print ('Total time after run number ' + str(i+1) + ': ' + str(time.time() - initial_time))


    for i in range(0, number_of_runs):
        y = rnd.randint(0,100)
        y2 = rnd.randint(0,100)
        update(i,y,y2)

    ani = FuncAnimation(fig, update, frames=number_of_runs, interval=100, repeat=False)
    plt.show()

multiple_runs(100)

1 Ответ

0 голосов
/ 30 января 2019

Как прокомментировано, я бы рекомендовал использовать FuncAnimation.Это будет выглядеть следующим образом в вашем случае.Обратите внимание, что для закрытия окна необходимо нажать q или закрыть его мышью.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random as rnd
import time

initial_time = time.time()

def multiple_runs(number_of_runs):
    x_data, y_data = [], []
    x_data2, y_data2 = [], []
    fig, ax = plt.subplots(2, sharex = True)
    sc = ax[0].scatter(x_data, y_data)
    sc2 = ax[1].scatter(x_data2, y_data2)
    ax[0].set(xlim=(0,100), ylim=(0,100))
    ax[1].set(xlim=(0,100), ylim=(0,100))

    def get_ydata(i):
        y = rnd.randint(0,100)
        y2 = rnd.randint(0,100)
        return y, y2

    def update(i):
        y, y2 = get_ydata(i)
        x_data.append(i+1)
        y_data.append(y)
        x_data2.append(i+1)
        y_data2.append(y2)
        sc.set_offsets(np.c_[x_data, y_data])
        sc2.set_offsets(np.c_[x_data2, y_data2])

    ani = FuncAnimation(fig, update, frames=number_of_runs, interval=100, repeat=False)
    plt.show()

multiple_runs(100)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...