更新绘图中的for循环功能

时间:2019-01-29 23:11:14

标签: python-3.x matplotlib

我正在尝试调用以下示例中的函数,并在运行代码时绘图。我作为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)

UPDATE2: 我尝试使用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 :(得分:1)

如前所述,我建议使用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)