2016-05-30 2 views
1

Я пытаюсь обновить свой лабиринт как поиск непрерывного решения (это простой поиск стоимости для лабиринта с равномерной стоимостью). Я использую pyplots ion() для обновления моей фигуры после посещения каждого узла. Моя проблема в том, что эта цифра очень медленно обновляется примерно через 20 итераций. Я попытался уменьшить значение для pause(), но, похоже, это не влияет. Я уверен, что это не мой компьютер.Python - matplotlib.pyplot ion() slow

import matplotlib.pyplot as plt 
from matplotlib import colors as c 
import math 
import numpy as np 

class Queue: 
    def __init__(self): 
     self.items = [] 

    def isEmpty(self): 
     return self.items == [] 

    def enqueue(self, item): 
     self.items.insert(0,item) 

    def dequeue(self): 
     return self.items.pop() 

    def size(self): 
     return len(self.items) 

def euclideanDistance(pos1, pos2): 
    return math.sqrt(math.pow((pos2[0]-pos1[0]),2) + math.pow((pos2[1]-pos1[1]),2)) 

def getChildren(node, maze): 
    children = [] 
    y = node[0] 
    x = node[1] 
    i = 0 
    if y-1 != -1 and maze[y-1][x] != 1 and maze[y-1][x] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x) 
     i += 1 
    if y-1 != -1 and x+1 != 12 and maze[y-1][x+1] != 1 and maze[y-1][x+1] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x+1) 
     i += 1 
    if x+1 != 12 and maze[y][x+1] != 1 and maze[y][x+1] != '.': 
     children.append([]) 
     children[i].append(y) 
     children[i].append(x+1) 
     i += 1 
    if y+1 != 12 and x-1 != -1 and maze[y+1][x-1] != 1 and maze[y+1][x-1] != 2: 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x-1) 
     i += 1 
    if y+1 != 12 and maze[y+1][x] != 1 and maze[y+1][x] != '.': 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x) 
     i += 1 
    if y+1 != 12 and x+1 != 12 and maze[y+1][x+1] != 1 and maze[y+1][x+1] != 2: 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x+1) 
     i += 1 
    if x-1 != -1 and maze[y][x-1] != 1 and maze[y][x-1] != 2: 
     children.append([]) 
     children[i].append(y) 
     children[i].append(x-1) 
     i += 1 
    if y-1 != -1 and x-1 != -1 and maze[y-1][x-1] != 1 and maze[y-1][x-1] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x-1) 
     i += 1 
    return children 

def uniformCostSearch(root, goal, maze): 
    q = Queue() 
    path = maze 
    root.append(0) 
    q.enqueue(root) 
    while not q.isEmpty(): 
     temp = q.dequeue() 
     printMaze(path) 
     path[temp[0]][temp[1]] = 2 
     if temp[0] == goal[0] and temp[1] == goal[1]: 
      return path 
     else: 
      children = getChildren(temp, path) 
      cArray = [] 
      if len(children) != 0: 
       for child in children: 
        child.append(temp[2]+euclideanDistance(temp, child)) 
        cArray.append(child) 
       cArray.sort(key=lambda x:x[2]) 
       for child in cArray: 
        q.enqueue(child) 

def printMaze(maze): 
    y = [12,11,10,9,8,7,6,5,4,3,2,1,0] 
    x = [0,1,2,3,4,5,6,7,8,9,10,11,12] 
    x, y = np.meshgrid(x, y) 
    maze = np.array(maze) 
    plt.ion() 
    cMap = c.ListedColormap(['w','grey','green','red']) 
    plt.xticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11]) 
    plt.yticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11]) 
    plt.pcolormesh(x, y, maze, edgecolor='k',cmap=cMap) 
    plt.pause(0.000000001) 
    plt.show() 

maze = [[0,0,0,0,0,0,0,0,0,0,0,0], 
     [0,1,1,1,1,1,1,1,1,1,1,0], 
     [0,1,1,1,1,1,1,1,0,3,1,0], 
     [0,0,0,0,0,0,1,1,0,0,1,0], 
     [0,1,1,0,0,0,1,1,0,0,1,0], 
     [0,1,1,0,0,0,1,1,0,0,1,0], 
     [0,1,0,0,0,0,1,1,0,0,1,0], 
     [0,0,0,0,0,1,1,1,0,0,1,0], 
     [0,0,0,0,1,1,1,1,0,0,1,0], 
     [0,0,0,1,1,1,1,1,0,0,1,0], 
     [0,0,1,1,1,1,1,1,0,0,0,0], 
     [0,0,0,0,0,0,0,0,0,0,0,0]] 

root = [] 
root.append(11) 
root.append(0) 

goal = [] 
goal.append(2) 
goal.append(9) 

printMaze(maze) 
uniformCostSearch(root, goal, maze) 

ответ

2

Вот основной пример, показывающий, как анимировать Quadmesh, таких как тот, возвращаемой pcolormesh. Все, что вам нужно сделать (hah!), Это изменить step, чтобы получить лабиринты, которые вы хотите отобразить.

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.animation as animation 

def step(): 
    while True: 
     yield np.random.randint(4, size=(N, N)) 

def animate(data, quadmesh): 
    quadmesh.set_array(data.ravel()) 
    return [quadmesh] 

N = 12 
maze = np.random.randint(4, size=(N, N)) 

fig, ax = plt.subplots() 
cmap = mcolors.ListedColormap(['w','grey','green','red']) 
x, y = np.meshgrid(np.arange(N), np.arange(N)) 
quadmesh = ax.pcolormesh(x, y, maze, edgecolor='k',cmap=cmap) 

