我试着在同一情节中画两行。在四处搜索之后,我偶然发现了this post,它似乎让我走上了正确的轨道。当我运行这段代码时,停滞的图形没有动画显示,给了我一个错误的AttributeError: 'AxesSubplot' object has no attribute 'set_data'
。我查了一下set_data
,它说它‘接受: 2D数组(行是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)
发布于 2020-07-28 01:19:34
似乎sns
给了AxesSublot
,你必须为这个Axes
找到line(s)
ax1 = sns.lineplot(...)
ax2 = sns.lineplot(...)
line1 = ax1.lines[0]
line2 = ax2.lines[1]
或者(因为这两行都在同一个Axes
上)
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]
编辑:
对于Google Colab
,它需要
from matplotlib import rc
rc('animation', html='jshtml')
# code without `plt.show()`
ani # display it
来源:Embedding Matplotlib Animations in Python (google colab notebook)
具有随机数据的最小工作代码
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([], [])
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
https://stackoverflow.com/questions/63124772
复制相似问题