首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python的matplotlib中在同一地块上动画2行

在python的matplotlib中在同一地块上动画2行
EN

Stack Overflow用户
提问于 2020-07-27 22:54:23
回答 1查看 412关注 0票数 1

我试着在同一情节中画两行。在四处搜索之后,我偶然发现了this post,它似乎让我走上了正确的轨道。当我运行这段代码时,停滞的图形没有动画显示,给了我一个错误的AttributeError: 'AxesSubplot' object has no attribute 'set_data'。我查了一下set_data,它说它‘接受: 2D数组(行是x,y)或两个一维数组’。由于我将line1line2分配给绘图而不是2D数组,动画是否无法工作?我希望能有任何帮助,让这些台词在我的情节动画,我已经尝试了,但没有任何效果。谢谢!

代码语言:javascript
运行
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-28 01:19:34

似乎sns给了AxesSublot,你必须为这个Axes找到line(s)

代码语言:javascript
运行
复制
ax1 = sns.lineplot(...)
ax2 = sns.lineplot(...)

line1 = ax1.lines[0]
line2 = ax2.lines[1]

或者(因为这两行都在同一个Axes上)

代码语言:javascript
运行
复制
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,它需要

代码语言:javascript
运行
复制
from matplotlib import rc
rc('animation', html='jshtml')

# code without `plt.show()`

ani   # display it

来源:Embedding Matplotlib Animations in Python (google colab notebook)

具有随机数据的最小工作代码

代码语言:javascript
运行
复制
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([], [])

代码语言:javascript
运行
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63124772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档