从文本列表和 xy 咕咕声中歼灭注释

Annimate a annotation from a list of texts and xy coo

提问人:Beomhui Lee 提问时间:11/16/2023 更新时间:11/16/2023 访问量:8

问:

我使用队列数据结构和 BFS 算法实现了最短路径搜索算法。我正在尝试创建一个 GIF 文件,根据遍历顺序描述探索过程。但是,当我执行代码时,GIF文件保存正确,但是在执行过程中显示的屏幕存在问题。我该如何解决这个问题?

from collections import deque
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import sys
import pandas as pd
import copy


class WireRouting():
    def read_data(self, layout_path:str)->None:
        # Get user input from keyboard
        start_pin_line = input("Enter the start pin coordinate (separate comma): ").split(',')
        end_pin_line = input("Enter the end pin coordinate (separate comma): ").split(',')
    
        self.start_pin = []
        self.end_pin = []
        for coordinate in zip(start_pin_line, end_pin_line):
            self.start_pin.append(int(coordinate[0]))
            self.end_pin.append(int(coordinate[1]))

        # Read the layout.csv file
        self.layout = pd.read_csv(layout_path, header=None).values
        self.solution = copy.deepcopy(self.layout)
   

    def routing_solve(self)->None:
        # Search order: right -> down -> left -> up
        self.offset = [[0, 1], [1, 0], [0, -1], [-1, 0]]

        # Solution_index for Visualization
        self.solution_index = []

        current_x = self.start_pin[0]
        current_y = self.start_pin[1]
    
        queue = deque()
        queue.append((current_x, current_y))
    
        self.solution[current_x][current_y] = -1
        self.solution_index.append((current_x, current_y))

        found = False
        while not found:
            current_x, current_y = queue.popleft()
            for direction in range(len(self.offset)):
                if (0 <= current_x + self.offset[direction][0] < len(self.solution) and
                    0 <= current_y + self.offset[direction][1] < len(self.solution[0]) and
                    self.solution[current_x + self.offset[direction][0]][current_y +    self.offset[direction][1]] == 0):

                    next_x = current_x + self.offset[direction][0]
                    next_y = current_y + self.offset[direction][1]

                    self.solution[next_x][next_y] = self.solution[current_x][current_y] - 1
                    self.solution_index.append((next_x, next_y))

                    if (next_x == self.end_pin[0]) & (next_y == self.end_pin[1]):
                        found = True
                        break
                    queue.append((next_x, next_y))
           
  
    def get_solution(self)->None:
        self.path = []
        objective_value = -(self.solution[self.end_pin[0]][self.end_pin[1]] + 1)
        current_x = self.end_pin[0]
        current_y = self.end_pin[1]

        self.path.append((current_x, current_y))
        while True:
            if ((current_x == self.start_pin[0]) & (current_y == self.start_pin[1])):
                break

            for direction in range(len(self.offset)):
                previous_x = current_x - self.offset[direction][0]
                previous_y = current_y - self.offset[direction][1]
                if ((previous_x >= 0) & (previous_x <= len(self.solution)-1)) & ((previous_y >= 0) & (previous_y <= len(self.solution[0])-1)):
                    if self.solution[previous_x][previous_y] == self.solution[current_x][current_y] + 1:
                        self.path.append((previous_x, previous_y))
                        current_x = previous_x
                        current_y = previous_y
                    
        print("Start pin : {}\nEnd pin : {}\nObjective value : {}".format(self.start_pin, self.end_pin, objective_value))
        print("Routing path : ", end="")
        for idx, value in enumerate(self.path[::-1]):
            if idx == len(self.path)-1:
                print(value)
            else:
                print(value, end="-->")


    def layout_visualize(self)->None:
        fig, ax = plt.subplots()

        self.layout[self.start_pin[0]][self.start_pin[1]] = 3
        self.layout[self.end_pin[0]][self.end_pin[1]] = 3

        ax.imshow(self.layout, cmap="binary")
        plt.annotate("S", (self.start_pin[1], self.start_pin[0]), color="coral", fontsize=12, ha="center", va="center")
        plt.annotate("T", (self.end_pin[1], self.end_pin[0]), color="royalblue", fontsize=12, ha="center", va="center")
        plt.xticks([])
        plt.yticks([])
        plt.savefig("layout.png", dpi=300)
        plt.show()


    def animate(self, idx: int) -> None:
        if idx < len(self.solution_index):
            current_x, current_y = self.solution_index[idx]
            plt.annotate(-self.solution[current_x][current_y], (current_y, current_x), color="coral", fontsize=12, ha="center", va="center")
        else:
            current_x, current_y = self.path[idx - len(self.solution_index)]
            plt.annotate(-self.solution[current_x][current_y], (current_y, current_x), color="royalblue", fontsize=12, weight="bold", ha="center", va="center")


    def solution_visualize(self) -> None:
        fig, ax = plt.subplots()
    
        self.layout[self.start_pin[0]][self.start_pin[1]] = 3
        self.layout[self.end_pin[0]][self.end_pin[1]] = 3

        ax.imshow(self.layout, cmap="binary")
        anim = FuncAnimation(fig, self.animate, frames=len(self.solution_index) + len(self.path), interval=300, repeat=True)

        plt.xticks([])
        plt.yticks([])

        anim.save('BFS_EndPin{}.gif'.format(self.end_pin), writer='pillow')
        plt.show()


if __name__ == "__main__":
    # Program parameters
    # "args": ["layout_data.csv"]
    try:
        layout_data = sys.argv[1]

        wire_routing = WireRouting()
        wire_routing.read_data(layout_data)
        # wire_routing.layout_visualize()
        wire_routing.routing_solve()
        wire_routing.get_solution()
        wire_routing.solution_visualize()
    except Exception as e:
        print(e)

我尝试使用 set_postion 修改solution_visualize和动画方法,但它不起作用。

matplotlib 动画 注解

评论


答: 暂无答案