I’d like to change the title and the colorbar for each plot in my Artist animation. But in the final .gif
it is only showing the title and colorbar of the last frame.
Any idea what I am missing here?
Thank you for your help
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
class AnimatedGif:
def __init__(self, vmin=0, vmax=1):
self.fig, self.ax = plt.subplots()
self.images = []
self.vmin = vmin
self.vmax = vmax
self.cb = None
self.title = 'default title'
def add(self, arr, vmin=None, vmax=None, title=None):
if vmin is None:
vmin = self.vmin
if vmax is None:
vmax = self.vmax
if title is None:
title = self.title
image = plt.imshow(arr.T, vmin=vmin, vmax=vmax, animated=True)
plt.title(title)
if self.cb is not None:
self.cb.remove()
self.cb = self.fig.colorbar(image)
self.images.append([image])
def save(self, filename):
animation = anim.ArtistAnimation(self.fig, self.images)
animation.save(filename, fps=1)
if __name__ == '__main__':
arr = np.random.random((3,128,128))
animated_gif = AnimatedGif()
animated_gif.add(arr[0], vmin=0, vmax=0.3, title='image 0')
images = []
for i in range(1, arr.shape[0]):
animated_gif.add(arr[i], vmin=i*0.01, vmax=(i+1)*0.3, title='image {}'.format(i))
animated_gif.save('arr.gif')
Explanation of the Issue and Fix:
The problem was that plt.title() sets a single title for the whole plot, so only the last title showed up in the final animation. Similarly, the colorbar was being updated, but it wasn’t part of the animation.
How to fix It:
use self.ax.text instead of plt.title() to set a dynamic title for each frame.
Ensure that both the title and the colorbar were added to each frame’s list of animated objects (artists). This way, both the title and colorbar update properly as the frames change.
main diff
title_artist = self.ax.text(0.5, 1.05, title, transform=self.ax.transAxes, ha=”center”, fontsize=12)
And then add title_artist to self.images.append([image, title_artist]) so that the title updates in every frame.output result
2
test with this code it working like indented and I have tested this
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
class AnimatedGif:
def __init__(self, vmin=0, vmax=1):
self.fig, self.ax = plt.subplots()
self.images = []
self.vmin = vmin
self.vmax = vmax
self.cb = None
def add(self, arr, vmin=None, vmax=None, title=None):
if vmin is None:
vmin = self.vmin
if vmax is None:
vmax = self.vmax
if title is None:
title = 'default title'
image = self.ax.imshow(arr.T, vmin=vmin, vmax=vmax, animated=True)
# Update the title for this frame
title_artist = self.ax.text(0.5, 1.05, title, transform=self.ax.transAxes,
ha="center", fontsize=12, animated=True)
if self.cb is not None:
self.cb.remove() # Removing previous colorbar
self.cb = self.fig.colorbar(image, ax=self.ax) # new colorbar for each frame
# Append the image and title as artists that will be updated in each frame
self.images.append([image, title_artist])
def save(self, filename):
animation = anim.ArtistAnimation(self.fig, self.images)
animation.save(filename, fps=1)
if __name__ == '__main__':
arr = np.random.random((5, 128, 128))
animated_gif = AnimatedGif()
for n in range(1, arr.shape[0] + 1):
if n % 2 == 1:
title = f'image {n}'
else:
title = f'artist {n}'
animated_gif.add(arr[n - 1], vmin=(n - 1) * 0.01, vmax=n * 0.3, title=title)
animated_gif.save('arr3.gif')