如何为 seaborn 的热图或相关矩阵设置动画?

Posted

技术标签:

【中文标题】如何为 seaborn 的热图或相关矩阵设置动画?【英文标题】:How to animate a seaborn's heatmap or correlation matrix? 【发布时间】:2016-02-17 23:48:37 【问题描述】:

我对 python 比较陌生(来自 Matlab)。作为一个项目,我试图随着时间的推移创建相关矩阵的动画图。为了使情节更好,我正在尝试 seaborn。我很难完成动画(在 Mac 上的 Matplotlib 后端有问题),但是现在使用来自网络的这段代码可以制作一个非常基本的动画:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

nx = 50
ny = 50

fig = plt.figure()
data = np.random.rand(nx, ny)
im = plt.imshow(data)

def init():
    im.set_data(np.zeros((nx, ny)))

def animate(i):
    #xi = i // ny
    #yi = i % ny
    data = np.random.rand(nx, ny)
    im.set_data(data)
    return im

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=50, repeat = False)

现在,我试图将其调整为 seaborn,但没有成功。似乎 seaborn 在次要情节上工作,并且为这些情节制作动画要困难得多。我曾经得到的最好的东西是一种递归图,其中seaborn.heatmaps 被绘制在彼此之上。此外,im.set_data 方法不可用。

非常感谢任何建议。

【问题讨论】:

【参考方案1】:

我用seaborn.heatmap 替换了plt.imshow(通过set_data 投射数据不起作用)。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import animation

fig = plt.figure()
data = np.random.rand(10, 10)
sns.heatmap(data, vmax=.8, square=True)

def init():
      sns.heatmap(np.zeros((10, 10)), vmax=.8, square=True, cbar=False)

def animate(i):
    data = np.random.rand(10, 10)
    sns.heatmap(data, vmax=.8, square=True, cbar=False)

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=20, repeat = False)

这创造了我苦苦挣扎的递归情节。

【讨论】:

认为我刚刚找到了一个解决方案:将 plt.clf() 放在 animate-function 的第一行现在可以了!谢谢,拉尔夫。 我在此处添加了您的内容作为对您问题的编辑,这实际上属于该问题,并将您的答案编辑为实际答案。 它不起作用,因为每次迭代您的代码都会在图形上生成另一个比例尺。【参考方案2】:

这是一个完整的示例(使用 Matplotlib 3.0.3 测试)。

import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns


def animate_heat_map():
    fig = plt.figure()

    nx = ny = 20
    data = np.random.rand(nx, ny)
    ax = sns.heatmap(data, vmin=0, vmax=1)

    def init():
        plt.clf()
        ax = sns.heatmap(data, vmin=0, vmax=1)

    def animate(i):
        plt.clf()
        data = np.random.rand(nx, ny)
        ax = sns.heatmap(data, vmin=0, vmax=1)

    anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1000)

    plt.show()


if __name__ == "__main__":
    animate_heat_map()

【讨论】:

【参考方案3】:

根据 r schmaelzle 的回答,我创建了带有注释的动画 seaborn heatmap。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import animation


class Heatmap:

    def __init__(self):
        self.fig, self.ax = plt.subplots()
        self.anim = None

    def animate(self):
        def init():
            sns.heatmap(np.zeros((10, 10)), vmax=.8, ax=self.ax)

        def animate(i):
            self.ax.texts = []
            sns.heatmap(np.random.rand(10, 10), annot=True, vmax=.8, cbar=False, ax=self.ax)

        self.anim = animation.FuncAnimation(self.fig, animate, init_func=init, frames=20, repeat=False)

if __name__ == '__main__':
    hm = Heatmap()
    hm.animate()

更新注解的技巧是将ax.texts = []设为空。

我希望它会帮助别人! :)

【讨论】:

【参考方案4】:

除了您上面的答案之外,我还想从数据框列表中执行此操作并保存为 gif。因此,使用您的代码和 Serenity 对Matplotlib animation iterating over list of pandas dataframes的回答@

fig = plt.figure()
def init():
    sns.heatmap(np.zeros((10, 10)), vmax=.8, square=True, cbar=False)

def animate(i):
    data = data_list[i]
    sns.heatmap(data, vmax=.8, square=True, cbar=False)

data_list = []
for j in range(20):
    data = np.random.rand(10, 10)
    data_list.append(data)

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=20, repeat = False)

savefile = r"test3.gif"
pillowwriter = animation.PillowWriter(fps=20)
anim.save(savefile, writer=pillowwriter)

plt.show()

谢谢!!!

【讨论】:

以上是关于如何为 seaborn 的热图或相关矩阵设置动画?的主要内容,如果未能解决你的问题,请参考以下文章

具有相同单元大小的 Seaborn 相关热图

Seaborn 热图相关性不适合注释数字

如何为热图聚类 numpy 系数数组

使用 python seaborn 仅在某些值之间设置热图相关性

如何反转seaborn热图颜色条的颜色

在 seaborn 中自定义相关热图