如何在不创建新窗口的情况下更新matplotlib热图图

时间:2014-11-16 09:52:42

标签: python-3.x matrix matplotlib heatmap

我有从列表继承的矩阵类。该类可以将其自身显示为矩阵的matplotlib热图表示。

我正在尝试编写这样的类,当我更改矩阵中的值时,我可以调用矩阵的方法plot()并且它将更新绘图以反映热图中的矩阵变化。 / p>

但是,每次运行方法plot()时,它都会在新窗口中创建新的热图,而不是更新现有的图。我怎么能只是更新现有的情节呢?

在下面的代码中,有三个主要部分:main函数显示如何创建,绘制和更新矩阵类的实例;矩阵类基本上是一个列表对象,其中一些次要功能(包括绘图)用螺栓固定;函数plotList()是矩阵类为了最初生成绘图对象而调用的函数。

import time
import random
import matplotlib.pyplot as plt
plt.ion()
import numpy as np

def main():

    print("plot 2 x 2 matrix and display it changing in a loop")
    matrix = Matrix(
        numberOfColumns = 2,
        numberOfRows    = 2,
        randomise       = True
    )
    # Plot the matrix.
    matrix.plot()
    # Change the matrix, redrawing it after each change.
    for row in range(len(matrix)):
        for column in range(len(matrix[row])):
            input("Press Enter to continue.")
            matrix[row][column] = 10
            matrix.plot()
    input("Press Enter to terminate.")
    matrix.closePlot()

class Matrix(list):

    def __init__(
        self,
        *args,
        numberOfColumns          = 3,
        numberOfRows             = 3,
        element                  = 0.0,
        randomise                = False,
        randomiseLimitLower      = -0.2,
        randomiseLimitUpper      = 0.2
        ):
        # list initialisation
        super().__init__(self, *args)   
        self.numberOfColumns     = numberOfColumns
        self.numberOfRows        = numberOfRows
        self.element             = element
        self.randomise           = randomise
        self.randomiseLimitLower = randomiseLimitLower
        self.randomiseLimitUpper = randomiseLimitUpper
        # fill with default element
        for column in range(self.numberOfColumns):
            self.append([element] * self.numberOfRows)
        # fill with pseudorandom elements
        if self.randomise:
            random.seed()
            for row in range(self.numberOfRows):
                for column in range(self.numberOfColumns):
                    self[row][column] = random.uniform(
                        self.randomiseLimitUpper,
                        self.randomiseLimitLower
                    )
        # plot
        self._plot               = plotList(
                                       list  = self,
                                       mode  = "return"
                                   )
        # for display or redraw plot behaviour
        self._plotShown          = False

    def plot(self):
        # display or redraw plot
        self._plot.draw()
        if self._plotShown:
            #self._plot            = plotList(
            #                            list  = self,
            #                            mode  = "return"
            #                        )
            array = np.array(self)
            fig, ax = plt.subplots()
            heatmap = ax.pcolor(array, cmap = plt.cm.Blues)
            self._plot.draw()
        else:
            self._plot.show()
            self._plotShown = True

    def closePlot(self):
        self._plot.close()

def plotList(
    list  = list,
    mode  = "plot" # plot/return
    ):
    # convert list to NumPy array
    array = np.array(list)
    # create axis labels
    labelsColumn = []
    labelsRow = []
    for rowNumber in range(0, len(list)):
        labelsRow.append(rowNumber + 1)
        for columnNumber in range(0, len(list[rowNumber])):
            labelsColumn.append(columnNumber)
    fig, ax = plt.subplots()
    heatmap = ax.pcolor(array, cmap = plt.cm.Blues)
    # display plot or return plot object
    if mode == "plot":
        plt.show()
    elif mode == "return":
        return(plt)
    else:
        Exception

if __name__ == '__main__':
    main()

我在Ubuntu中使用Python 3。

1 个答案:

答案 0 :(得分:1)

方法plot(self)在行fig, ax = plt.subplots()中创建一个新数字。要使用现有数字,您可以在plotList()首次创建时为figure提供一个数字或名称:

fig = plt.figure('matrix figure')
ax = fig.add_subplot(111)

然后使用

plt.figure('matrix figure') 
ax = gca() # gets current axes

使活跃的数字和axes。或者,您可能希望在plotList中创建图形和轴,并将它们传递给plot