0

Python 3.9 on Mac with OS 11.6.1

I'm using the Player class defined at Managing dynamic plotting in matplotlib Animation module to design a function, which creates an animation that will be placed on a tkinter canvas contained in a Toplevel window. Each frame of the animation consists of a heatmap appearing above a corresponding bar plot. A colorbar appears next to the heatmap. The heatmap axis labels are strings stored in channels.

Here's my function, where root is my main tkinter window, axis labels are stored in channels, M_list is a list of matrices, and bar_list is a list of lists, where each list in bar_list has length equal to the number of channels and bar_list itself has length equal to the number of matrices.

def heatplot_barplot_animation_combined(root,channels,M_list,bar_list):
    num_times=len(M_list)-1

    fig, ax = plt.subplots(2)

    plot_window = Toplevel(root)
    canvas = FigureCanvasTkAgg(fig, master=plot_window)
    canvas.draw()
    canvas.get_tk_widget().pack(side=TOP,fill=BOTH,expand=1)


    def update_graph(i):
        ax[0].cla
        cbar_ax.cla()
        sns.heatmap(ax = ax[0], data = M_list[i], cmap = "coolwarm", cbar_ax = 
        cbar_ax,vmin=0,vmax=1)
        ax[0].set_xticks(range(len(channels)))
        ax[0].set_xticklabels(channels,fontsize=10)
        ax[0].set_yticks(range(len(channels)))
        ax[0].set_yticklabels(channels,fontsize=10)

        ax[1].cla()
        ax[1].bar(channels,bar_list[i])
        ax[1].set_ylim(0, 1)

        fig.suptitle('Frame: '+str(i), fontsize=12)

    divider = make_axes_locatable(ax[0])
    cbar_ax = divider.append_axes("right", size="5%", pad=0.05)

    ani = Player(fig, update_graph, maxi=num_times)

Sample implementation for 50 8-by-8 matrices:

channels=['a','b','c','d','e','f','g','i']
Nc=len(channels)
Nt=50
M_list=[np.random.rand(Nc,Nc) for i in range(Nt)]
bar_list=[[random.uniform(0,1) for i in range(Nc)] for t in range(Nt)]
heatplot_barplot_animation_combined(root,channels,M_list,bar_list)

The axes are labelled correctly, but the labels flicker in an annoying manner as the animation plays out.

On the other hand, if I move the four lines where I set the labels of ax[0] (the heatmap) outside the update function and immediately below it, the resulting animation does not flicker, but the heatmap axes labels are the numbers 0,1,...,7 and not the entries in channels.

So, I'm struggling to label the axes correctly AND to eliminate the flickering.

fishbacp
  • 1,123
  • 3
  • 14
  • 29

1 Answers1

0

I solved the problem by not trying to set all the ax[0] properties and just adding xticklabels=channels, yticklabels=channels as options to sns.heatmap. I'm still not sure how to rotate my y-axis labels without encountering flickering though. Seems like any axis property modified after heatmap introduces flickering of some sort.

fishbacp
  • 1,123
  • 3
  • 14
  • 29