我有一个可能是以前问过的问题,但是我找不到任何描述我的问题的帖子。
我有两个大熊猫数据框,每个都有相同的索引,分别代表一个数据框中的x坐标和另一个索引中的y坐标。每个列代表一辆汽车,该汽车开始一个特定的时间步,记录每个步直到到达,然后停止记录。
每当汽车在其路线上开始行驶时,都会在每个数据框中添加一列,并在每个帧中添加每一步的坐标(每步移动其槽空间的坐标都有新的x,y坐标),(请参见示例x坐标数据框)
但是我试图通过在动画图中绘制坐标来为每辆车的轨迹设置动画,但是我似乎无法使它起作用。我的代码:
%matplotlib notebook
from matplotlib import animation
from JSAnimation import IPython_display
from IPython.display import HTML
fig = plt.figure(figsize=(10,10))
#ax = plt.axes()
#nx.draw_networkx_edges(w_G,nx.get_node_attributes(w_G, 'pos'))
n_steps = simulation.x_df.index
def init():
graph, = plt.plot([],[],'o')
return graph,
def get_data_x(i):
return simulation.x_df.loc[i]
def get_data_y(i):
return simulation.y_df.loc[i]
def animate(i):
x = get_data_x(i)
y= get_data_y(i)
graph.set_data(x,y)
return graph,
animation.FuncAnimation(fig, animate, frames=100, init_func = init, repeat=True)
plt.show()
它不会绘制任何内容,因此非常感谢您的帮助。
编辑:示例最少,完整且可验证!
所以我有两个简单的x和y数据帧示例。每个都有相同的索引。
import random
import geopandas as gpd
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import math
import pandas as pd
from shapely.geometry import Point
from matplotlib import animation
from JSAnimation import IPython_display
%matplotlib inline
[IN]: df_x = pd.DataFrame(data=np.array([[np.NaN, np.NaN, np.NaN, np.NaN], [4, np.nan, np.NaN,np.NaN], [7, 12, np.NaN,np.NaN], [6, 18, 12,9]]), index= [1, 2, 3, 4], columns=[1, 2, 3, 4])
给予:
[OUT]
1 2 3 4
1 NaN NaN NaN NaN
2 4.0 NaN NaN NaN
3 7.0 12.0 NaN NaN
4 6.0 18.0 12.0 9.0
和y坐标数据框:
[IN] df_y = pd.DataFrame(data=np.array([[np.NaN, np.NaN, np.NaN, np.NaN], [6, np.nan, np.NaN,np.NaN], [19, 2, np.NaN,np.NaN], [4, 3, 1,12]]), index= [1, 2, 3, 4], columns=[1, 2, 3, 4])'
给予:
[OUT]
1 2 3 4
1 NaN NaN NaN NaN
2 6.0 NaN NaN NaN
3 19.0 2.0 NaN NaN
4 4.0 3.0 1.0 12.0
现在,我想通过绘制两个数据帧每一行的每一列的x坐标和y坐标来创建帧来创建动画。在此示例中,框架1不应包含任何绘图。第2帧应绘制(第1列的)点(4.0,6.0)。第3帧应标出点(7.0,19.0)(第1列)和点(12.0,2.0)(第2列)。框架4应该标出点(6.0,4.0)(第1列),点(18.0,3.0)(第2列),点(12.0,1.0)(第3列)和(9.0,12.0)列4。因此,我写了以下内容代码:
我尝试编写以下代码对此进行动画处理:
[IN] %matplotlib notebook
from matplotlib import animation
from JSAnimation import IPython_display
from IPython.display import HTML
fig = plt.figure(figsize=(10,10))
#ax = plt.axes()
graph, = plt.plot([],[],'o')
def get_data_x(i):
return df_x.loc[i]
def get_data_y(i):
return df_y.loc[i]
def animate(i):
x = get_data_x(i)
y= get_data_y(i)
graph.set_data(x,y)
return graph,
animation.FuncAnimation(fig, animate, frames=4, repeat=True)
plt.show()
但这不会提供任何输出。有什么建议吗?
答案 0 :(得分:1)
我已经重新格式化了代码,但我认为您的主要问题是数据帧以索引1开始,但是当您使用frames=4
调用动画时,它会使用update()
调用动画i=[0,1,2,3]
。因此,当您进行get_data_x(0)
时,您会举起KeyError: 'the label [0] is not in the [index]'
As per the documentation,frames=
传递给int而不是int。在这里,我只是传递数据帧的索引,函数将迭代并使用每个值调用update()
。实际上,我决定传递两个数据帧索引的交集,这样,如果一个数据帧中存在一个索引,而另一个数据帧中不存在,则不会引发错误。如果您保证两个索引相同,则可以执行frames=df_x.index
x_ = """ 1 2 3 4
1 NaN NaN NaN NaN
2 4.0 NaN NaN NaN
3 7.0 12.0 NaN NaN
4 6.0 18.0 12.0 9.0
"""
y_ = """1 2 3 4
1 NaN NaN NaN NaN
2 6.0 NaN NaN NaN
3 19.0 2.0 NaN NaN
4 4.0 3.0 1.0 12.0"""
df_x = pd.read_table(StringIO(x_), sep='\s+')
df_y = pd.read_table(StringIO(y_), sep='\s+')
fig, ax = plt.subplots(figsize=(5, 5))
graph, = ax.plot([],[], 'o')
# either set up sensible limits here that won't change during the animation
# or see the comment in function `update()`
ax.set_xlim(0,20)
ax.set_ylim(0,20)
def get_data_x(i):
return df_x.loc[i]
def get_data_y(i):
return df_y.loc[i]
def update(i):
x = get_data_x(i)
y = get_data_y(i)
graph.set_data(x,y)
# if you don't know the range of your data, you can use the following
# instructions to rescale the axes.
#ax.relim()
#ax.autoscale_view()
return graph,
# Creating the Animation object
ani = animation.FuncAnimation(fig, update,
frames=pd.Index.intersection(df_x.index,df_y.index),
interval=500, blit=False)
plt.show()