2014-11-16 2 views
0

У меня есть класс матрицы, который наследуется от списка. Этот класс может отображать себя как матричное представление матрицы матрицы.Как обновить график matplotlib без создания нового окна

Я пытаюсь записать класс таким образом, что при изменении значений в матрице я могу вызвать метод матрицы plot(), и он обновит график, чтобы отразить изменения матрицы в тепловой карте.

Однако каждый раз, когда я запускаю метод plot(), он создает новую тепловую карту в новом окне вместо обновления существующего графика. Как я могу получить это просто до обновление существующего участка?

В приведенном ниже коде есть три основные части: основная функция показывает, как создается экземпляр класса матрицы, отображается и обновляется; класс матрицы - это в основном объект списка, с некоторыми незначительными функциональными возможностями (включая построение графика); функция 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() 

Я использую Python 3 в Ubuntu.

+0

Пожалуйста, предоставьте [минимальный пример] (https://stackoverflow.com/help/mcve) – sebix

ответ

1

Метод plot(self) создает новую цифру в строке fig, ax = plt.subplots(). Чтобы использовать существующую фигуру вы можете дать figure номер или имя, когда он первым создал в plotList():

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

затем использовать

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

сделать что активной фигурой и axes. В качестве альтернативы вам может понадобиться фигура и ось, созданные в plotList, и передать их plot.

+0

Большое вам спасибо за помощь. Я сделал то, что вы предлагали, возвращая объекты фигуры и осей из функции создания сюжета. – d3pd