PerseumAI

  1#!/usr/bin/env python3
  2#sudo apt-get install python3-tk
  3from tkinter import *
  4from tkinter import ttk
  5from tkinter import filedialog
  6from PIL import Image, ImageTk
  7from matplotlib.pyplot import text, title
  8from matplotlib.figure import Figure
  9import pattern_utils
 10import main as mn
 11import matplotlib.pyplot as plt
 12from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
 13import re
 14
 15"""Code for GUI of Perseum AI"""
 16
 17FG = '#ffffff'
 18FONT = 'Raleway'
 19BUTTON_BG = '#0C60DB'
 20MAIN_BG = "#20385C"
 21
 22class LandingWindow:
 23    """Landing window where the program starts"""
 24    def __init__(self, master):
 25        """Definition of constructor for landing page"""
 26        self.master = master
 27        self.master.geometry('800x600')
 28        self.master.configure(bg="#20385C")
 29        self.master.title('PerseumAI')
 30        self.frame = Frame(self.master, width=500, height=300, bg=MAIN_BG)
 31        self.image = Image.open('./resources/images/PerseumAI.PNG')
 32        self.logo = ImageTk.PhotoImage(self.image)
 33        self.logo_label = Label(self.frame, image=self.logo)
 34        self.button1 = Button(self.frame, text = 'Click here to start', command = self.nextWindow, font=FONT, bg=BUTTON_BG, fg='white', height=2, width=15, pady=5, activebackground="#69AAF5")
 35        
 36        self.frame.pack()
 37        self.frame.place(anchor='center', relx=0.5, rely=0.5)
 38        self.logo_label.pack()
 39        self.button1.pack(pady=10)
 40
 41    def nextWindow(self):
 42        """Method for advancing to next window"""
 43        self.frame.destroy()
 44        self.app = MenuWindow(self.master)
 45
 46class MenuWindow:
 47    """Menu window where the user specifies the parameters for the program"""
 48    def __init__(self, master):
 49        self.master = master
 50        self.companies = None
 51        pattern_types = ['Double top', 'Double bottom']
 52        self.selected_types = []
 53
 54        self.frame = Frame(self.master, height=2000, width=500, bg=MAIN_BG)
 55        self.patterns_type = Label(self.frame, text='Choose which patterns to find', font=(FONT, 18), fg=FG, bg=MAIN_BG, highlightthickness=0)
 56        self.types_frame = Frame(self.frame, height=200, bg=MAIN_BG)
 57        for type in pattern_types:
 58            value = BooleanVar(self.types_frame)
 59            pattern_type_dict = {
 60                'type': type,
 61                'value': value,
 62                'button': Checkbutton(self.types_frame, text=type, height=1, width=12, variable=value, font=FONT, bg="#69AAF5", activebackground="#69AAF5", highlightthickness=0, fg=MAIN_BG) #, font=FONT, variable=value, bg=MAIN_BG, fg=FG, activebackground="#69AAF5", highlightthickness=0
 63            }
 64            pattern_type_dict['button'].pack(side=LEFT, pady=15)
 65            self.selected_types.append(pattern_type_dict)
 66        self.empty_label = Label(self.frame, text='\n')
 67        self.year_label = Label(self.frame, text='Year to start counting from', font=FONT, bg=MAIN_BG, fg=FG)
 68        self.year_entry = Entry(self.frame)
 69        self.open_file_button = Button(self.frame, text = 'Open file', width = 25, command = self.openTxt, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
 70        self.warning_file_label = Label(self.frame, text='', font=FONT, bg=MAIN_BG, fg=FG)
 71        self.intensive_search_frame = Frame(self.frame, bg=MAIN_BG)
 72        self.intensive_search_value = BooleanVar(self.intensive_search_frame)
 73        self.intensive_search_check = Checkbutton(self.intensive_search_frame, text='Intensive search mode', height=1, width=18, variable=self.intensive_search_value, font=FONT, bg="#69AAF5", activebackground="#69AAF5", highlightthickness=0, fg=MAIN_BG) 
 74        self.run_button = Button(self.frame, text = 'Run', width = 25, command = self.runProgram, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
 75        self.quit_button = Button(self.frame, text = 'Quit', width = 25, command = self.closeWindow, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
 76       
 77        self.patterns_type.pack()
 78        self.year_label.pack()
 79        self.types_frame.pack()
 80        self.year_entry.pack(pady=5)
 81        self.open_file_button.pack(pady=5)
 82        self.warning_file_label.pack()
 83        self.intensive_search_frame.pack()
 84        self.intensive_search_check.pack()
 85        self.run_button.pack(pady=(100,5))
 86        self.quit_button.pack()
 87
 88        self.frame.pack(fill=BOTH, expand=True)
 89        self.frame.place(relx=.5, rely=.5, anchor='c')
 90
 91    def runProgram(self):
 92        """Execute the back-end program with the parametes given by the user"""
 93        if self.companies == None:
 94            self.warning_file_label.configure(text='Please select a file')
 95            return
 96        if not self.year_entry.get():
 97            return
 98        selected_types_set = set()
 99        for pattern_type in self.selected_types:
100            if (pattern_type['value'].get()):
101                if pattern_type['type'] == 'Double top':
102                    selected_types_set.add('double_top')
103                elif pattern_type['type'] == 'Double bottom':
104                    selected_types_set.add('double_bottom')
105        patterns_dictionary = pattern_utils.loadPatterns(15, selected_types_set)
106        historic_results = []
107        current_results = []
108        if not re.search("^\d{4}$", self.year_entry.get()):
109            raise Exception('Enter a valid year format %dddd')
110        for company in self.companies:
111            historic_results = historic_results + mn.trainHistoricDatabase(company, self.year_entry.get(), patterns_dictionary)
112            current_results = current_results + mn.findCurrentPatterns(company, patterns_dictionary, self.intensive_search_value.get())
113        tendency_results = pattern_utils.calculateTendencyProbability(historic_results, selected_types_set)
114        self.results_window = Toplevel(self.master)
115        self.app = ResultsWindow(self.results_window, historic_results, current_results, tendency_results)
116
117    def closeWindow(self):
118        """End the program by closing the window"""
119        self.master.destroy()
120
121    def openTxt(self):
122        """Read the txt file chose by the user"""
123        text_file = filedialog.askopenfile(initialdir='./', title="Open Text File", filetypes=(("Text Files", "*.txt"), ))
124        if text_file != None:
125            text_file = open(text_file.name, 'r')
126            input_text = text_file.read()
127            self.companies = self.parseTxt(input_text)
128            text_file.close()
129    
130    def parseTxt(self, text):
131        """Parse a given txt file"""
132        text = text.split()
133        result_companies = []
134        for word in text:
135            if re.search(",$", word):
136                result_companies.append(word[:-1])
137            else:
138                result_companies.append(word)
139        return result_companies           
140
141class ResultsWindow:
142    """Window where the user can see the tendency results and choose to see historic patterns or current patterns"""
143    def __init__(self, master, historic_patterns, current_patterns, tendency_results):
144        self.historic_patterns = historic_patterns
145        self.current_patterns = current_patterns
146        self.tendency_results = tendency_results
147        self.master = master
148        self.master.geometry('1000x800')
149        self.master.configure(bg=MAIN_BG)
150        self.frame = Frame(self.master, bg=MAIN_BG)
151        temp_text = ''
152        for key, value in tendency_results.items():
153            if isinstance(value, float):
154                value = str(round(value)) + '%'
155            if key == 'double_top':
156                temp_text += f'Double top: {value}\n'
157            elif key == 'double_bottom':
158                temp_text += f'Double bottom: {value}\n'
159            elif key == 'triple_top':
160                temp_text += f'Triple top: {value}\n' 
161
162        self.title_text = Label(self.frame, text='Achieve objective probability', font=(FONT,18), fg=FG, bg=MAIN_BG, highlightthickness=0)
163        self.tendency_results_text = Label(self.frame, text=temp_text, font=FONT, fg=FG, bg=MAIN_BG, highlightthickness=0) #Añadir otra label comno esta para el titulo
164        self.buttons_frame = Frame(self.frame, highlightthickness=0, bg=MAIN_BG)
165        self.show_historic = Button(self.buttons_frame, text = 'Show historic patterns', command = self.showHistoricPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5", fg='white', height=3, width=20)
166        self.show_current = Button(self.buttons_frame, text = 'Show current patterns', command = self.showCurrentPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5",  fg='white', height=3, width=20)
167        self.quit_button = Button(self.frame, text = 'Quit', width = 25, command = self.closeWindow, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
168        
169        self.title_text.pack(pady=(0,10))
170        self.tendency_results_text.pack(pady=(0,125))
171        self.buttons_frame.pack()
172        self.show_current.pack(side=RIGHT, padx=(125, 40), anchor='w')
173        self.show_historic.pack(side=LEFT, padx=(40, 125), anchor='e')
174        self.quit_button.pack(side=BOTTOM, anchor='s', pady=(200, 0))
175        self.frame.pack(fill=BOTH, expand=True)
176        self.frame.place(relx=.5, rely=.5, anchor='c')
177
178    def closeWindow(self):
179        """Destroy the window"""
180        self.master.destroy()
181
182    def showHistoricPatterns(self):
183        """Show the historic patterns that were found"""
184        self.frame.destroy()
185        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 0)
186    
187    def showCurrentPatterns(self):
188        """Show the current patterns that were found"""
189        self.frame.destroy()
190        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 1)
191
192class ShowPatternsWindow:
193    def __init__(self, master, results, mode):
194        self.results = results
195        self.master = master
196        self.master.configure(bg=MAIN_BG)
197        self.frame = Frame(self.master, bg=MAIN_BG)
198        self.canvas = Canvas(self.frame, bg=MAIN_BG)
199        self.scroll_bar = ttk.Scrollbar(self.frame, orient=VERTICAL, command=self.canvas.yview)
200        self.canvas.configure(yscrollcommand=self.scroll_bar.set)
201        self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
202        self.second_frame = Frame(self.canvas, bg=MAIN_BG)
203        self.canvas.create_window((0,0), window=self.second_frame, anchor="nw")
204        self.go_back_frame = Frame(self.canvas, bg=MAIN_BG)
205        self.go_back = Button(self.go_back_frame, text = 'Return', command = self.goBack, font=FONT, bg=BUTTON_BG, fg='white', height=1, width=20)
206        
207        self.frame.pack(fill=BOTH, expand=1)
208        self.canvas.pack(side=LEFT, fill=BOTH, expand=1)
209        self.scroll_bar.pack(side=RIGHT, fill=Y)
210        self.go_back_frame.pack(side=BOTTOM, fill=X)
211        self.go_back.pack(anchor='w', padx=5, pady=5)
212        if mode == 0:
213            self.showPatterns(results[0])
214        elif mode == 1:
215            self.showPatterns(results[1])
216            
217
218    def goBack(self):
219        """Go back to ResultsWindow"""
220        self.frame.destroy()
221        self.app = ResultsWindow(self.master, self.results[0], self.results[1], self.results[2])
222
223    def showPatterns(self, results):
224        """Show patterns given as a list"""
225        for pattern in results:
226            temp_frame = Frame(self.second_frame, bg=MAIN_BG)
227            fig = Figure(figsize = (9,5), dpi = 100)
228            plot1 = fig.add_subplot(111)
229            plot1.plot(pattern.dataframe_segment)
230            fig.suptitle(f'{pattern.company_name} {pattern.pattern_type} {pattern.starting_date[:10]} - {pattern.ending_date[:10]}')
231            canvas = FigureCanvasTkAgg(fig, master=temp_frame)
232            canvas.draw()
233            temp_frame.pack()
234            canvas.get_tk_widget().pack(side=LEFT, pady=10)
235            if pattern.tendency is True:
236                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="#40BD2E")
237                tendency = '✅'
238            elif pattern.tendency is False:
239                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="red")
240                tendency = '❌'
241            else:
242                continue
243            pattern_tendency_text.insert(INSERT, tendency)
244            pattern_tendency_text.pack(side=RIGHT, padx=20)
245
246            # toolbar = NavigationToolbar2Tk(canvas, self.second_frame)
247            # toolbar.update()
248            # canvas.get_tk_widget().pack()
249
250def main():
251    """Main function for GUI app"""
252    try:
253        root = Tk()
254        app = LandingWindow(root)
255        root.mainloop()
256    except Exception as err:
257        print(err)
258
259
260if __name__ == '__main__':
261    main()
class LandingWindow:
23class LandingWindow:
24    """Landing window where the program starts"""
25    def __init__(self, master):
26        """Definition of constructor for landing page"""
27        self.master = master
28        self.master.geometry('800x600')
29        self.master.configure(bg="#20385C")
30        self.master.title('PerseumAI')
31        self.frame = Frame(self.master, width=500, height=300, bg=MAIN_BG)
32        self.image = Image.open('./resources/images/PerseumAI.PNG')
33        self.logo = ImageTk.PhotoImage(self.image)
34        self.logo_label = Label(self.frame, image=self.logo)
35        self.button1 = Button(self.frame, text = 'Click here to start', command = self.nextWindow, font=FONT, bg=BUTTON_BG, fg='white', height=2, width=15, pady=5, activebackground="#69AAF5")
36        
37        self.frame.pack()
38        self.frame.place(anchor='center', relx=0.5, rely=0.5)
39        self.logo_label.pack()
40        self.button1.pack(pady=10)
41
42    def nextWindow(self):
43        """Method for advancing to next window"""
44        self.frame.destroy()
45        self.app = MenuWindow(self.master)

Landing window where the program starts

LandingWindow(master)
25    def __init__(self, master):
26        """Definition of constructor for landing page"""
27        self.master = master
28        self.master.geometry('800x600')
29        self.master.configure(bg="#20385C")
30        self.master.title('PerseumAI')
31        self.frame = Frame(self.master, width=500, height=300, bg=MAIN_BG)
32        self.image = Image.open('./resources/images/PerseumAI.PNG')
33        self.logo = ImageTk.PhotoImage(self.image)
34        self.logo_label = Label(self.frame, image=self.logo)
35        self.button1 = Button(self.frame, text = 'Click here to start', command = self.nextWindow, font=FONT, bg=BUTTON_BG, fg='white', height=2, width=15, pady=5, activebackground="#69AAF5")
36        
37        self.frame.pack()
38        self.frame.place(anchor='center', relx=0.5, rely=0.5)
39        self.logo_label.pack()
40        self.button1.pack(pady=10)

Definition of constructor for landing page

def nextWindow(self)
42    def nextWindow(self):
43        """Method for advancing to next window"""
44        self.frame.destroy()
45        self.app = MenuWindow(self.master)

Method for advancing to next window

class ResultsWindow:
142class ResultsWindow:
143    """Window where the user can see the tendency results and choose to see historic patterns or current patterns"""
144    def __init__(self, master, historic_patterns, current_patterns, tendency_results):
145        self.historic_patterns = historic_patterns
146        self.current_patterns = current_patterns
147        self.tendency_results = tendency_results
148        self.master = master
149        self.master.geometry('1000x800')
150        self.master.configure(bg=MAIN_BG)
151        self.frame = Frame(self.master, bg=MAIN_BG)
152        temp_text = ''
153        for key, value in tendency_results.items():
154            if isinstance(value, float):
155                value = str(round(value)) + '%'
156            if key == 'double_top':
157                temp_text += f'Double top: {value}\n'
158            elif key == 'double_bottom':
159                temp_text += f'Double bottom: {value}\n'
160            elif key == 'triple_top':
161                temp_text += f'Triple top: {value}\n' 
162
163        self.title_text = Label(self.frame, text='Achieve objective probability', font=(FONT,18), fg=FG, bg=MAIN_BG, highlightthickness=0)
164        self.tendency_results_text = Label(self.frame, text=temp_text, font=FONT, fg=FG, bg=MAIN_BG, highlightthickness=0) #Añadir otra label comno esta para el titulo
165        self.buttons_frame = Frame(self.frame, highlightthickness=0, bg=MAIN_BG)
166        self.show_historic = Button(self.buttons_frame, text = 'Show historic patterns', command = self.showHistoricPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5", fg='white', height=3, width=20)
167        self.show_current = Button(self.buttons_frame, text = 'Show current patterns', command = self.showCurrentPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5",  fg='white', height=3, width=20)
168        self.quit_button = Button(self.frame, text = 'Quit', width = 25, command = self.closeWindow, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
169        
170        self.title_text.pack(pady=(0,10))
171        self.tendency_results_text.pack(pady=(0,125))
172        self.buttons_frame.pack()
173        self.show_current.pack(side=RIGHT, padx=(125, 40), anchor='w')
174        self.show_historic.pack(side=LEFT, padx=(40, 125), anchor='e')
175        self.quit_button.pack(side=BOTTOM, anchor='s', pady=(200, 0))
176        self.frame.pack(fill=BOTH, expand=True)
177        self.frame.place(relx=.5, rely=.5, anchor='c')
178
179    def closeWindow(self):
180        """Destroy the window"""
181        self.master.destroy()
182
183    def showHistoricPatterns(self):
184        """Show the historic patterns that were found"""
185        self.frame.destroy()
186        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 0)
187    
188    def showCurrentPatterns(self):
189        """Show the current patterns that were found"""
190        self.frame.destroy()
191        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 1)

Window where the user can see the tendency results and choose to see historic patterns or current patterns

ResultsWindow(master, historic_patterns, current_patterns, tendency_results)
144    def __init__(self, master, historic_patterns, current_patterns, tendency_results):
145        self.historic_patterns = historic_patterns
146        self.current_patterns = current_patterns
147        self.tendency_results = tendency_results
148        self.master = master
149        self.master.geometry('1000x800')
150        self.master.configure(bg=MAIN_BG)
151        self.frame = Frame(self.master, bg=MAIN_BG)
152        temp_text = ''
153        for key, value in tendency_results.items():
154            if isinstance(value, float):
155                value = str(round(value)) + '%'
156            if key == 'double_top':
157                temp_text += f'Double top: {value}\n'
158            elif key == 'double_bottom':
159                temp_text += f'Double bottom: {value}\n'
160            elif key == 'triple_top':
161                temp_text += f'Triple top: {value}\n' 
162
163        self.title_text = Label(self.frame, text='Achieve objective probability', font=(FONT,18), fg=FG, bg=MAIN_BG, highlightthickness=0)
164        self.tendency_results_text = Label(self.frame, text=temp_text, font=FONT, fg=FG, bg=MAIN_BG, highlightthickness=0) #Añadir otra label comno esta para el titulo
165        self.buttons_frame = Frame(self.frame, highlightthickness=0, bg=MAIN_BG)
166        self.show_historic = Button(self.buttons_frame, text = 'Show historic patterns', command = self.showHistoricPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5", fg='white', height=3, width=20)
167        self.show_current = Button(self.buttons_frame, text = 'Show current patterns', command = self.showCurrentPatterns, font=(FONT,16), bg=BUTTON_BG, activebackground="#69AAF5",  fg='white', height=3, width=20)
168        self.quit_button = Button(self.frame, text = 'Quit', width = 25, command = self.closeWindow, font=FONT, fg=FG, bg=BUTTON_BG, activebackground="#69AAF5")
169        
170        self.title_text.pack(pady=(0,10))
171        self.tendency_results_text.pack(pady=(0,125))
172        self.buttons_frame.pack()
173        self.show_current.pack(side=RIGHT, padx=(125, 40), anchor='w')
174        self.show_historic.pack(side=LEFT, padx=(40, 125), anchor='e')
175        self.quit_button.pack(side=BOTTOM, anchor='s', pady=(200, 0))
176        self.frame.pack(fill=BOTH, expand=True)
177        self.frame.place(relx=.5, rely=.5, anchor='c')
def closeWindow(self)
179    def closeWindow(self):
180        """Destroy the window"""
181        self.master.destroy()

Destroy the window

def showHistoricPatterns(self)
183    def showHistoricPatterns(self):
184        """Show the historic patterns that were found"""
185        self.frame.destroy()
186        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 0)

Show the historic patterns that were found

def showCurrentPatterns(self)
188    def showCurrentPatterns(self):
189        """Show the current patterns that were found"""
190        self.frame.destroy()
191        self.app = ShowPatternsWindow(self.master, [self.historic_patterns, self.current_patterns, self.tendency_results], 1)

Show the current patterns that were found

class ShowPatternsWindow:
193class ShowPatternsWindow:
194    def __init__(self, master, results, mode):
195        self.results = results
196        self.master = master
197        self.master.configure(bg=MAIN_BG)
198        self.frame = Frame(self.master, bg=MAIN_BG)
199        self.canvas = Canvas(self.frame, bg=MAIN_BG)
200        self.scroll_bar = ttk.Scrollbar(self.frame, orient=VERTICAL, command=self.canvas.yview)
201        self.canvas.configure(yscrollcommand=self.scroll_bar.set)
202        self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
203        self.second_frame = Frame(self.canvas, bg=MAIN_BG)
204        self.canvas.create_window((0,0), window=self.second_frame, anchor="nw")
205        self.go_back_frame = Frame(self.canvas, bg=MAIN_BG)
206        self.go_back = Button(self.go_back_frame, text = 'Return', command = self.goBack, font=FONT, bg=BUTTON_BG, fg='white', height=1, width=20)
207        
208        self.frame.pack(fill=BOTH, expand=1)
209        self.canvas.pack(side=LEFT, fill=BOTH, expand=1)
210        self.scroll_bar.pack(side=RIGHT, fill=Y)
211        self.go_back_frame.pack(side=BOTTOM, fill=X)
212        self.go_back.pack(anchor='w', padx=5, pady=5)
213        if mode == 0:
214            self.showPatterns(results[0])
215        elif mode == 1:
216            self.showPatterns(results[1])
217            
218
219    def goBack(self):
220        """Go back to ResultsWindow"""
221        self.frame.destroy()
222        self.app = ResultsWindow(self.master, self.results[0], self.results[1], self.results[2])
223
224    def showPatterns(self, results):
225        """Show patterns given as a list"""
226        for pattern in results:
227            temp_frame = Frame(self.second_frame, bg=MAIN_BG)
228            fig = Figure(figsize = (9,5), dpi = 100)
229            plot1 = fig.add_subplot(111)
230            plot1.plot(pattern.dataframe_segment)
231            fig.suptitle(f'{pattern.company_name} {pattern.pattern_type} {pattern.starting_date[:10]} - {pattern.ending_date[:10]}')
232            canvas = FigureCanvasTkAgg(fig, master=temp_frame)
233            canvas.draw()
234            temp_frame.pack()
235            canvas.get_tk_widget().pack(side=LEFT, pady=10)
236            if pattern.tendency is True:
237                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="#40BD2E")
238                tendency = '✅'
239            elif pattern.tendency is False:
240                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="red")
241                tendency = '❌'
242            else:
243                continue
244            pattern_tendency_text.insert(INSERT, tendency)
245            pattern_tendency_text.pack(side=RIGHT, padx=20)
246
247            # toolbar = NavigationToolbar2Tk(canvas, self.second_frame)
248            # toolbar.update()
249            # canvas.get_tk_widget().pack()
ShowPatternsWindow(master, results, mode)
194    def __init__(self, master, results, mode):
195        self.results = results
196        self.master = master
197        self.master.configure(bg=MAIN_BG)
198        self.frame = Frame(self.master, bg=MAIN_BG)
199        self.canvas = Canvas(self.frame, bg=MAIN_BG)
200        self.scroll_bar = ttk.Scrollbar(self.frame, orient=VERTICAL, command=self.canvas.yview)
201        self.canvas.configure(yscrollcommand=self.scroll_bar.set)
202        self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
203        self.second_frame = Frame(self.canvas, bg=MAIN_BG)
204        self.canvas.create_window((0,0), window=self.second_frame, anchor="nw")
205        self.go_back_frame = Frame(self.canvas, bg=MAIN_BG)
206        self.go_back = Button(self.go_back_frame, text = 'Return', command = self.goBack, font=FONT, bg=BUTTON_BG, fg='white', height=1, width=20)
207        
208        self.frame.pack(fill=BOTH, expand=1)
209        self.canvas.pack(side=LEFT, fill=BOTH, expand=1)
210        self.scroll_bar.pack(side=RIGHT, fill=Y)
211        self.go_back_frame.pack(side=BOTTOM, fill=X)
212        self.go_back.pack(anchor='w', padx=5, pady=5)
213        if mode == 0:
214            self.showPatterns(results[0])
215        elif mode == 1:
216            self.showPatterns(results[1])
def goBack(self)
219    def goBack(self):
220        """Go back to ResultsWindow"""
221        self.frame.destroy()
222        self.app = ResultsWindow(self.master, self.results[0], self.results[1], self.results[2])

Go back to ResultsWindow

def showPatterns(self, results)
224    def showPatterns(self, results):
225        """Show patterns given as a list"""
226        for pattern in results:
227            temp_frame = Frame(self.second_frame, bg=MAIN_BG)
228            fig = Figure(figsize = (9,5), dpi = 100)
229            plot1 = fig.add_subplot(111)
230            plot1.plot(pattern.dataframe_segment)
231            fig.suptitle(f'{pattern.company_name} {pattern.pattern_type} {pattern.starting_date[:10]} - {pattern.ending_date[:10]}')
232            canvas = FigureCanvasTkAgg(fig, master=temp_frame)
233            canvas.draw()
234            temp_frame.pack()
235            canvas.get_tk_widget().pack(side=LEFT, pady=10)
236            if pattern.tendency is True:
237                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="#40BD2E")
238                tendency = '✅'
239            elif pattern.tendency is False:
240                pattern_tendency_text = Text(temp_frame, height=1, width=2, bg="red")
241                tendency = '❌'
242            else:
243                continue
244            pattern_tendency_text.insert(INSERT, tendency)
245            pattern_tendency_text.pack(side=RIGHT, padx=20)
246
247            # toolbar = NavigationToolbar2Tk(canvas, self.second_frame)
248            # toolbar.update()
249            # canvas.get_tk_widget().pack()

Show patterns given as a list

def main()
251def main():
252    """Main function for GUI app"""
253    try:
254        root = Tk()
255        app = LandingWindow(root)
256        root.mainloop()
257    except Exception as err:
258        print(err)

Main function for GUI app