Overlapping charts in `matplotlib.animation.FuncAnimation` overwrite the alpha parameter

Viewed 12

I am trying to plot a random walk in two ways:

  1. static using plot method from matplotlib.pyplot,
  2. animated using FuncAnimation from matplotlib.animation.

The first one works pretty well, you can see an example of a really simple Brownian motion below.

Static Brownian motion

I tried to implement the code which would be capable of animating the random walk however I struggle with colors and the alpha parameter.

First of all the alpha parameter does not work. After successive iterations, the points overlap losing their transparency. In addition, the colors of the individual points change in each iteration, making the animation very unreadable.

You can see one animation below. The paths are the same as in the figure above.

Animated Brownian motion

The code I used to create the animation.

import os
from datetime import datetime

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.animation import PillowWriter


class Plotter:

    def __init__(self, paths, link, annotate, grid, save, alpha, cmap):

        self._paths = paths
        self._link = link
        self._annotate = annotate
        self._alpha = alpha
        self._cmap = cmap

        self._fig, self._ax = plt.subplots()
        self._animation = None

        if grid:
            self._ax.grid()

        self._plot()

        if save:
            self._check_path()
            self._filename = self._create_filename()
            self._save()

    def _plot(self):
        self._animation = FuncAnimation(
            self._fig, self._anim,  interval=500, frames=len(self._paths[0][0]), repeat=False,
        )

    def _anim(self, frame):
        self._ax.set_title(f'Frame: {frame}')
        for path in self._paths:
            x, y = path

            if self._link:
                self._ax.plot(x[:frame+1], y[:frame+1], linestyle='--', marker='o', alpha=self._alpha)
            else:
                self._ax.scatter(x[:frame+1], y[:frame+1], alpha=self._alpha, cmap=self._cmap)

    def _save(self):
        self._animation.save(self._filename, dpi=300, writer=PillowWriter(fps=25))

    @staticmethod
    def _check_path():
        if not os.path.exists('figures/'):
            os.mkdir('figures/')

    @staticmethod
    def _create_filename():
        filename = 'figures/{name}.gif'
        name = datetime.now().strftime("%d-%m-%Y %H:%M:%S")
        return filename.format(name=name)

And that's how I created the .gif.

paths = [
    (
        [0, -0.6655408436280401, 0.10568259609257569, -0.26149279371869266, -0.5009666521908381, 0.3639625899869371, -0.49976435812228837, -0.48682212081220344, -1.2885433457534117, -0.9850803395821125, -0.018343580936876158],
        [0, -0.7463614308516193, -1.3829259649135648, -0.45277423905538894, 0.5181285733354615, 1.0200223928090424, 1.523982469709905, 2.5238987154492216, 3.1215968645836893, 4.074440085625576, 4.330213499967454]),
    (
        [0, 0.06636040923368702, 0.05255193650063124, 0.597356910675901, -0.2793019906386772, -0.894506810533089, 0.06788127670582911, -0.3820663494179474, -0.3801418070740879, 0.6063698370900061, -0.3466678114238062],
        [0, 0.9977957186149565, 1.9977003771103456, 1.1591375946582005, 1.6402500251210983, 2.4286173440649295, 2.700295774457584, 3.5933507188734235, 2.593352570806755, 2.4296614716942626, 2.732513317512087]
    )
]

Plotter(paths=paths, link=True, annotate=False, grid=True, save=True, alpha=0.5, cmap='Pastel1')

Is it possible to set fixed colours for individual points and a fixed value for the alpha parameter?

0 Answers
Related