vlad_tepesch
vlad_tepesch

Reputation: 6891

matblotlib animate matshow by cycling colors

I want to animate a matrix plot by just changing the colormap. but i could not get it running

this is my code:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
from  matplotlib.animation import FuncAnimation


def rotate(l, n):
    return l[n:] + l[:n]

def samplemat(dims):
    aa = np.zeros(dims)
    for i in range(min(dims)):
      for j in range(min(dims)):
        aa[i, j] = (i+1)*(j+1)
    return aa


min_val, max_val = 0, 15

fig = plt.figure()
mat = samplemat((15, 15))
colmapV = plt.cm.Blues(list(range(0, max_val*max_val)))
colmap = ListedColormap(colmapV)
ms = plt.matshow(mat, cmap=colmap)



def animate(i):
  global  colmapV
  colmapV = rotate(colmapV, 1)
  colmap = ListedColormap(colmapV)
  ms = plt.matshow(mat, cmap=colmap)
  return ms,

# create animation using the animate() function
myAnimation = FuncAnimation(fig, animate, frames=100, interval=100, blit=True, repeat=True)
plt.show()

it fails with

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python3\lib\tkinter\__init__.py", line 1884, in __call__
    return self.func(*args)
  File "C:\Python3\lib\tkinter\__init__.py", line 805, in callit
    func(*args)
  File "C:\Python3\lib\site-packages\matplotlib\backends\_backend_tk.py", line 99, in _on_timer
    TimerBase._on_timer(self)
  File "C:\Python3\lib\site-packages\matplotlib\backend_bases.py", line 1194, in _on_timer
    ret = func(*args, **kwargs)
  File "C:\Python3\lib\site-packages\matplotlib\animation.py", line 1426, in _step
    still_going = Animation._step(self, *args)
  File "C:\Python3\lib\site-packages\matplotlib\animation.py", line 1157, in _step
    self._draw_next_frame(framedata, self._blit)
  File "C:\Python3\lib\site-packages\matplotlib\animation.py", line 1177, in _draw_next_frame
    self._post_draw(framedata, blit)
  File "C:\Python3\lib\site-packages\matplotlib\animation.py", line 1200, in _post_draw
    self._blit_draw(self._drawn_artists)
  File "C:\Python3\lib\site-packages\matplotlib\animation.py", line 1222, in _blit_draw
    a.axes.draw_artist(a)
  File "C:\Python3\lib\site-packages\matplotlib\axes\_base.py", line 2760, in draw_artist
    raise AttributeError("draw_artist can only be used after an "
AttributeError: draw_artist can only be used after an initial draw which caches the renderer

Does anybody a hint?

Another small issue is that I always get 2 figure windows, but if i remove the figure call I do not know that I should pass to FuncAnimation.

Upvotes: 0

Views: 112

Answers (1)

Diziet Asahi
Diziet Asahi

Reputation: 40667

This is a weird error, and the fact that you get two figures is also weird. You can fix it by creating the axes explicitly, but then I don't think the way you are shifting your colormap is quite right. Here is the code I ended up with:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.animation import FuncAnimation


def samplemat(dims):
    aa = np.zeros(dims)
    for i in range(min(dims)):
        for j in range(min(dims)):
            aa[i, j] = (i + 1) * (j + 1)
    return aa


min_val, max_val = 0, 15

fig = plt.figure()
ax = fig.add_subplot(111)
mat = samplemat((15, 15))
cmap = plt.get_cmap('Blues')
ms = ax.matshow(mat, cmap=cmap)


def animate(i, out):
    out = np.roll(out, i)
    new_cmap = LinearSegmentedColormap.from_list("", cmap(out))
    ms.set_cmap(new_cmap)
    return ms,


# create animation using the animate() function
myAnimation = FuncAnimation(fig, animate, frames=max_val*max_val, interval=100, blit=True, repeat=True,
                            fargs=(np.arange(0, max_val * max_val),))
plt.show()

enter image description here (I had to reduce the resolution to fit in the filesize requirements)

Upvotes: 2

Related Questions