Skip to content

animation blitting is no longer working #4947

Closed

Description

@jrevans

This is mentioned in #4897.

I currently do not have a solution for this one, but I do have a script that demonstrates the problem. I am using the current devel branch and a Qt5Agg backend.

The following is in reference to the attached script.

The line 'bg = fig.canvas.copy_from_bbox( fig.bbox )' will in fact save the current Agg buffer state as appropriate. The later calls to 'fig.canvas.restore_region( bg, fig.bbox )' however do not seem to actually restore the Agg buffers to the saved state, because in the subsequent call to 'fig.canvas.blit( fig.bbox )' the Agg buffers are still in the same state as before the call to 'restore_region'. The result is the red ellipse gets drawn multiple times to the Agg backend.

At the end of the script a new call to the canvas 'draw' method causes the entire figure to redraw (and the Agg backend), and the plot then is updated to look as expected.

======================================================================
#   blit.py
======================================================================
#!/bin/env python

import pylab as p
from matplotlib.patches import Ellipse
import math, time

p.ion()
fig, ax = p.subplots()
ax.set_xlim( [ -3, 3 ] )
ax.set_ylim( [ -3, 3 ] )

e1 = Ellipse( [ 0, 0 ], 1, 2, 0 )
ax.add_patch( e1 )

e2 = Ellipse( [ 2, 0 ], 1, 3, 0 )
ax.add_patch( e2 )

raw_input( "Press return to start blit" )

bg = fig.canvas.copy_from_bbox( fig.bbox )

e0 = Ellipse( [1,0], 1, 1, 0, facecolor="red" )
ax.add_patch( e0 )

t0 = time.time()
num = 0
while True:
   dt = time.time() - t0
   if dt > 1:
      print "%d frames in %g sec (%g frames/sec)" % ( num, dt, num/dt )
      break

   fig.canvas.restore_region( bg, fig.bbox )

   x = num / 10.0
   e0.center = [ math.cos( x ), math.sin( x ) ]

   ax.draw_artist( e0 )
   fig.canvas.blit( fig.bbox )

   num += 1


print "================="
print "Qt5 bug: red ellipse is not removed each time."
raw_input( "Press return to remove red ellipse" )

e0.remove()
fig.canvas.restore_region( bg, fig.bbox )
fig.canvas.blit( fig.bbox )

print "================="
print "The red ellipse should be gone - if it's still there, try to resize"
print "the screen.  In some cases an extra 'draw' happens here which "
print "causes the entire plot to redraw and look correct.  In Qt5agg, "
print "this shows the bug..."
print
raw_input( "Press return to exit" )

Activity

  1. tacaswell commented on Aug 17, 2015

    @tacaswell
    Member

    I ended up modifying your script a bit (mostly style + python3 compatibility as I only have qt5 + python3 set up to test with) and can not reproduce this issue with either pyqt4 or pyqt5 in python3 @ 3520e94

    from __future__ import print_function
    import matplotlib.pyplot as plt
    from matplotlib.patches import Ellipse
    import math
    import time
    
    plt.ion()
    fig, ax = plt.subplots()
    ax.set_xlim([-3, 3])
    ax.set_ylim([-3, 3])
    
    e1 = Ellipse([0, 0], 1, 2, 0)
    ax.add_patch(e1)
    
    e2 = Ellipse([2, 0], 1, 3, 0)
    ax.add_patch(e2)
    
    input("Press return to start blit")
    
    bg = fig.canvas.copy_from_bbox(fig.bbox)
    
    e0 = Ellipse([1, 0], 1, 1, 0, facecolor="red")
    ax.add_patch(e0)
    
    t0 = time.time()
    num = 0
    while True:
        dt = time.time() - t0
        if dt > 1:
            print("%d frames in %g sec (%g frames/sec)" % (num, dt, num/dt))
            break
    
        fig.canvas.restore_region(bg, fig.bbox)
    
        x = num / 10.0
        e0.center = [math.cos(x), math.sin(x)]
    
        ax.draw_artist(e0)
        fig.canvas.blit(fig.bbox)
    
        num += 1
    
    
    print("=================")
    print("Qt5 bug: red ellipse is not removed each time.")
    input("Press return to remove red ellipse")
    
    e0.remove()
    fig.canvas.restore_region(bg, fig.bbox)
    fig.canvas.blit(fig.bbox)
    
    print("=================")
    print("The red ellipse should be gone - if it's still there, try to resize")
    print("the screen.  In some cases an extra 'draw' happens here which ")
    print("causes the entire plot to redraw and look correct.  In Qt5agg, ")
    print("this shows the bug...")
    
    input("Press return to exit")
  2. mdehoon commented on Aug 18, 2015

    @mdehoon
    Contributor

    With the current master (latest commit 512b5d7), the animation doesn't run at all with qt5agg. With tkagg, the animation runs, but the red ellipse gets drawn multiple times as described by @jrevans .

  3. tacaswell commented on Aug 18, 2015

    @tacaswell
    Member

    ah, I now see what is going on, in 512b5d7 I am getting a bunch of extra draws so it looks like the animation is working, but is running much slower than it should be. I do see the overlapped circles with tkagg and if I merge the two qt PRs into master.

  4. tacaswell commented on Aug 18, 2015

    @tacaswell
    Member

    The problem seems to be this code path https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_agg.py#L347

    If you change

    fig.canvas.restore_region(bg)

    then it works as expected.

    This looks like fall out from the cxx conversion.

  5. added a commit that references this issue on Aug 18, 2015
    f0792ba
  6. added this to the milestone on Aug 18, 2015
  7. self-assigned this
    on Aug 18, 2015
  8. tacaswell commented on Aug 18, 2015

    @tacaswell
    Member

    @mdehoon @jrevans Thanks! Can you check if #4951 fixes this for you?

    Sorry I was being cranky.

  9. mdehoon commented on Aug 18, 2015

    @mdehoon
    Contributor

    @tacaswell #4951 fixes the problem for tkagg.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions