在for循环中动态更新网格中的项目(Python)

2024-09-28 21:30:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在for循环中动态更新一个绘图,但我无法使它工作。不知道有没有人能帮忙?你知道吗

我在传递图形和轴以及如何更新之间有点困惑。我一直想用

display.clear_output(wait=True)
display.display(plt.gcf())
time.sleep(2)

但它没有做我想做的。你知道吗

我想: 1向网格添加对象(setupGrid2) 2在一个时间步-随机移动每个对象(makeMove2) 三。在网格上直观地更新每个对象的位置(updateGrid2)

我的问题是3。我想清除上一步,以便只显示每个对象的新位置。目标是显示在网格中动态移动的对象。你知道吗

我还想使用setupGrid2中创建的ax对象,这样我就可以在一个地方设置绘图变量(标题、图例等)并更新该图表。你知道吗

谢谢你的帮助。你知道吗

下面的示例代码(用于在jupyter笔记本中运行):

 %matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import time
import pylab as pl
from IPython import display


def setupGrid2(norows,nocols,noobjects):
    #each object needs current grid position (x and y coordinate)
    objects = np.zeros(noobjects)
    ObjectPos = np.zeros(shape=(noobjects,2))

    #put objects randomly on grid
    for i in range (noobjects):
        ObjectPos[i][0] = np.random.uniform(0,norows)
        ObjectPos[i][1] = np.random.uniform(0,nocols)

    #plot objects on grid
    fig = plt.figure(1,figsize=(15,5))
    ax = fig.add_subplot(1,1,1)
    x,y  = zip(*ObjectPos)
    ax.scatter(x, y,c="b", label='Initial positions')
    ax.grid()
    plt.show()

    return ax,ObjectPos

def updateGrid2(ax,ObjPos):
    x,y  = zip(*ObjPos)
    plt.scatter(x, y)
    display.clear_output(wait=True)
    display.display(plt.gcf())
    time.sleep(0.1)

#move object in a random direction
def makeMove2(object,xpos,ypos):
    #gets a number: 1,2,3 or 4
    direction = int(np.random.uniform(1,4))

    if (direction == 1):
        ypos = ypos+1
    if (direction == 2):
        ypos = ypos - 1
    if (direction == 3):
        xpos = xpos+1
    if (direction == 4):
        xpos = xpos-1
    return xpos,ypos

def Simulation2(rows,cols,objects,steps):

    ax,ObjPos = setupGrid2(rows,cols,objects)

    for i in range(steps):
        for j in range (objects):
            xpos = ObjPos[j][0]
            ypos = ObjPos[j][1]
            newxpos,newypos = makeMove2(j,xpos,ypos)
            ObjPos[j][0] = newxpos
            ObjPos[j][1] = newypos
            updateGrid2(ax,ObjPos)

Simulation2(20,20,2,20) 

Tags: 对象importforobjectsdefdisplaynpplt
1条回答
网友
1楼 · 发布于 2024-09-28 21:30:45

似乎您希望更新散点,而不是为每个帧生成新的散点。这将在这个问题中体现出来。当然,在jupyter中运行时,您仍然可以使用display,而不是使用funcion或animation显示的解决方案。你知道吗

让问题中的代码保持原封不动,这可能如下所示。你知道吗

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import time
import pylab as pl
from IPython import display


def setupGrid2(norows,nocols,noobjects):
    #each object needs current grid position (x and y coordinate)
    objects = np.zeros(noobjects)
    ObjectPos = np.zeros(shape=(noobjects,2))

    #put objects randomly on grid
    for i in range (noobjects):
        ObjectPos[i,0] = np.random.uniform(0,norows)
        ObjectPos[i,1] = np.random.uniform(0,nocols)

    #plot objects on grid
    fig = plt.figure(1,figsize=(15,5))
    ax = fig.add_subplot(1,1,1)
    ax.axis([0,nocols+1,0,norows+1])
    x,y  = zip(*ObjectPos)
    scatter = ax.scatter(x, y,c="b", label='Initial positions')
    ax.grid()

    return ax,scatter,ObjectPos

def updateGrid2(ax,sc,ObjPos):
    sc.set_offsets(ObjPos)
    display.clear_output(wait=True)
    display.display(plt.gcf())
    time.sleep(0.1)

#move object in a random direction
def makeMove2(object,xpos,ypos):
    #gets a number: 1,2,3 or 4
    direction = int(np.random.uniform(1,4))

    if (direction == 1):
        ypos = ypos+1
    if (direction == 2):
        ypos = ypos - 1
    if (direction == 3):
        xpos = xpos+1
    if (direction == 4):
        xpos = xpos-1
    return xpos,ypos

def Simulation2(rows,cols,objects,steps):

    ax,scatter,ObjPos = setupGrid2(rows,cols,objects)

    for i in range(steps):
        for j in range (objects):
            xpos = ObjPos[j,0]
            ypos = ObjPos[j,1]
            newxpos,newypos = makeMove2(j,xpos,ypos)
            ObjPos[j,0] = newxpos
            ObjPos[j,1] = newypos
        updateGrid2(ax,scatter,ObjPos)

Simulation2(20,20,3,20)

相关问题 更多 >