Как анимировать несколько столбцов как точки с помощью matplotlib из фрейма данных pandas с NaN в python - PullRequest
0 голосов
/ 09 октября 2018

У меня есть вопрос, который, возможно, задавался ранее, но я не смог найти ни одного поста, описывающего мою проблему.

У меня есть два кадра данных панд, каждый с одинаковым индексом, представляющих координаты x в одном кадре данных икоординаты у в другом.Каждый столбец представляет автомобиль, который запускал определенный временной шаг, регистрировал каждый шаг до его прибытия, а затем останавливал запись.

Каждый раз, когда автомобиль начинает свой маршрут, к каждому фрейму данных добавляется столбец, а координаты каждого шага добавляются в каждый фрейм (каждый шаг, который он проходит через пространство, имеет новые координаты x, y), (см.пример для кадра данных координат х)

enter image description here

Но я пытаюсь анимировать треки каждого автомобиля путем построения координат в анимированном графике, но яне могу заставить его работать.Мой код:

    %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 должен отображать точку (4.0, 6.0) (столбца 1).Кадр 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()

Но это не дает никакого вывода.Есть предложения?

1 Ответ

0 голосов
/ 10 октября 2018

Я переформатировал ваш код, но я думаю, что ваша основная проблема заключалась в том, что ваши кадры данных начинаются с индекса 1, но когда вы вызываете анимацию с frames=4, она вызывает update() с i=[0,1,2,3].Поэтому, когда вы делаете get_data_x(0), вы поднимаете KeyError: 'the label [0] is not in the [index]'

Согласно документации , frames= может быть передано итерируемо вместо 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()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...