如何在python中使用NaN使用Matplotlib将pandas数据框中的matplotlib动画为点 [英] How to Animate multiple columns as dots with matplotlib from pandas dataframe with NaN in python

查看:97
本文介绍了如何在python中使用NaN使用Matplotlib将pandas数据框中的matplotlib动画为点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可能是以前问过的问题,但是我找不到任何描述我的问题的帖子。



我有两个熊猫数据框,每个框都相同索引,在一个数据帧中表示x坐标,在另一数据帧中表示y坐标。每个列代表一辆汽车,该汽车开始一个特定的时间步,记录每个步直到到达,然后停止记录。



每当汽车在其路线上启动时,都会在每个数据框中添加一列,并在每个帧中添加每一步的坐标(每步移动其槽空间的位置都有新的x,y坐标),(请参见x坐标数据框的示例)





但是我试图通过在动画图中绘制坐标来动画化每辆车的轨迹,但是我似乎无法使它起作用。我的代码:

 %matplotlib笔记本
从matplotlib导入动画
从JSAnimation导入IPython_display
从IPython.display导入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():
图, = plt.plot([],[],'o')
返回图,

def get_data_x(i):
返回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(figAnimation) ,帧数= 100,init_func = init,重复= True)

plt.show()

它不会打印任何内容,因此非常感谢您的帮助。






编辑:最小,完整和可验证的示例!



所以我有两个x和y数据帧的简单示例。每个索引都有相同的索引。

 导入随机
导入geopandas为gpd
导入networkx为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
从JSAnimation导入IPython_display
$ matplotlib内联



[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]]),索引= [1、2、3、4],列= [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]]),索引= [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。因此,我写了以下内容代码:



我尝试编写以下代码对此进行动画处理:

  [输入]来自matplotlib的%matplotlib笔记本
从JSAnimation导入动画
从IPython.import导入IPython_display
从displayPython导入HTML

图= plt.figure(figsize =( 10,10))
#ax = plt.axes()

图,= plt.plot([],[],'o')

def get_data_x(i):
返回df_x.loc [i]

def get_data_y(i):
返回df_y.loc [i]


def animate(i):
x = get_data_x(i)
y = get_data_y(i)
图.set_data(x,y)
返回图,

animation.FuncAnimation(图,动画,帧= 4,重复=真实)
plt.show()

但这不会提供任何输出。有任何建议吗?

解决方案

我已经重新格式化了代码,但是我认为您的主要问题是数据帧以索引开头1,但是当您使用 frames = 4 调用动画时,它会使用<$ c调用 update() $ c> i = [0,1,2,3] 。因此,当您执行 get_data_x(0)时,会引发 KeyError:'标签[0]不在[index]中




I have a question that maybe is asked before, but I couldn't find any post describing my problem.

I have two pandas dataframes, each with the same index, representing x coordinates in one dataframe and y coordinates in the other. Each colum represent a car that started a specific timestep, logged every step until it arrived, and then stopped logging.

Everytime a car starts on its route, a column is added to each dataframe and the coordinates of each step are added to each frame (every step it moves trough space therefor has new x,y coordinates), (see example for the x coordinates dataframe)

But I am trying to animate the tracks of each car by plotting the coordinates in an animated graph, but I cannot seem to get it worked. My code:

    %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()

It does not plot anything, so any help would be very much appreciated.


EDIT: Minimal, Complete, and Verifiable example!

So two simple examples of the x and y dataframes that I have. Each has the same index.

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])

gives:

[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

And the y coordinate dataframe:

[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])'

gives:

[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

Now I want to create an animation, by creating a frame by plotting the x coordinate and the y coordinate of each column per each row of both dataframes. In this example, frame 1 should not contain any plot. Frame 2 should plot point (4.0 , 6.0) (of column 1). Frame 3 should plot point (7.0,19.0) (column1) and point (12.0,2.0) (column 2). Frame 4 should plot point (6.0, 4.0) (column 1), point (18.0,3.0) (column 2), point (12.0,1.0) (column 3) and (9.0, 12.0) column 4. Therefore I wrote the following code:

I tried writing the following code to animate this:

  [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()

But this does not give any output. Any suggestions?

解决方案

I've reformatted your code, but I think your main issue was that your dataframes start with a index of 1, but when you're calling your animation with frames=4, it's calling update() with i=[0,1,2,3]. Therefore when you do get_data_x(0) you raise a KeyError: 'the label [0] is not in the [index]'

As per the documentation, frames= can be passed an iterable instead of an int. Here, I simply pass the index of your dataframe, and the function will iterate and call update() with each value. Actually, I decided to pass the intersection of your two dataframe indexes, that way, if there is one index present in one dataframe but not the other, it will not raise an Error. If you are garanteed that your two indexes are the same, then you could just do 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()

这篇关于如何在python中使用NaN使用Matplotlib将pandas数据框中的matplotlib动画为点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