【问题标题】:Redraw solely a specific axes object in Python在 Python 中仅重绘特定的轴对象
【发布时间】:2021-05-24 15:50:08
【问题描述】:

我正在尝试用 Python 专门使用 matplotlib 编写一个小型视频游戏。这个想法是让一个小坐标轴对象上有一个角色,该坐标轴对象在更大的地图上移动。我设法更新了轴的位置,但该方法似乎重绘了完整的图形而不是小轴对象(通过在源代码中调用 plt.draw() ),因此角色后面的重地图也是如此,使得处理速度极慢。

有没有办法在 matplotlib 中重绘特定的轴对象?

我在终端的 IPython shell 中工作。

这是一个模拟我的问题的测试代码,我得到的东西比理想情况慢 10 倍:

import matplotlib.pylab as plt 
import time
import numpy as np 

dtframe = 0.02 #time between plot updating in seconds
frames = 30

plt.subplots(5,5) #to simulate an heavy background matplotlib figure 
ax = plt.axes([0.1,0.5,0.03,0.03])
plt.show(block=False)

begin = time.time()
for j in np.linspace(0.1,0.9,frames):
    plt.pause(dtframe)
    ax.set_position([j,0.5,0.03,0.03])
    #ax.set_position([j,0.5,0.03,0.03], redraw_only_axes=True) ???

print('Current time [s] :',time.time() - begin)
print('Expected time [s] :',dtframe*frames)

#Current time [s] : 5.70146918296814
#Expected time [s] : 0.6 


【问题讨论】:

    标签: python matplotlib draw axes


    【解决方案1】:

    您正在寻找的技术称为 blitting。

    这里有一个关于 matplotlib 的教程:https://matplotlib.org/stable/tutorials/advanced/blitting.html

    【讨论】:

    • 感谢您的帮助!但是,通过查看示例,似乎 blitting 更专注于更新轴内的艺术家对象,而不是轴本身还是我错了?我看不出如何将您提供的示例改编为我的案例...
    【解决方案2】:

    根据@ianhi 提供的教程,这里是blitting的解决方案:

    import matplotlib.pylab as plt 
    import time
    import numpy as np 
    
    dtframe = 0.02 #time between plot updating in seconds
    frames = 30
    
    fig,axes = plt.subplots(5,5) #to simulate an heavy background matplotlib figure 
    ax = plt.axes([0.1,0.5,0.03,0.03],animated=True)
    plt.show(block=False)
    plt.pause(0.1)
    
    bg = fig.canvas.copy_from_bbox(fig.bbox)
    fig.canvas.blit(fig.bbox)
    
    begin = time.time()
    for j in np.linspace(0.1,0.9,frames):
        fig.canvas.restore_region(bg)
        ax.set_position([j,0.5,0.03,0.03])
        plt.pause(dtframe)
        fig.draw_artist(ax)
        fig.canvas.blit(fig.bbox)
        fig.canvas.flush_events()
    
    print('Current time [s] :',time.time() - begin)
    print('Expected time [s] :',dtframe*frames)
    
    #Current time [s] : 1.2531671524047852
    #Expected time [s] : 0.6
    

    【讨论】:

    • 您应该使用ax.bbox 进行blit 以获得更好的性能。目前你正在对整个图进行 blitting
    • @Ianhi 如果我用 ax.bbox 替换所有的 fig.bbox,我会得到几个正在移动的轴的副本。
    • 哦,是的,您需要对两个位置进行 blit。移动轴之前的 bbox 和之后的 bbox
    猜你喜欢
    • 2017-12-08
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2018-05-15
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    相关资源
    最近更新 更多