ani = animation.FuncAnimation(
    fig, animate, step, 
    interval=10, fargs=(quadmesh,), repeat=True, blit=True) 
plt.show() 

Уменьшение параметра interval в FuncAnimation, чтобы уменьшить задержку между кадрами. Это ускорит анимацию. Вы обнаружите, что нет проблемы , что делает анимацию довольно быстро.

Хотя обновление одного quadmesh (как это было сделано выше) быстрее, чем вызов pcolormesh несколько раз с plt.ion включены, главной причиной, почему ваш анимация идет медленно, потому что это printMaze(path) вызывается много раз то же path.

Вы можете подтвердить это утверждение, изменив printMaze быть

def printMaze(maze): 
    print(maze) 
    print('-'*80) 

Вы увидите в терминале, что лабиринты часто одни и те же один много раз. Поэтому, чтобы сделать вашу анимацию быстрее, вам нужно сделать свой uniformCostSearch умнее. Возможно использовать набор помнить maze S, которые имеют уже были показаны и не называют printMaze снова в этом случае:

import math 
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.colors as mcolors 
import matplotlib.animation as animation 

class Queue: 
    def __init__(self): 
     self.items = [] 

    def isEmpty(self): 
     return self.items == [] 

    def enqueue(self, item): 
     self.items.insert(0,item) 

    def dequeue(self): 
     return self.items.pop() 

    def size(self): 
     return len(self.items) 

def euclideanDistance(pos1, pos2): 
    return math.sqrt(math.pow((pos2[0]-pos1[0]),2) + math.pow((pos2[1]-pos1[1]),2)) 

def getChildren(node, maze): 
    children = [] 
    y = node[0] 
    x = node[1] 
    i = 0 
    if y-1 != -1 and maze[y-1][x] != 1 and maze[y-1][x] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x) 
     i += 1 
    if y-1 != -1 and x+1 != 12 and maze[y-1][x+1] != 1 and maze[y-1][x+1] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x+1) 
     i += 1 
    if x+1 != 12 and maze[y][x+1] != 1 and maze[y][x+1] != '.': 
     children.append([]) 
     children[i].append(y) 
     children[i].append(x+1) 
     i += 1 
    if y+1 != 12 and x-1 != -1 and maze[y+1][x-1] != 1 and maze[y+1][x-1] != 2: 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x-1) 
     i += 1 
    if y+1 != 12 and maze[y+1][x] != 1 and maze[y+1][x] != '.': 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x) 
     i += 1 
    if y+1 != 12 and x+1 != 12 and maze[y+1][x+1] != 1 and maze[y+1][x+1] != 2: 
     children.append([]) 
     children[i].append(y+1) 
     children[i].append(x+1) 
     i += 1 
    if x-1 != -1 and maze[y][x-1] != 1 and maze[y][x-1] != 2: 
     children.append([]) 
     children[i].append(y) 
     children[i].append(x-1) 
     i += 1 
    if y-1 != -1 and x-1 != -1 and maze[y-1][x-1] != 1 and maze[y-1][x-1] != 2: 
     children.append([]) 
     children[i].append(y-1) 
     children[i].append(x-1) 
     i += 1 
    return children 

def step(): 
    seen = set() 
    q = Queue() 
    path = maze 
    root.append(0) 
    q.enqueue(root) 
    while not q.isEmpty(): 
     temp = q.dequeue() 
     frozen = tuple(map(tuple, path)) 
     if frozen not in seen: 
      seen.add(frozen) 
      yield path 
     path[temp[0]][temp[1]] = 2 
     if temp[0] == goal[0] and temp[1] == goal[1]: 
      return path 
     else: 
      children = getChildren(temp, path) 
      cArray = [] 
      if len(children) != 0: 
       for child in children: 
        child.append(temp[2]+euclideanDistance(temp, child)) 
        cArray.append(child) 
       cArray.sort(key=lambda x:x[2]) 
       for child in cArray: 
        q.enqueue(child) 


def animate(data, quadmesh): 
    quadmesh.set_array(data.ravel()) 
    return [quadmesh] 

maze = np.array([[0,0,0,0,0,0,0,0,0,0,0,0], 
       [0,1,1,1,1,1,1,1,1,1,1,0], 
       [0,1,1,1,1,1,1,1,0,3,1,0], 
       [0,0,0,0,0,0,1,1,0,0,1,0], 
       [0,1,1,0,0,0,1,1,0,0,1,0], 
       [0,1,1,0,0,0,1,1,0,0,1,0], 
       [0,1,0,0,0,0,1,1,0,0,1,0], 
       [0,0,0,0,0,1,1,1,0,0,1,0], 
       [0,0,0,0,1,1,1,1,0,0,1,0], 
       [0,0,0,1,1,1,1,1,0,0,1,0], 
       [0,0,1,1,1,1,1,1,0,0,0,0], 
       [0,0,0,0,0,0,0,0,0,0,0,0]]) 
root = [11, 0] 
goal = [2, 9] 

fig, ax = plt.subplots() 
x = np.arange(13) 
y = x[::-1] 
X, Y = np.meshgrid(x, y) 
plt.xticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11]) 
plt.yticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11]) 

cmap = mcolors.ListedColormap(['w','grey','green','red']) 
quadmesh = ax.pcolormesh(X, Y, maze, edgecolor='k',cmap=cmap) 

ani = animation.FuncAnimation(
    fig, animate, step, 
    interval=10, fargs=[quadmesh], repeat=False, blit=True) 
plt.show() 
Смежные вопросы