Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Animation of contourf becomes extremely slow #6985

Closed
@erichlf

Description

@erichlf

When creating an animation with FuncAnimation and contourf I have run into an issue where the more frames I have the slower things become. This is illustrated in the code below. I print a progress bar, which displays both progress and the time required for the current step. As the animation creation progresses you will see that each step takes longer and longer. I was able to mitigate this by creating a derived class MyFuncAnimation, where I overloaded the function save. In the new version of save I go through and clear all collections associated with self._drawn_artists, after writer.grab_frame, in the following way:
for collection in self._drawn_artists.collections: gca().collections.remove(collection)

I am not sure if there is a better way to do this, but it was the only way I could figure out how to address the issue.

Matplot Version = 1.5.1
Python Version = 3.5.2
Platform = MAC OS 10.11.6

Installed matplotlib through pip

Example:

#!/usr/bin/env python3

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import mlab, cm
from matplotlib.animation import FuncAnimation
import sys
import time

barWidth = 40
n_steps = 100

class ProgressBar():
    '''
    Provides a simple progress bar class
    '''
    def __init__(self, nsteps, width=barWidth):
        self._start = self._stop = time.time()
        self._nsteps = nsteps
        self._width = width
        self._status = ""

    def update(self, step):
        '''
        This function produces and updates a progress bar.
        It was stolen and modified from
        http://stackoverflow.com/a/15860757/1552338
        '''
        self._start = self._stop
        self._stop = time.time()
        self._status = self._stop - self._start

        progress = float(step)/float(self._nsteps - 1)
        if progress >= 1:
            progress = 1
            self._status = "Complete...\r\n"
        block = int(round(self._width * progress))
        text = "\rProcessing: [{}] {:.1%} {:.3}".format("#" * block
                                                        + "-" * (self._width
                                                                 - block),
                                                        progress,
                                                        self._status)
        sys.stdout.write(text)
        sys.stdout.flush()

# Create x, y data
delta = 0.5

extent = (-3, 4, -4, 3)

x = np.arange(-3.0, 4.001, delta)
y = np.arange(-4.0, 3.001, delta)
X, Y = np.meshgrid(x, y)

# Boost the upper limit to avoid truncation errors.
levels = np.arange(-2.0, 1.601, 0.4)

fig, ax = plt.subplots(1, 1)  # create our figure and axes
progress = ProgressBar(n_steps)  # initialize the progress bar


def update(frame_number):
    '''
    This is where our contour is creating
    '''
    sigma = np.random.uniform(0, 1, 4)
    Z1 = mlab.bivariate_normal(X, Y, sigma[0], sigma[1], 0.0, 0.0)
    Z2 = mlab.bivariate_normal(X, Y, sigma[2], sigma[3], 1, 1)
    Z = (Z1 - Z2) * 10

    norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max())
    cmap = cm.PRGn

    contf = plt.contourf(X, Y, Z, levels,
                         cmap=cm.get_cmap(cmap, len(levels) - 1),
                         norm=norm)

    progress.update(frame_number)

    return contf

# Construct the animation, using the update function as the animation
# director.
anim = FuncAnimation(fig, update, interval=n_steps)
anim.save("AnimContourf.mp4")
plt.close(fig)
sys.stdout.write("\n")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions