在python'中为同一绘图上的两行设置动画;s matplotlib

在python'中为同一绘图上的两行设置动画;s matplotlib,python,pandas,dataframe,matplotlib,animation,Python,Pandas,Dataframe,Matplotlib,Animation,我试图在同一个情节上设置两条线的动画。在四处搜索之后,我发现这似乎让我走上了正确的道路。当我运行此代码时,停滞的图形显示为没有动画,这给了我一个错误AttributeError:'AxesSubplot'对象没有属性“set\u data”。我查了一下set_data,它说它“接受:二维数组(行是x,y)或两个一维数组”。由于我将line1和line2指定给绘图而不是2D阵列,动画是否不起作用?如果能帮我在我的情节中设置这些线条的动画,我将不胜感激,我已经试过了,但都没有用。谢谢 fig, ax

我试图在同一个情节上设置两条线的动画。在四处搜索之后,我发现这似乎让我走上了正确的道路。当我运行此代码时,停滞的图形显示为没有动画,这给了我一个错误
AttributeError:'AxesSubplot'对象没有属性“set\u data”
。我查了一下
set_data
,它说它“接受:二维数组(行是x,y)或两个一维数组”。由于我将
line1
line2
指定给绘图而不是2D阵列,动画是否不起作用?如果能帮我在我的情节中设置这些线条的动画,我将不胜感激,我已经试过了,但都没有用。谢谢

fig, ax = plt.subplots(figsize=(16,8))

#Plot Lines
line1 = sns.lineplot('game_seconds_remaining', 'away_wp', data=game, color='#4F2683',linewidth=2)
line2 = sns.lineplot('game_seconds_remaining', 'home_wp', data=game, color='#869397',linewidth=2)
#Add Fill
ax.fill_between(game['game_seconds_remaining'], 0.5, game['away_wp'], where=game['away_wp']>.5, color = '#4F2683',alpha=0.3)
ax.fill_between(game['game_seconds_remaining'], 0.5, game['home_wp'], where=game['home_wp']>.5, color = '#869397',alpha=0.3)


#Plot Aesthetics - Can Ignore
plt.ylabel('Win Probability %', fontsize=16)
plt.xlabel('', fontsize=16)
plt.axvline(x=900, color='white', alpha=0.7)
plt.axvline(x=1800, color='white', alpha=0.7)
plt.axvline(x=2700, color='white', alpha=0.7)
plt.axhline(y=.50, color='white', alpha=0.7)
plt.suptitle('Minnesota Vikings @ Dallas Cowboys', fontsize=20, style='italic',weight='bold')
plt.title('Min 28, DAL 24 - Week 10 ', fontsize=16, style = 'italic',weight='semibold')


#Labels (And variable assignment for animation below)
x = ax.set_xticks(np.arange(0, 3601,900))
y1 = game['away_wp']
y2 = game['home_wp']
plt.gca().invert_xaxis()
x_ticks_labels = ['End','End Q3','Half','End Q1','Kickoff']
ax.set_xticklabels(x_ticks_labels, fontsize=12)


#Animation - Not working
def update(num, x, y1, y2, line1, line2):
    line1.set_data(x[:num], y1[:num])
    line2.set_data(x[:num], y2[:num])
    return [line1,line2]

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y1, y2, line1, line2],
                  interval=295, blit=False)

似乎
sns
给出了
AxesSublot
,您必须为此
轴获得

ax1 = sns.lineplot(...)
ax2 = sns.lineplot(...)

line1 = ax1.lines[0]
line2 = ax2.lines[1]
sns.lineplot(x=x, y='away_wp', data=game)
sns.lineplot(x=x, y='home_wp', data=game)

ax = plt.gca()

line1 = ax.lines[0]
line2 = ax.lines[1]
或(因为两行位于相同的
轴上)


编辑:

对于
googlecolab
它需要

from matplotlib import rc
rc('animation', html='jshtml')

# code without `plt.show()`

ani   # display it
资料来源:


随机数据的最小工作码

import random
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation
from matplotlib import rc
rc('animation', html='jshtml')

