根据if条件(matplot animate python)对标记进行数字化更改

3zwjbxry  于 2023-06-25  发布在  Python
关注(0)|答案(2)|浏览(120)

我有一个点的列表,我转换成数组后,我想显示点与标记'o',如果点和移动的点之间的距离超过10,例如,点的标记从'o'到'*',我只是尝试这样做,但所有的标记改变不仅从节点谁是条件下的标记.有人能帮我吗
下面是一个没有移动的点的代码示例,我只是设置了一个静态条件,这是我的第一步,我想改变标记但不是所有的点,只对那些处于if条件下的点:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def createList(r1, r2):
    return [item for item in range(r1, r2+1)]

r1, r2 = 1, 50
mialistax=createList(r1, r2)
mialistay=createList(r1, r2)

fig, ax = plt.subplots()

import numpy as np
x_l=np.array(mialistax)
y_l = np.array(mialistay)

def animate(i):

    max_x= max(mialistax)
    max_y=max(mialistay)
    ax.clear()

    if (x_l[i]>10):
        mark='*'
    else:
        mark='o'

    ax.plot(x_l[i],y_l[i],marker=mark)
    ax.set_xlim([0,max_x])
    ax.set_ylim([0,max_y])
    plt.plot(x_l,y_l,marker=mark)

ani = FuncAnimation(fig, animate, frames=200, interval=500, repeat=False)

plt.show()

在这段代码中,所有点的标记都发生了变化,我希望标记只为那些在if条件下的点发生变化。

zfciruhq

zfciruhq1#

当你将frame设置为整数时,例如你所做的frames=200,那么range(200)将被传递给animate()函数,并且animate(i)的参数被视为函数定义中的整数,而不是range对象。相反,你可以设置一个迭代对象,比如python list或numpy array作为frame参数。请运行下面的代码来获得框架参数的想法:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def createList(r1, r2):
    return [item for item in range(r1, r2+1)]

r1, r2 = 1, 50
mialistax=createList(r1, r2)
mialistay=createList(r1, r2)

fig, ax = plt.subplots()

import numpy as np
x_l=np.array(mialistax)
y_l = np.array(mialistay)

def animate(i):

    max_x= max(mialistax)
    max_y=max(mialistay)
    ax.clear()

    if (x_l[i]>10):
        mark='*'
    else:
        mark='o'

    ax.plot(x_l[i],y_l[i],marker=mark)
    ax.set_xlim([0,max_x])
    ax.set_ylim([0,max_y])
    plt.plot(x_l,y_l,marker=mark)

ani = FuncAnimation(fig, animate, frames=[5,15], interval=500, repeat=True)

plt.show()
xuo3flqw

xuo3flqw2#

如果我对这个问题的理解是正确的,您需要一个显示所有点的动画,但是如果索引i(帧编号)处的点的x值大于10,则应将其转换为"*"标记。
首先,你有三个问题。第一个是你阴谋的顺序。

ax.plot(x_l[i], y_l[i], marker=mark)
ax.plot(x_l, y_l, marker=mark)

这意味着您首先绘制单个点,然后在顶部绘制其余点。所以你不会看到你的“特殊”点,因为它被其他点掩盖了。
第二个问题是您为两个图设置了相同的标记(单个点和其余点)。我将创建一个所有标记的列表,如果满足条件,则更新索引i处的标记。然后,循环遍历所有点并分别绘制它们(因为无法传递标记列表)。您可能希望您的“特殊”点突出,这样我们就可以将其显示为不同的颜色。

markers = ["o"]*len(x_l)

def animate(i):
    max_x = max(x_l)
    max_y = max(y_l)
    ax.clear()

    if x_l[i] > 10:
        markers[i] = '*'

    ax.set_xlim([0, max_x])
    ax.set_ylim([0, max_y])
    
    for indx, (x, y, marker) in enumerate(zip(x_l, y_l, markers)):
        color = "tab:orange" if indx == i else "tab:blue"
        ax.plot(x, y, marker=marker, color=color)

最后,你只有50个点,但是有frames=200,所以你需要增加你的点或减少帧的数量来匹配。

ani = FuncAnimation(fig, animate, frames=len(x_l), interval=5, repeat=False)

我假设你是Python新手,所以我还将提出其他建议来改进你的代码。
1.您可以使用list函数直接从range创建列表:list(range(start, stop))。因为你要将它转换为numpy数组,所以有一个numpy函数:np.arange(start, stop)
1.对于numpy数组,你可以使用max方法:x_l.max(),虽然这个变化并不重要。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation

plt.close("all")

r1 = 1
r2 = 50
x_l = np.arange(r1, r2+1)
y_l = np.arange(r1, r2+1)

fig, ax = plt.subplots()

markers = ["o"]*x_l.shape[0]

def animate(i):
    max_x = x_l.max()
    max_y = y_l.max()
    ax.cla()
    
    if x_l[i] > 10:
        markers[i] = '*'
    
    for indx, (x, y, marker) in enumerate(zip(x_l, y_l, markers)):
        color = "tab:orange" if indx == i else "tab:blue"
        ax.plot(x, y, marker=marker, color=color)
        
    ax.set_xlim([0, max_x])
    ax.set_ylim([0, max_y])

ani = FuncAnimation(fig, animate, frames=x_l.shape[0], interval=500, repeat=False)
fig.show()

相关问题