diff --git a/AZUL/Gui.py b/AZUL/Gui.py
new file mode 100644
index 0000000000000000000000000000000000000000..a28f84b03860c967a0b83d7554f9f1ea945ad034
--- /dev/null
+++ b/AZUL/Gui.py
@@ -0,0 +1,211 @@
+from collections import deque
+from tkinter import *
+from tkinter import font
+
+WIDTH = 1600
+HEIGHT = 900
+
+
+class Gui:
+    def __init__(self, tree, name = 'tk'):
+        self.tree = tree
+        master = Tk()
+        master.title(name)
+        self.master = master
+        w, h = master.maxsize()
+        master.geometry("{}x{}".format(w, h))
+
+        self.rate = 0.01
+        self.elements = []
+        self.sketch = []
+        self.map_x = WIDTH // 2
+        self.map_y = HEIGHT // 2
+        self.show_info = False
+
+        self.initWedge()
+        self.master.protocol('WM_DELETE_WINDOW', self.closeWindow)
+        master.mainloop()
+
+    def closeWindow(self):
+        print('closing window')
+        self.master.destroy()
+
+    def initWedge(self):
+        master = self.master
+        self.cv = Canvas(master,
+                         width=WIDTH,
+                         height=HEIGHT)
+        self.cv.pack()
+        self.cv.bind('<MouseWheel>', self.zoom)
+        self.cv.bind('<B1-Motion>', self.move_to_map)
+        self.cv.bind('<Button-1>', self.press)
+        self.cv.bind('<Button-3>',self.info_switch)
+        self.refresh_tree()
+
+    def info_switch(self, event):
+        if self.show_info is False:
+            self.refresh_tree(info=True)
+            self.show_info = True
+        else:
+            self.refresh_tree(info=False)
+            self.show_info = False
+
+    def press(self, event):
+        self.pre_event_x = event.x
+        self.pre_event_y = event.y
+
+    def move_to_map(self, event):
+        for s in self.sketch:
+            self.cv.move(s, event.x - self.pre_event_x, event.y - self.pre_event_y)
+        self.pre_event_x = event.x
+        self.pre_event_y = event.y
+
+    def zoom(self, event):
+        zoom_rate = 0.8
+        if event.delta < 0:
+            for s in self.sketch:
+                self.cv.scale(s, event.x, event.y, zoom_rate, zoom_rate)
+        else:
+            for s in self.sketch:
+                self.cv.scale(s, event.x, event.y, 1 / zoom_rate, 1 / zoom_rate)
+
+    def refresh_tree(self, info=False):
+        for e in self.elements:
+            e.delete_self()
+        m = Map(x=self.map_x, y=self.map_y, rate=self.rate, cv=self.cv, elements=self.elements, sketch=self.sketch)
+        self.m = m
+        self.generate_tree(m, info)
+
+    def generate_gui_node(self, node, parent_gui_node, m, info=False):
+        DEFAULT_WIDTH = 200
+        DEFAULT_HEIGTH = 200
+        DEFAULT_LAYERH_HEIGHT = 2000
+        if parent_gui_node is None:
+            gui_node = GuiNode(DEFAULT_WIDTH, DEFAULT_HEIGTH,
+                               m.width // 2, m.height // 4,
+                               m.width,
+                               node, parent_gui_node, m,
+                               self.rate, self.cv, self.elements, self.sketch, info)
+
+        else:
+            peers = [c for c in node.parent.get_children()]
+            width_for_children = parent_gui_node.width_for_children // len(peers)
+            i = peers.index(node)
+
+            peer_width = parent_gui_node.width_for_children
+            x = parent_gui_node.x - peer_width // 2 + peer_width // (len(peers) + 1) * (i + 1)
+            y = parent_gui_node.y + DEFAULT_LAYERH_HEIGHT
+
+            gui_node = GuiNode(DEFAULT_WIDTH, DEFAULT_HEIGTH,
+                               x, y,
+                               width_for_children,
+                               node, parent_gui_node, m,
+                               self.rate, self.cv, self.elements, self.sketch, info)
+        return gui_node
+
+    def generate_tree(self, m, info=False):
+        if len(self.tree) > 0:
+            tree_dict = {}
+            tree_dict[None] = None
+            q = deque()
+            root_node = self.tree[0]
+            q.append(root_node)
+            while len(q) > 0:
+                n = q.popleft()
+                gui_node = self.generate_gui_node(n, tree_dict[n.parent], m, info)
+                tree_dict[n] = gui_node
+
+                children = n.get_children()
+                for c in children:
+                    if c is not None:
+                        q.append(c)
+
+
+class Map:
+    def __init__(self, x=0, y=0, rate=0.1, cv=None, elements=None, sketch=None):
+        self.width = 100000
+        self.height = 100000
+        self.cv = cv
+        self.refer_x = x - self.width * rate // 2
+        self.refer_y = y - self.height * rate // 2
+        self.rect = cv.create_rectangle(x - self.width * rate // 2, y - self.height * rate // 2,
+                                        x + self.width * rate // 2, y + self.height * rate // 2,
+                                        outline='black',
+                                        fill='white',
+                                        )
+
+        elements.append(self)
+        sketch.append(self.rect)
+
+    def delete_self(self):
+        self.cv.delete(self.rect)
+
+
+class GuiNode:
+    def __init__(self,
+                 width_on_map, height_on_map,
+                 x_on_map, y_on_map,
+                 width_for_children,
+                 node, parent_gui_node, m,
+                 rate, cv,
+                 elements=None,
+                 sketch=None, info=False):
+
+        self.node = node
+        self.cv = cv
+        self.color = 'red' if node.mark else 'black'
+        self.line = None
+        self.info = None
+
+
+        if parent_gui_node is not None:
+            self.layer = parent_gui_node.layer + 1
+            self.line = cv.create_line(m.refer_x + x_on_map * rate,
+                                       m.refer_y + (y_on_map - height_on_map) * rate,
+                                       m.refer_x + parent_gui_node.x * rate,
+                                       m.refer_y + (parent_gui_node.y + height_on_map) * rate,
+                                       fill=self.color)
+            sketch.append(self.line)
+        else:
+            self.layer = 0
+        width_on_map = width_on_map/(self.layer+1)
+        height_on_map = height_on_map/(self.layer+1)
+        self.rect = cv.create_rectangle(m.refer_x + (x_on_map - width_on_map + self.layer // 2) * rate,
+                                        m.refer_y + (y_on_map - height_on_map + self.layer // 2) * rate,
+                                        m.refer_x + (x_on_map + width_on_map - self.layer // 2) * rate,
+                                        m.refer_y + (y_on_map + height_on_map - self.layer // 2) * rate,
+                                        outline=self.color,
+                                        fill='white' if self.layer%2==0 else 'black',
+                                        )
+        if info:
+            self.info = cv.create_text(m.refer_x + (x_on_map - width_on_map + self.layer // 2) * rate,
+                                       m.refer_y + (y_on_map - height_on_map - 40 + self.layer // 2) * rate,
+                                       font=font.Font(size=int(10)),
+                                       fill='red',
+                                       text=node.info())
+            sketch.append(self.info)
+
+        self.x = x_on_map
+        self.y = y_on_map
+        self.width_for_children = width_for_children
+
+        sketch.append(self.rect)
+
+        elements.append(self)
+
+
+
+    def delete_self(self):
+
+        self.cv.delete(self.rect)
+        if self.line is not None:
+            self.cv.delete(self.line)
+        if self.info is not None:
+            self.cv.delete(self.info)
+
+
+if __name__ == '__main__':
+    # tree = generate_tree()
+    # print(len(tree))
+    # g = Gui(tree)
+    pass