【问题标题】:Python Matplotlib Update ScatterPython Matplotlib 更新散点图
【发布时间】:2016-11-18 22:08:04
【问题描述】:

我尝试编写一个简单的脚本来更新每个时间步的散点图t。我想尽可能简单地做到这一点。但它所做的只是打开一个我什么都看不见的窗口。窗口只是冻结。这可能只是一个小错误,但我找不到它。

data.dat 的格式为

                x      y
Timestep 1      1      2
                3      1
Timestep 2      6      3
                2      1

(文件只包含数字)

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

# Load particle positioins
with open('//home//user//data.dat', 'r') as fp:
    particles = []
    for line in fp:
        line = line.split() 
        if line:
            line = [float(i) for i in line]
            particles.append(line)

T = 100
numbParticles = 2

x, y = np.array([]), np.array([])

plt.ion()
plt.figure()
plt.scatter(x,y)
for t in range(T):
    plt.clf()
    for k in range(numbP):
            x = np.append(x, particles[numbParticles*t+k][0])
            y = np.append(y, particles[numbParticles*t+k][1])
    plt.scatter(x,y)
    plt.draw()
    time.sleep(1)
    x, y = np.array([]), np.array([])

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    制作动画最简单、最简洁的方法是使用matplotlib.animation module

    由于散点图返回matplotlib.collections.PathCollection,更新它的方法是调用它的set_offsets 方法。您可以将形状数组 (N, 2) 或 N 个 2 元组的列表传递给它——每个 2 元组是一个 (x,y) 坐标。

    例如,

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    T = 100
    numbParticles = 2
    particles = np.random.random((T,numbParticles)).tolist()
    x, y = np.array([]), np.array([])
    
    def init():
        pathcol.set_offsets([[], []])
        return [pathcol]
    
    def update(i, pathcol, particles):
        pathcol.set_offsets(particles[i])
        return [pathcol]
    
    fig = plt.figure()
    xs, ys = zip(*particles)
    xmin, xmax = min(xs), max(xs)
    ymin, ymax = min(ys), max(ys)
    ax = plt.axes(xlim=(xmin, xmax), ylim=(ymin, ymax))
    pathcol = plt.scatter([], [], s=100)
    
    anim = animation.FuncAnimation(
        fig, update, init_func=init, fargs=(pathcol, particles), interval=1000, frames=T, 
        blit=True, repeat=True)
    plt.show()
    

    【讨论】:

    • 我不需要循环吗?我看不到每个时间步的数字列表在哪里传递。你能解释一下吗?
    • 循环驻留在对FuncAnimation() 的调用中。对于每个时间步长(这里是每 1000 毫秒),函数 update 被调用,其增量值为 i
    • @ImportanceOfBeingErnest 我看不到i 在哪里增加。我希望像i=i+1 这样的东西。
    • @Samuel 正如我所说,循环在FuncAnimation() 内部,所以你看不到它。如果您愿意,可以查看source code(实际上那里没有循环,而是一个迭代器),但您也可以接受从外部看到的FuncAnimation(fig, update, interval=1000, frames=100) 将每1000 毫秒调用一次函数update 并且将 i 增加 1,直到 frames 给出的数字。
    • set_offsets 是我的关键。为什么 pyplot 不能有一个集中的接口来设置元素的数据:( ... like set_data()
    【解决方案2】:

    我终于找到了解决办法。您只需使用此脚本即可完成。我尽量保持简单:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.animation import FuncAnimation
    
    # Helps me to get the data from the file I want to plot
    N = 0
    
    # Load particle positioins
    with open('//home//user//data.dat', 'r') as fp:
        particles = []
        for line in fp:
            line = line.split() 
            particles.append(line)
    
    # Create new Figure and an Axes which fills it.
    fig = plt.figure(figsize=(7, 7))
    ax = fig.add_axes([0, 0, 1, 1], frameon=True)
    border = 100
    ax.set_xlim(-border, border), ax.set_xticks([])
    ax.set_ylim(-border, border), ax.set_yticks([])
    
    # particle data
    p = 18 # number of particles
    myPa = np.zeros(p, dtype=[('position', float, 2)])
    
    # Construct the scatter which we will update during animation
    scat = ax.scatter(myPa['position'][:, 0], myPa['position'][:, 1])
    
    def update(frame_number):
        # New positions
        myPa['position'][:] = particles[N*p:N*p+p]
    
        # Update the scatter collection, with the new colors, sizes and positions.
        scat.set_offsets(myPa['position'])
        increment()
    
    def increment():
        global N
        N = N+1
    
    # Construct the animation, using the update function as the animation director.
    animation = FuncAnimation(fig, update, interval=20)
    
    plt.show()
    

    【讨论】:

    • 如果这个例子很简单,显然 matplotlib 的这方面会遇到麻烦。
    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多