I want the green rectangle to not disappear as it moves from one value to another in matrix b
. For example, the rectangle is around 0.24671953. Then the rectangle stays on this value. Then another rectangle appears onto the next value which is 0.25959473. Then another rectangle appears on 0.41092171, with the previous two rectangles not disappearing.
import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap import seaborn as sns import numpy as np from celluloid import Camera a = np.array([[0.24671953, 0.25959473, 0.85494718], [0.60553861, 0.76276659, 0.41092171], [0.37356358, 0.69378785, 0.46988614]]) b = np.array([[0.24671953,0.25959473], [0.41092171,0.46988614], [0.37356358,0.60553861]]) annot=True fig, ax1 = plt.subplots(1) camera = Camera(fig) sns.set_style('white') ax1 = sns.heatmap(a, linewidth=0.5,ax=ax1,annot=annot) for bb in b.flatten(): ax1.add_patch(plt.Rectangle((np.where(a == bb)[1][0], np.where(a == bb)[0][0]), 1, 1, fc='none', ec='green', lw=5, clip_on=False)) camera.snap() animation = camera.animate(interval=800) animation.save('animation2.gif') plt.show()
Advertisement
Answer
It looks like celluloid
clears the existing plot at each snap
. You can recreate the plot from scratch at each step. The rectangles can be stored in a list.
To avoid that new colorbar positions are set at each step, you can use sns.heatmap
‘s cbar_ax=
parameter to always use the same colorbar ax
:
import matplotlib.pyplot as plt import seaborn as sns import numpy as np from celluloid import Camera a = np.array([[0.24671953, 0.25959473, 0.85494718], [0.60553861, 0.76276659, 0.41092171], [0.37356358, 0.69378785, 0.46988614]]) b = np.array([[0.24671953, 0.25959473], [0.41092171, 0.46988614], [0.37356358, 0.60553861]]) fig, (ax1, cbar_ax) = plt.subplots(ncols=2, gridspec_kw={'width_ratios': [20, 1]}) camera = Camera(fig) sns.set_style('white') rectangles = [] for bb in b.flatten(): sns.heatmap(a, linewidth=0.5, ax=ax1, annot=True, cbar_ax=cbar_ax) rectangles.append(plt.Rectangle((np.where(a == bb)[1][0], np.where(a == bb)[0][0]), 1, 1, fc='none', ec='green', lw=5, clip_on=False)) for rect in rectangles: ax1.add_patch(rect) camera.snap() animation = camera.animate(interval=800) animation.save('animation2.gif') plt.show()
An alternative could be to directly use matplotlib’s animation framework. Then, the code could look like:
import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import seaborn as sns import numpy as np a = np.array([[0.24671953, 0.25959473, 0.85494718], [0.60553861, 0.76276659, 0.41092171], [0.37356358, 0.69378785, 0.46988614]]) b = np.array([[0.24671953, 0.25959473], [0.41092171, 0.46988614], [0.37356358, 0.60553861]]) fig, ax1 = plt.subplots() sns.set_style('white') sns.heatmap(a, linewidth=0.5, ax=ax1, annot=True) def animate(i): bb = b.flatten()[i] patch = ax1.add_patch(plt.Rectangle((np.where(a == bb)[1][0], np.where(a == bb)[0][0]), 1, 1, fc='none', ec='green', lw=5, clip_on=False)) return patch, animation = FuncAnimation(fig, animate, frames=range(0, b.size), interval=800, repeat=False) animation.save('animation2.gif') plt.show()