game = pd.DataFrame({
    'away_wp': [random.randint(-10,10) for _ in range(100)],
    'home_wp': [random.randint(-10,10) for _ in range(100)],
    'game_seconds_remaining': list(range(100)),
})

x = range(len(game))
y1 = game['away_wp']
y2 = game['home_wp']

fig = plt.gcf()
ax = plt.gca()

sns.lineplot(x='game_seconds_remaining', y='away_wp', data=game)
sns.lineplot(x='game_seconds_remaining', y='home_wp', data=game)

line1 = ax.lines[0]
line2 = ax.lines[1]

ax.fill_between(game['game_seconds_remaining'], 0.5, game['away_wp'], where=game['away_wp']>.5, color = '#4F2683',alpha=0.3)
ax.fill_between(game['game_seconds_remaining'], 0.5, game['home_wp'], where=game['home_wp']>.5, color = '#869397',alpha=0.3)
#print(ax.collections)

def update(num, x, y1, y2, line1, line2):
    line1.set_data(x[:num], y1[:num])
    line2.set_data(x[:num], y2[:num])

    ax.collections.clear()
    ax.fill_between(game['game_seconds_remaining'][:num], 0.5, game['away_wp'][:num], where=game['away_wp'][:num]>.5, color = '#4F2683',alpha=0.3)
    ax.fill_between(game['game_seconds_remaining'][:num], 0.5, game['home_wp'][:num], where=game['home_wp'][:num]>.5, color = '#869397',alpha=0.3)

    return line1,line2

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y1, y2, line1, line2], interval=295, blit=False)

#plt.show()

ani   # display it

编辑:

同样,没有
seaborn
,但只有
plt.plot()

开始时,我创建空行
line1,=plt.plot([],[])


仅当您使用
matplotlib
函数绘制线条时,它才起作用-即
plt.plot()
seaborn
可能需要更多代码才能从
AxeSubPlot
@furas plt.plot()获取行。plot()仍然返回您执行的非动画GraphId
line1,=plt.plot(…)
,而不是
sns.lineplot()
?@furas正确。也尝试了
ax.plot(…)
。请稍候,
line1,=plt.plot(…)
line1=plt.plot(…)
返回不同的内容。带逗号的那个把事情搞砸了。两者都没有动画。我复制了这段代码,得到了一个没有动画的空白绘图。如果这很重要的话,我现在在google colab中。我正常运行它
python script.py
。我从来没有尝试过在谷歌Colab上这样做。也许它需要更多的东西来显示动画。可能是一些神奇的函数
%
-在
update()
中,你必须删除它
ax.colections.clear()
,然后用
[:num]
再次绘制,我在
update()
的示例中添加了
fill_between()
import random
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation
from matplotlib import rc
rc('animation', html='jshtml')

game = pd.DataFrame({
    'away_wp': [random.randint(-10,10) for _ in range(100)],
    'home_wp': [random.randint(-10,10) for _ in range(100)],
    'game_seconds_remaining': list(range(100)),
})

x = range(len(game))
y1 = game['away_wp']
y2 = game['home_wp']

fig = plt.gcf()
ax = plt.gca()

# empty lines at start
line1, = plt.plot([], [])
line2, = plt.plot([], [])

# doesn't draw fill_between at start

# set limits 
ax.set_xlim(0, 100)
ax.set_ylim(-10, 10)

def update(num, x, y1, y2, line1, line2):
    line1.set_data(x[:num], y1[:num])
    line2.set_data(x[:num], y2[:num])
    # autoscale 
    #ax.relim()
    #ax.autoscale_view()

    ax.collections.clear()
    ax.fill_between(game['game_seconds_remaining'][:num], 0.5, game['away_wp'][:num], where=game['away_wp'][:num]>.5, color = '#4F2683',alpha=0.3)
    ax.fill_between(game['game_seconds_remaining'][:num], 0.5, game['home_wp'][:num], where=game['home_wp'][:num]>.5, color = '#869397',alpha=0.3)
    
    return line1,line2

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y1, y2, line1, line2], interval=295, blit=False)

#plt.show()

ani