在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()仍然返回您执行的非动画GraphIdline1,=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