def draw_utility(window, brb): fig_util = plt.figure(figsize=(9, 6), dpi=120) canvas_res = tkagg.FigureCanvasTkAgg(fig_util, master=window) plot_utility_monotonicity(brb, [[0, 1], [0, 1], [0, 1]], fig=fig_util) canvas_res.draw() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) toolbar_res = tkagg.NavigationToolbar2Tk(canvas_res, window) toolbar_res.update() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) btn_next = tk.Button(window, text="Next", command=lambda: quit(window)) btn_next.pack(side=tk.BOTTOM, fill=tk.X) return True
def __init__(self, frame, side='top', figsize=None, dpi=None, **kwargs): self.figsize = figsize self.dpi = dpi self.__frame = Tk.Frame(frame) self.__frame.pack(side=side) self.__figure = fg.Figure(figsize=self.figsize, dpi=self.dpi, facecolor='w') self.__canvas = tkagg.FigureCanvasTkAgg(self.__figure, self.__frame) self.__grid=[1,1] if 'grid' in kwargs: self.__grid = kwargs['grid'] else: self.axAni = self.__figure.add_subplot(111) self.__canvas.show() self.__canvas.get_tk_widget().pack(fill=Tk.BOTH, expand=1) self.__canvas._tkcanvas.pack(fill=Tk.BOTH, expand=1)
def draw_ranking(window, brb, paretofront): fig_3d = plt.figure(figsize=(8, 6), dpi=120) canvas_res = tkagg.FigureCanvasTkAgg(fig_3d, master=window) plot_3d_ranks_colored(brb, paretofront, fig=fig_3d) canvas_res.draw() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) toolbar_res = tkagg.NavigationToolbar2Tk(canvas_res, window) toolbar_res.update() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) btn_next = tk.Button(window, text="Next", command=lambda: quit(window)) btn_next.pack(side=tk.BOTTOM, fill=tk.X) return True
def initialize_canvas(self, use_labels): self.figure = matplotfig.Figure(figsize=(5, 2), dpi=100, tight_layout=True) # self.figure.patch.set_facecolor(self.master["background"]) self.figure.patch.set_facecolor("white") self.axes = self.figure.add_subplot(111) self.axes.get_yaxis().set_visible(False) if not use_labels: self.axes.get_xaxis().set_visible(False) else: # self.axes.xaxis.label.set_color(invert_color(self.master["background"], self)) self.axes.tick_params(axis="x", colors=invert_color( self.master["background"], self)) self.canvas = matplottk.FigureCanvasTkAgg(self.figure, self)
def __init__(self, master, *argvs, **kwargvs): WG.Widget.__init__(self, master, *argvs, **kwargvs) self.rows = self.getParamValue('rows', 3, **kwargvs) self.cols = self.getParamValue('cols', 2, **kwargvs) self.framerate = self.getParamValue('framerate', 44100, **kwargvs) # self.width = self.getParamValue('width', self.master.getWidget()['width'], **kwargvs) self.height= self.getParamValue('height', self.master.getWidget()['height'], **kwargvs) self.dpi = 99 self.figure= FG.Figure( figsize = (self.width / self.dpi, self.height / self.dpi), dpi = self.dpi, facecolor = '#EEEEEE' ) self.canvas= MBTK.FigureCanvasTkAgg(self.figure, master = self.master.getWidget()) self.canvas.show() self.canvas.get_tk_widget().place(x = 0, y = 0)
def BuildGraph(self): eval_total, eval_varialbes = self.tools.GetGraphVariablesType() for each_value_type in [eval_total] + list(eval_varialbes): each_graph = np_fig.Figure(figsize=(self.graph_GUI_each_width, 1), dpi=100) each_plot = each_graph.add_subplot(111) graph_canvas = mp_tkagg.FigureCanvasTkAgg(each_graph, self.graph_frame) graph_canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH) self.graph_plots[each_value_type] = each_plot self.graph_animations.append( mp_ani.FuncAnimation(each_graph, self.GraphAnimation, fargs=(each_value_type, ), interval=1000))
def draw_parallel(candidates, obj_names=["INCOME", "CO2", "CHSI"]): print(candidates) window = tk.Tk() window.title(f"Candidate comparison") fig_par = plt.figure(figsize=(7, 4), dpi=120) canvas_res = tkagg.FigureCanvasTkAgg(fig_par, master=window) fig_par.suptitle("Candidate comparison") ax = fig_par.add_subplot(111) df = pandas.DataFrame( data=candidates, index=[f"Candidate {i+1}" for i in range(len(candidates))], columns=obj_names).reset_index() if len(candidates) == 5: parallel_coordinates(df, "index", ax=ax, colors=["red", "green", "grey", "blue", "orange"]) else: parallel_coordinates(df, "index", ax=ax) ax.set_ylim(0, 1) ax.set_yticks([0, 0.25, 0.5, 0.75, 1]) ax.set_yticklabels(["nadir", "", "", "", "ideal"]) box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.65, box.height]) legend_x = 1 legend_y = 0.5 ax.legend(loc="center left", bbox_to_anchor=(legend_x, legend_y)) canvas_res.draw() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) toolbar_res = tkagg.NavigationToolbar2Tk(canvas_res, window) toolbar_res.update() canvas_res.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) btn_close = tk.Button(window, text="Close", command=lambda: window.destroy()) btn_close.pack(side=tk.BOTTOM, fill=tk.X) return True
def plot_plot(self): self.parent.title('Plot of data') self.pack(fill=tk.BOTH, expand=1) self.canvas = tk.Canvas(self) self.fig = mplfig.Figure(figsize=(4, 4)) self.subplot = self.fig.add_subplot(111) self.subplot.set_ylabel('Y') self.subplot.set_xlabel('X') self.subplot.plot(self.data[1], self.data[0], color='k') self.subplot.scatter(self.data[1], self.data[0], color='k') self.canvas = tkagg.FigureCanvasTkAgg(self.fig, master=self.parent) self.subplot.grid(True) # self.ax.set_xticklabels([]) # self.ax.set_yticklabels([]) self.canvas.get_tk_widget().pack() self.canvas.draw()
def plot(self): canvas = tkagg.FigureCanvasTkAgg(self.figure, master=self.window) wcanvas = canvas.get_tk_widget() wcanvas.config(width=1000, height=300) wcanvas.pack(side=tk.TOP, expand=True, fill=tk.BOTH) toolbar = tkagg.NavigationToolbar2TkAgg(canvas, self.window) toolbar.update() self.output = tk.StringVar() label = tk.Label(self.window, textvariable=self.output, bg="white", fg="red", bd=2) label.pack(side=tk.RIGHT, expand=True, fill=tk.X) wcanvas.pack(side=tk.TOP, expand=True, fill=tk.BOTH) canvas.draw() # Print task type using mouse clicks or motion. if self.motion: fig.canvas.mpl_connect('motion_notify_event', self.onclick) else: fig.canvas.mpl_connect('button_press_event', self.onclick)
def __init__(self, add_subplot=True, root=None, **kwargs): args = kwargs figure = matplotlib.pyplot.figure(figsize=(10,6), dpi=100) figure.set_facecolor('white') axis = figure.add_subplot(111) if add_subplot else None self.figure, self.axis = figure, axis window = Tk.Tk() if root is None else Tk.Toplevel(root) figure_frame = ttk.Frame(window) canvas = backend.FigureCanvasTkAgg(figure, master=figure_frame) canvas._tkcanvas.config(highlightthickness=0, width=1000, height=600) toolbar = backend.NavigationToolbar2Tk(canvas, figure_frame) toolbar.pack(side=Tk.TOP, fill=Tk.X) canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) toolbar.update() figure_frame.grid(column=0, row=0, sticky=(Tk.N, Tk.S, Tk.E, Tk.W)) window.columnconfigure(0, weight=1) window.rowconfigure(0, weight=1) self.window, self.canvas, self.toolbar = window, canvas, toolbar self.figure_frame = figure_frame
def add_canvas(figure, container): """Add the figure and toolbar to GUI. Args: figure (matplotlib.Figure): The figure object to visualize. container: The GUI part where the figure is shown. """ canvas = tk_backend.FigureCanvasTkAgg(figure, master=container) canvas.draw() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=True) # NavigationToolbar2TkAgg is deprecated since matplotlib 2.2, # NavigationToolbar2Tk should be used and is only available in new version. toolbar = tk_backend.NavigationToolbar2Tk(canvas, container) \ if hasattr(tk_backend, 'NavigationToolbar2Tk') \ else tk_backend.NavigationToolbar2TkAgg(canvas, container) toolbar.update() canvas._tkcanvas.pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=True) pyplot.close(figure.number)
def createWidgets(self): self.radioVar = tkinter.IntVar(self, 0) labelHeader = tkinter.Label(self, text="Playlist", font=("Verdana", 12)) labelHeader.grid(row=0, column=0, sticky="nsw") muHeader = tkinter.Label(self, text="Mu", font=("Verdana", 12)) muHeader.grid(row=0, column=1, sticky="ns", padx=5) sigmaHeader = tkinter.Label(self, text="Sigma", font=("Verdana", 12)) sigmaHeader.grid(row=0, column=2, sticky="ns", padx=5) mmrHeader = tkinter.Label(self, text="TrueSkill", font=("Verdana", 12)) mmrHeader.grid(row=0, column=3, sticky="ns", padx=5) mmrDiffHeader = tkinter.Label(self, text="TS change", font=("Verdana", 12)) mmrDiffHeader.grid(row=0, column=4, columnspan=2, sticky="ns") self.rows[ROW_UNRANKED] = self.addRow("Unranked", ROW_UNRANKED, 0) self.rows[ROW_RANKED_DUEL] = self.addRow("Ranked Duel", ROW_RANKED_DUEL, 10) self.rows[ROW_RANKED_DOUBLES] = self.addRow("Ranked Doubles", ROW_RANKED_DOUBLES, 11) self.rows[ROW_RANKED_SOLO_STANDARD] = self.addRow( "Ranked Solo Standard", ROW_RANKED_SOLO_STANDARD, 12) self.rows[ROW_RANKED_STANDARD] = self.addRow("Ranked Standard", ROW_RANKED_STANDARD, 13) figure = mplfig.Figure(figsize=(5, 3), dpi=100, frameon=False) self.plot = figure.add_subplot(1, 1, 1) self.canvas = mpltk.FigureCanvasTkAgg(figure, self) self.canvas.show() self.canvas.get_tk_widget().grid(row=0, column=6, rowspan=6) self.plotSizeRadioVar = tkinter.IntVar(self, 20) self.createPlotSizeWidgets()
def __initIonsFrame(self): self.ion_frame = tk.Frame( self.root_frame, bd=1, relief="raised" ) self.ion_frame.pack( side="left", fill="y", ) self.ion_fig = plt.Figure() self.ion_ax = self.ion_fig.add_subplot(111) self.ion_canvas = tkagg.FigureCanvasTkAgg(self.ion_fig, self.ion_frame) self.ion_toolbar = tkagg.NavigationToolbar2Tk( self.ion_canvas, self.ion_frame ) self.ion_canvas.get_tk_widget().pack( fill='both', expand=True ) self.getAxisType() self.ion_ax.set_title("Ions")
def __initAggregatesFrame(self): self.aggregate_frame = tk.Frame( self.root_frame, bd=1, relief="raised" ) self.aggregate_frame.pack( side="left", fill="both", expand=True ) self.aggregate_fig = plt.Figure() self.aggregate_ax = self.aggregate_fig.add_subplot(111) self.aggregate_canvas = tkagg.FigureCanvasTkAgg(self.aggregate_fig, self.aggregate_frame) self.aggregate_canvas.get_tk_widget().pack( fill='both', expand=True ) self.aggregate_toolbar = tkagg.NavigationToolbar2Tk( self.aggregate_canvas, self.aggregate_frame ) default_release = self.aggregate_toolbar.release def release(event): default_release(event) self.refresh() self.aggregate_toolbar.release = release self.aggregate_ax.set_xlim( [ np.min(self.dataset.anchors["RT"]), np.max(self.dataset.anchors["RT"]), ] ) self.aggregate_ax.set_ylim( [ np.min(self.dataset.anchors["DT"]), np.max(self.dataset.anchors["DT"]), ] ) self.aggregate_ax.set_xlabel("RT") self.aggregate_ax.set_ylabel("DT") self.aggregate_ax.set_title("Aggregates") def onclick(event): if (event is None) or (not event.dblclick): return self.dataset.updateSelectedNodes(self, event) self.dataset.plotSelectedNodes(self) self.dataset.plotIons(self) self.refreshAggregateCanvas() self.refreshIonCanvas() self.aggregate_canvas.mpl_disconnect(self.click_connection) self.click_connection = self.aggregate_canvas.mpl_connect( 'button_press_event', onclick ) self.click_connection = self.aggregate_canvas.mpl_connect( 'button_press_event', onclick )
def __init__(self) -> None: """ Initializer. """ self.window = tk.Tk() self.window.title("Bounded Wavefunction in 2D") colour = "#F0F0F0" constant = Constant() x = np.linspace(constant.x0, constant.L + constant.x0, constant.N) # Defaults potential = "(x)**2/2" psi = np.exp(-0.5 * ((x - 0.25) / 0.05)**2) # Other # potential = rect(8*x) # psi = np.exp(-0.5*((x-0.25)/0.05)**2 - 160j*x*np.pi) # Initialize the inherited animation object QuantumAnimation.__init__(self, function=psi, potential=potential) self.canvas = backend_tkagg.FigureCanvasTkAgg(self.figure, master=self.window) self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=20, columnspan=2) # self.canvas.get_tk_widget().bind("<B1-Motion>", self.sketch) # self.canvas.get_tk_widget().bind("<ButtonRelease-1>", self.sketch) # self.canvas.get_tk_widget().bind("<MouseWheel>", # self.mouse_wheel_handler) # self.canvas.get_tk_widget().bind("<Button-4>", # self.mouse_wheel_handler) self.canvas.get_tk_widget().bind( # "<Button-5>", self.mouse_wheel_handler) self.figure.patch.set_facecolor(colour) # Show Probability Distribution/Wavefunction change_view(self.window, commands=[self.change_view_to_pd, self.change_view_to_wf]) # Change energy add_energy_level_dropdown(self.window, command=self.mouse_menu_handler) # Measurement measurement_label = tk.Label(self.window, text='Measurement') measurement_label.grid(row=7, column=3, sticky=tk.E + tk.W + tk.S, padx=(10, 10)) add_measurement_button(self.window, text='Energy', row=8, column=3, command=self.measure_energy) add_measurement_button(self.window, text='Position', row=8, column=4, command=self.measure_position) add_measurement_button(self.window, text='Momentum', row=8, column=5, command=self.measure_position) # Mouse menu tuple self.mouse_menu_tuple = ("Reshape Wavefunction", "Reshape Wavefunction in Real Time", "Select Energy Level", "Reshape Potential V(x)") # Mouse menu string # self.mouse_menu_string = tk.StringVar(self.window) # self.mouse_menu_string.set("Reshape Wavefunction") # self.mouse_menu = tk.OptionMenu( # self.window, # self.mouse_menu_string, # *self.mouse_menu_tuple, # command=self.mouse_menu_handler) # self.mouse_menu.grid(row=8, column=3, # columnspan=2, # sticky=tk.W + tk.E + tk.N, # padx=(10, 10)) # Wavefunction entry field # self.enter_function_label = tk.Label( # self.window, # text="Enter Wavefunction \u03C8(x)") # # self.enter_function_label.grid(row=9, column=3, # columnspan=2, # sticky=tk.E + tk.W + tk.S, # padx=(10, 10)) # self.enter_function = tk.Entry(self.window) # self.enter_function.bind( # "<Return>", # self.update_wavefunction_by_name) # self.enter_function.grid(row=10, column=3, # columnspan=2, # sticky=tk.W + tk.E + tk.N + tk.S, # padx=(11, 11)) # Update wavefunction button b2 = tk.Button(self.window, text='OK', command=self.update_wavefunction_by_name) self.update_wavefunction_button = b2 self.update_wavefunction_button.grid(row=11, column=3, columnspan=2, sticky=tk.N + tk.W + tk.E, padx=(10, 10)) # Right click Menu self.menu = tk.Menu(self.window, tearoff=0) # self.menu.add_command(label="Measure Position", # command=self.measure_position) # self.menu.add_command(label="Measure Momentum", # command=self.measure_momentum) # self.menu.insert_separator(3) # self.menu.add_command(label="Reshape Wavefunction", # command=self.rightclick_reshape_wavefunction) # self.menu.add_command(label="Reshape Potential", # command=self.rightclick_reshape_potential) # self.menu.add_command(label="Select Energy Level", # command=self.rightclick_select_energylevel) # self.menu.insert_separator(7) # self.menu.add_command(label="Toggle Show Energy Levels", # command=self.rightclick_toggle_energylevel) # self.menu.add_command(label="Toggle Expectation Values", # command=self.toggle_expectation_values) # self.menu.insert_separator(9) # self.menu.add_command(label="Higher Stationary State", # command=self.higher_energy_eigenstate) # self.menu.add_command(label="Lower Stationary State", # command=self.lower_energy_eigenstate) # self.window.bind("<ButtonRelease-3>", self.popup_menu) # self.window.bind("<Up>", self.higher_energy_eigenstate) # self.window.bind("<Down>", self.lower_energy_eigenstate) # self.window.bind("<Control>", lambda *arg: print("ctrl printed")) self.sliders1 = [] self.sliders1_count = -1 self.sliders2 = [] self.sliders2_count = -1 self.clear_wavefunction_button = None self.potential_menu_dict = { "Infinite Square Well": "0", "Simple Harmonic Oscillator": "x**2/2", "Barrier in SHO": "x**2 + rect(150*x)/10", # "Potential Barrier": "10*rect(32*x)", # "Double stepped potential": # "1/4 - (Sum(rect(4*b*a*(x-0.07)), " # "(b, 1, 5)) + Sum(rect(4*b*a*(x+0.07))," # "(b, 1, 5)))/20", "Potential Well": "-rect(4*x)/2", # "Potential Well and Barrier": # "-2*rect(16*(x+1/4)) + 2*rect(16*(x-1/4))", # "Coulomb": "-1/(100*sqrt(x**2))", "Double Well": "(1-rect((21/10)*(x-1/4))-rect((21/10)*(x+1/4)))/10", # "Double Well 2": "(1-rect(2*x)+rect(50*x)/10)/5", # "Double Well 3": "1/10-a*rect(2*k1*x)/10 + b*rect(50*x)/15", # "Many Wells":"a*(1/60)*Sum(rect(150*b*(x-i*0.1+0.5)),(i, 0, 10))", "Many Wells": "a*0.017*Sum(rect(150*b*(x-i*0.1+0.5)), (i, 0, 10))", # "Simple Harmonic Oscillators": # "Sum(rect(int(4*l)*(x+0.8725 - j/int(4*l)))*" # "(2*(x+0.8725 - j/int(4*l)))**2, (j, 1, 10))", "Triangular Well": "sqrt(x**2)" } self.potential_menu_string = tk.StringVar(self.window) self.potential_menu_string.set("Choose Preset Potential V(x)") self.previous_potential_menu_string = "Choose Preset Potential V(x)" self.potential_menu = None self.enter_potential_label = None self.enter_potential = None self.update_potential_button = None self.slider_speed_label = None self.slider_speed = None self.quit_button = None self.set_widgets_after_enter_wavefunction(init_call=True) self.loop() # Store the animation speed before a pause self.fpi_before_pause = None self.scale_y = 0.0 self.potential_is_reshaped = False
def __init__(self, master): self.master = master master.title('ExPaND') default_font = font.nametofont("TkDefaultFont") default_font.configure(size=8) # Model visualization self.figure = mplfig.Figure(figsize=(7, 7), dpi=100) self.ax = self.figure.add_subplot(111) self.ax.tick_params(axis='both', which='both', bottom=False, labelbottom=False, left=False, labelleft=False) self.figure.subplots_adjust(left=0, bottom=0.02, right=1, top=0.98, wspace=0, hspace=0) self.canvas = tkagg.FigureCanvasTkAgg(self.figure, self.master) self.canvas.get_tk_widget().grid(row=1, column=4, columnspan=1, rowspan=10) self.toolbar_frame = tk.Frame(self.master) self.toolbar_frame.grid(row=12, column=4, columnspan=1) self.toolbar = tkagg.NavigationToolbar2Tk(self.canvas, self.toolbar_frame) # Parameters # Start date self.start = tk.IntVar() self.start.set(4500) self.start_label = tk.Label(master, text='Start date (BP):') self.start_label.grid(row=3, column=1) self.start_entry = tk.Entry(master, textvariable=self.start) self.start_entry.config(width=10) self.start_entry.grid(row=3, column=2, columnspan=2) # Start coordinates self.lon = tk.DoubleVar() self.lon.set(-65.77) self.lat = tk.DoubleVar() self.lat.set(7.82) self.coords_label = tk.Label(master, text='Origin (Lon/Lat):') self.coords_label.grid(row=4, column=1) self.lon_entry = tk.Entry(master, textvariable=self.lon) self.lon_entry.config(width=5) self.lon_entry.grid(row=4, column=2) self.lat_entry = tk.Entry(master, textvariable=self.lat) self.lat_entry.config(width=5) self.lat_entry.grid(row=4, column=3) # K* self.k = tk.Scale(master, label='K* (persons/100 km2)', from_=20, to=100, resolution=20, orient=tk.HORIZONTAL, length=200) self.k.grid(row=5, column=1, columnspan=3) # Fission threshold self.fiss = tk.Scale(master, label='Fission threshold', from_=50, to=300, resolution=50, orient=tk.HORIZONTAL, length=200) self.fiss.grid(row=6, column=1, columnspan=3) # Catchment self.catch = tk.Scale(master, label='Catchment (km)', from_=10, to=30, resolution=10, orient=tk.HORIZONTAL, length=200) self.catch.grid(row=7, column=1, columnspan=3) # Leap distance self.leap = tk.Scale(master, label='Leap distance (km)', from_=0, to=300, resolution=50, orient=tk.HORIZONTAL, length=200) self.leap.grid(row=8, column=1, columnspan=3) # Permanence self.perm = tk.Scale(master, label='Permanence (years)', from_=10, to=30, resolution=10, orient=tk.HORIZONTAL, length=200) self.perm.grid(row=9, column=1, columnspan=3) # Controls self.setup_button = tk.Button(master, text='Setup', width=10, command=self.setup_model) self.setup_button.grid(row=1, column=1) self.run_button = tk.Button(master, text='Run', width=10, command=self.run_model) self.run_button.grid(row=1, column=2) self.stop_button = tk.Button(master, text='Stop', width=10, command=self.stop) self.stop_button.grid(row=1, column=3) self.iter_thousand_button = tk.Button(master, text='▶ 1000 yrs', width=10, command=self.iter_thousand) self.iter_thousand_button.grid(row=2, column=1) self.write_button = tk.Button(master, text='Write', width=10, command=self.write_model) self.write_button.grid(row=2, column=2) self.eval_button = tk.Button(master, text='Evaluate', width=10, command=self.eval_model) self.eval_button.grid(row=2, column=3) # South America elevation map as a background self.basemap = np.vstack( np.loadtxt('./layers/ele.asc', skiprows=6).astype(float)) self.basemap[self.basemap == -9999] = np.nan self.setup_model()
def __init__(self,Master,TestMatrix,Status): self.Status = Status self.TestMatrix = TestMatrix self.Status = Status self.PlotFrame = pd.DataFrame() # Window size WinWidth = 850 WinHeight = 480 #********************** PLOT VARIABLES AND CONTROL FRAME ********************** # List box size defaultWidth = 10 defaultHeight = 20 # Create the main window MainWindow = tk.Frame(Master, width=WinWidth, height=WinHeight) Master.title('PLOT') MainWindow.pack() # Window location xpos = 5 ypos = 5 # Create the subframe Subframe = tk.Frame(Master, relief=tk.GROOVE, borderwidth=0) # Add labels XLabel = tk.Label(Subframe, text='X') YLabel = tk.Label(Subframe, text='Y') ZLabel = tk.Label(Subframe, text='Z') Blank = tk.Label(Subframe, text='') GroupLabel = tk.Label(Subframe, text='GROUP') # Add list box self.GroupBox = tk.Listbox(Subframe,width=defaultWidth,height=defaultHeight,exportselection=0,selectmode=tk.MULTIPLE) self.XBox = tk.Listbox(Subframe,width=defaultWidth,height=defaultHeight,exportselection=0) self.YBox = tk.Listbox(Subframe,width=defaultWidth,height=defaultHeight,exportselection=0) self.ZBox = tk.Listbox(Subframe,width=defaultWidth,height=defaultHeight,exportselection=0) # Add buttons PlotButton = tk.Button(Subframe, text='PLOT',justify=tk.CENTER, command=self.Plot, width = int(defaultWidth)) ClearZSelButton = tk.Button(Subframe, text='CLEAR Z',justify=tk.CENTER, command=self.ClearZSel, width = int(defaultWidth)) # Add check button self.IncludeHull = tk.IntVar() self.IncludeHull.set(1) HullCheck = tk.Checkbutton(Subframe, text='CONVEX HULL', variable=self.IncludeHull) # Grid the items GroupLabel.grid( row=0, column=0) XLabel.grid( row=0, column=1) YLabel.grid( row=0, column=2) ZLabel.grid( row=0, column=3) self.GroupBox.grid( row=1, column=0)#, sticky='WE') self.XBox.grid( row=1, column=1)#, sticky='WE') self.YBox.grid( row=1, column=2)#, sticky='WE') self.ZBox.grid( row=1, column=3)#, sticky='WE') Blank.grid( row=2, column=0) HullCheck.grid( row=3, column=0) PlotButton.grid( row=4, column=0) ClearZSelButton.grid( row=2, column=3) # Place frame Subframe.place(x=xpos, y=ypos) #********************** PLOT GRAPH FRAME ********************** # Frame location xpos = 430 ypos = 10 # Plot size PlotWidth = 4 PlotHeight = 4 # Create the subframe Subframe = tk.Frame(Master, relief=tk.GROOVE, borderwidth=0) # Create figure and canvas self.DataFigure = mplfig.Figure(figsize=(PlotWidth,PlotHeight), dpi=100) self.PlotCanvas = tkagg.FigureCanvasTkAgg(self.DataFigure,master=Subframe) self.PlotCanvas.draw() self.DataGraph = self.DataFigure.add_subplot(111, projection='3d') #self.DataGraph.grid(True) #self.DataFigure.set_tight_layout(True) self.PlotCanvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) # Place the subframe Subframe.place(x=xpos, y=ypos) # Load variables self.LoadVars() # Marker array self.Markers = np.array(['^','s','P','*','D','o']) self.MarkersOG = self.Markers # Used to reset the marker array
def __init__(self, master): self.master = master master.title('Swidden Farming') # Model visualization self.figure = mplfig.Figure(figsize=(6, 6), dpi=100) self.ax = self.figure.add_subplot(111) self.canvas = tkagg.FigureCanvasTkAgg(self.figure, self.master) self.canvas.get_tk_widget().grid(row=1, column=3, columnspan=6, rowspan=12) self.cmap, self.norm = from_levels_and_colors( [1, 2, 3, 4, 5, 6, 7, 8, 9], [ 'forestgreen', 'crimson', 'mediumseagreen', 'tab:pink', 'tab:brown', 'mediumpurple', 'palegreen', 'white' ]) # Controls self.setup_button = tk.Button(master, text='Setup', command=self.setup_model) self.setup_button.grid(row=1, column=1) self.run_button = tk.Button(master, text='Run', command=self.run_model) self.run_button.grid(row=1, column=2) self.pause_button = tk.Button(master, text='Pause', command=self.pause_model) self.pause_button.grid(row=1, column=3) self.step_button = tk.Button(master, text='Step', command=self.step_model) self.step_button.grid(row=1, column=4) # Parameters self.init_households_slider = tk.Scale(master, from_=1, to=50, orient=tk.HORIZONTAL, label='Initial households') self.init_households_slider.grid(row=2, column=1) self.fission_energy_slider = tk.Scale(master, from_=100, to=200, orient=tk.HORIZONTAL, label='Fission energy') self.fission_energy_slider.set(150) self.fission_energy_slider.grid(row=3, column=1) self.swidden_radius_slider = tk.Scale(master, from_=1, to=20, orient=tk.HORIZONTAL, label='Swidden radius') self.swidden_radius_slider.set(12) self.swidden_radius_slider.grid(row=4, column=1) self.harvest_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Harvest rate') self.harvest_rate_slider.set(12) self.harvest_rate_slider.grid(row=5, column=1) self.farm_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Farm cost') self.farm_rate_slider.set(3) self.farm_rate_slider.grid(row=6, column=1) self.clearing_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Clearing cost') self.clearing_rate_slider.set(3) self.clearing_rate_slider.grid(row=7, column=1) self.max_fallow_slider = tk.Scale(master, from_=1, to=40, orient=tk.HORIZONTAL, label='Max fallow') self.max_fallow_slider.set(20) self.max_fallow_slider.grid(row=8, column=1) self.move_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Move threshhold') self.move_rate_slider.set(50) self.move_rate_slider.grid(row=2, column=2) self.move_cost_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Move cost') self.move_cost_rate_slider.set(2) self.move_cost_rate_slider.grid(row=3, column=2) self.fert_loss_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Fertility loss') self.fert_loss_slider.set(20) self.fert_loss_slider.grid(row=4, column=2) self.restore_rate_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Restore rate') self.restore_rate_slider.set(2) self.restore_rate_slider.grid(row=5, column=2) self.bad_years_slider = tk.Scale(master, from_=1, to=100, orient=tk.HORIZONTAL, label='Bad years') self.bad_years_slider.set(20) self.bad_years_slider.grid(row=6, column=2) self.innovation_rate_slider = tk.Scale(master, from_=0, to=500, orient=tk.HORIZONTAL, label='Innovation rate') self.innovation_rate_slider.set(500) self.innovation_rate_slider.grid(row=7, column=2) self.adaptive = tk.BooleanVar() self.adaptive_check = tk.Checkbutton(master, text='Adaptive', variable=self.adaptive) self.adaptive_check.grid(row=8, column=2) self.transfer = tk.BooleanVar() self.transfer_check = tk.Checkbutton(master, text='Transfer ownership', variable=self.transfer) self.transfer_check.grid(row=9, column=2) self.running = False
def __init__(self) -> None: """ This is the constructor. """ # Initialize the parent class NonLinearVectorField2D.__init__(self) # Primary Tkinter GUI self.window = tk.Tk() self.window.title("Linear Vector Field in 2D") self.window.configure() # Canvas # A short example of how to integrate a Matplotlib animation into a # Tkinter GUI is given here: # https://stackoverflow.com/a/21198403 # [Answer by HYRY: https://stackoverflow.com/users/772649/hyry] # Link to question: https://stackoverflow.com/q/21197728 # [Question by user3208454: # https://stackoverflow.com/users/3208454/user3208454] self.canvas = backend_tkagg.FigureCanvasTkAgg( self.figure, master=self.window ) maxrowspan = 18 self.canvas.get_tk_widget().grid( row=0, column=0, rowspan=maxrowspan, columnspan=3) self._canvas_height = self.canvas.get_tk_widget().winfo_height() self.canvas.get_tk_widget().bind("<B1-Motion>", self.mouse_listener) # Right click menu self.menu = tk.Menu(self.window, tearoff=0) self.menu.add_command(label="Use Forward-Euler", command=lambda *args: self.particle.set_method( "Forward-Euler")) self.menu.add_command(label="Use Runge-Kutta", command=lambda *args: self.particle.set_method( "Runge-Kutta")) self.window.bind("<ButtonRelease-3>", self.popup_menu) # Thanks to stackoverflow user rudivonstaden for # giving a way to get the colour of the tkinter widgets: # https://stackoverflow.com/questions/11340765/ # default-window-colour-tkinter-and-hex-colour-codes # # https://stackoverflow.com/q/11340765 # [Question by user user2063: # https://stackoverflow.com/users/982297/user2063] # # https://stackoverflow.com/a/11342481 # [Answer by user rudivonstaden: # https://stackoverflow.com/users/1453643/rudivonstaden] # colour = self.window.cget('bg') if colour == 'SystemButtonFace': colour = "#F0F0F0" # Thanks to stackoverflow user user1764386 for # giving a way to change the background colour of a plot. # # https://stackoverflow.com/q/14088687 # [Question by user user1764386: # https://stackoverflow.com/users/1764386/user1764386] # self.figure.patch.set_facecolor(colour) self._zoom = False self._mouse_action = 2 # self.mouse_dropdown_dict = {"Move Plot Around": 1, # "Plot Trajectories": 2} # self.mouse_dropdown_string = tk.StringVar(self.window) # self.mouse_dropdown_string.set("Set Mouse...") # self.mouse_dropdown = tk.OptionMenu( # self.window, # self.mouse_dropdown_string, # *tuple(key for key in self.mouse_dropdown_dict), # command=self.set_mouse_action # ) # self.mouse_dropdown.grid( # row=0, column=3, padx=(10, 10), pady=(0, 0) # ) # self.canvas.get_tk_widget().bind_all("<MouseWheel>", self.zoom) # self.canvas.get_tk_widget().bind_all("<Button-4>", self.zoom) # self.canvas.get_tk_widget().bind_all("<Button-5>", self.zoom) self.preset_dropdown_dict = { "Linear": ["a*x - b*y + k1", "c*x + d*y + k2"], "Pendulum 1": ["y", "5*a*sin(k*x/2)"], "Pendulum 2": ["y", "5*a*sin(k*x/2)-b*y"], # "Rescaled Lotka–Volterra": ["a*(x+10)/2 - b*(x+10)*(y+10)/2", # "d*(x+10)*(y+10)/4 - e*(y+10)/2"] "Lotka–Volterra": ["10*a*x/2 - 3*b*x*y/2", "6*d*x*y/4 - 10*e*y/2"] } self.preset_dropdown_string = tk.StringVar(self.window) self.preset_dropdown_string.set("Choose Preset Vector Field") self.preset_dropdown = tk.OptionMenu( self.window, self.preset_dropdown_string, *tuple(key for key in self.preset_dropdown_dict), command=self.set_preset_dropdown ) self.preset_dropdown.grid( row=1, column=3, padx=(10, 10), pady=(0, 0)) # Enter vx self.entervxlabel = tk.Label(self.window, text="Enter f(x, y)") self.entervxlabel.grid( row=2, column=3, columnspan=2, sticky=tk.W + tk.E + tk.S, padx=(10, 10) ) self.enter_vx = tk.Entry(self.window) self.enter_vx.bind("<Return>", self.update_function_by_entry) self.enter_vx.grid( row=3, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N + tk.S, padx=(10, 10) ) self.enter_vx_button = tk.Button(self.window, text="OK", command=self.update_function_by_entry) self.enter_vx_button.grid( row=4, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N, padx=(10, 10) ) # Enter vy self.entervylabel = tk.Label(self.window, text="Enter g(x, y)") self.entervylabel.grid( row=5, column=3, columnspan=2, sticky=tk.W + tk.E + tk.S, padx=(10, 10) ) self.enter_vy = tk.Entry(self.window) self.enter_vy.bind("<Return>", self.update_function_by_entry) self.enter_vy.grid( row=6, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N + tk.S, padx=(10, 10) ) self.enter_vy_button = tk.Button(self.window, text="OK", command=self.update_function_by_entry) self.enter_vy_button.grid( row=7, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N, padx=(10, 10) ) # Sliders self.sliderslist = [] self.sliderslist_symbols = [] self.simulation_speed_slider = None self.quit_button = None self.set_sliders() self.set_preset_dropdown("Linear") self.preset_dropdown_string.set("Choose Preset Vector Field")
def method(data_dir: str, fname_po: str, fname_pf: str, objective_names: str = objective_names): # setup tkinter app instance window = tk.Tk() window.title(f"INFRINGER - Variant {variant}") # load pre-computed paretofront, nadir, ideal, and the scaler # the data is scaled between 0 and 1 using the nadir and ideal points nadir, ideal, paretofront, payoff, scaler = load_and_scale_data( data_dir, fname_po, fname_pf) nadir = np.squeeze(nadir) ideal = np.squeeze(ideal) # used to store a reference point given by the DM global reference_point reference_point = None # show ideal and nadir def make_table(row_names: [str], col_names: [str], data: np.ndarray, row=1, column=0): tframe = tk.Frame(window, height=700, width=500, borderwidth=2) tframe.grid(row=row, column=column) entry = tk.Label(tframe, text="", font=const_fontsetting) entry.grid(row=0, sticky="we") # set row names for i, name in enumerate(row_names): entry = tk.Label(tframe, text=f"{name}", font=const_fontsetting) entry.grid(row=i + 1, column=0, padx=20, sticky="we") # set column names for i, name in enumerate(col_names): entry = tk.Label(tframe, text=f"{name}", font=const_fontsetting) entry.grid(row=0, column=i + 1, sticky="we") # set contents for i, _ in enumerate(row_names): for j, _ in enumerate(col_names): print(f"{(i, j)}") entry = tk.Label( tframe, text= f"{np.format_float_scientific(data[i, j], precision=2)}", font=const_fontsetting, relief="ridge") entry.grid(row=i + 1, column=j + 1, sticky="we", padx=5, pady=2.5) pass return True def close_window(frame=window): frame.quit() return True def give_reference_point(nadir: np.ndarray, ideal: np.ndarray, to_destroy=None): # destroy frames [thing.destroy() for thing in to_destroy] # build a reference form reference_frame = tk.Frame(window) reference_frame.grid(row=4) lbl = tk.Label( reference_frame, text= "Please specify a reference point with objective values between the nadir and ideal.", font=const_fontsetting) lbl.grid(row=0, column=0, columnspan=len(nadir)) reference_point_entry_list = [] for i in range(len(nadir)): print(i) lbl_ref = tk.Label(reference_frame, text=f"Objective {i+1}:") lbl_ref.grid(row=1, column=i) txt_entry = tk.Entry(reference_frame, font=const_fontsetting) txt_entry.insert(tk.END, f"{nadir[i]}") txt_entry.grid(row=2, column=i, sticky="we") reference_point_entry_list.append(txt_entry) def check_reference_point(): entry_txt_list = [ entry.get() for entry in reference_point_entry_list ] try: res = [float(txt) for txt in entry_txt_list] res = np.array(res) except ValueError as e: tk.messagebox.showerror( "Error in parsing reference point", f"Could not parse {entry_txt_list}. Are you sure the entries are numerical?" ) return False if not np.all(nadir <= res) or not np.all(res <= ideal): tk.messagebox.showerror( "Invalid reference point", "The given reference point is not between the nadir and ideal points" ) return False # good reference point given global reference_point reference_point = res window.quit() return True btn_check = tk.Button(reference_frame, text="Check", command=check_reference_point) btn_check.grid(row=3, columnspan=len(nadir), sticky="we", pady=5) return True # Start drawing on main window lbl_idealandnadir = tk.Label(window, text=f"Ideal and nadir points", font=const_fontsetting) lbl_idealandnadir.grid(row=0, padx=250) # show ideal and nadir make_table(["nadir", "ideal"], objective_names, scaler.inverse_transform(np.stack((nadir, ideal)))) # ask if DM wants to give a ref point lbl_question = tk.Label(window, text="Would you like to give a reference point?", pady=5, font=const_fontsetting) lbl_question.grid(row=2) btn_frame = tk.Frame(window) btn_frame.grid(row=3) yes_btn = tk.Button( btn_frame, text="Yes", command=lambda: give_reference_point( scaler.inverse_transform(nadir.reshape(1, -1)).squeeze(), scaler.inverse_transform(ideal.reshape(1, -1)).squeeze(), [btn_frame, lbl_question])) yes_btn.grid(row=0, column=1) no_btn = tk.Button(btn_frame, text="No", command=close_window) no_btn.grid(row=0, column=0) # show window until DM gives valid ref point or chooses not to window.mainloop() # clear the main window [child.destroy() for child in window.winfo_children()] # normalize reference point if given if reference_point is not None: print(f"ref point given: {reference_point}") reference_point = scaler.transform(reference_point.reshape( 1, -1)).squeeze() print(f"ref point normed: {reference_point}") else: print("ref point not given") reference_point = np.array([0.5, 0.5, 0.5]) print(f"ref point is {reference_point}") # show the paretofront fig_pf = plt.figure(figsize=(8, 6), dpi=120) fig_pf.suptitle("Paretofront in original scale") canvas_pf = tkagg.FigureCanvasTkAgg(fig_pf, master=window) ax_pf = fig_pf.add_subplot(111, projection="3d") extrema = scaler.inverse_transform(np.stack((nadir, ideal))) ax_pf.scatter(extrema[0, 0], extrema[0, 1], extrema[0, 2], label="nadir") ax_pf.scatter(extrema[1, 0], extrema[1, 1], extrema[1, 2], label="ideal") reference_point_orig = scaler.inverse_transform( reference_point.reshape(1, -1)).squeeze() ax_pf.scatter(reference_point_orig[0], reference_point_orig[1], reference_point_orig[2], label="reference point") paretofront_orig = scaler.inverse_transform(paretofront) ax_pf.scatter(paretofront_orig[:, 0], paretofront_orig[:, 1], paretofront_orig[:, 2]) ax_pf.set_xlabel("Income") ax_pf.set_ylabel("Carbon") ax_pf.set_zlabel("CHSI") fig_pf.legend() canvas_pf.draw() canvas_pf.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) toolbar_pf = tkagg.NavigationToolbar2Tk(canvas_pf, window) toolbar_pf.update() canvas_pf.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) btn_next = tk.Button(window, text="Next", command=lambda: quit(window)) btn_next.pack(side=tk.BOTTOM, fill=tk.X) # show the 3D plot window.mainloop() # clear main window [child.destroy() for child in window.winfo_children()] # initialize BRB # define parameters for the BRB precedents = np.stack((nadir, reference_point, ideal)).T consequents = np.array([[0, 0.25, 0.5, 0.75, 1]]) brb = BRBPref(precedents, consequents, f=lambda x: simple_mapping(x)) if variant == 1: pf_scores = brb_score(brb, paretofront) pf_scores_mean = np.mean(pf_scores) pf_scores_std = np.std(pf_scores) # show pairs to compare and asses fitness of model dm_choices = ask_preference(window, brb, paretofront, scaler, nadir=nadir, ideal=ideal) # check compatibility fitness, brb_choices = calculate_fitness(window, brb, dm_choices) # clear main window [child.destroy() for child in window.winfo_children()] # find 5 evenly distributed points (score wise) around the mean to be scored by the DM target_scores = np.array([ pf_scores_mean - pf_scores_std, pf_scores_mean - pf_scores_std / 2, pf_scores_mean, pf_scores_mean + pf_scores_std / 2, pf_scores_mean + pf_scores_std ]) diff_to_target = np.abs(pf_scores[:, None] - target_scores) score_indices = np.argmin(diff_to_target, axis=0) points_to_compare = paretofront[score_indices] # ask DM to score the points lbl_title = tk.Label( window, text="Please score each candidate between 0(worst) and 100(best)", font=const_fontsetting) lbl_title.grid(row=0, columnspan=3) lbl_scoring = tk.Label(window, text="Candidates", font=const_fontsetting) lbl_scoring.grid(row=1, column=0, sticky="we") make_table([f"Candidate {i+1}" for i in range(len(points_to_compare))], objective_names, scaler.inverse_transform(points_to_compare), row=1, column=0) lbl_score = tk.Label(window, text="Score", font=const_fontsetting) lbl_score.grid(row=1, column=1, sticky="we") frame_scoring = tk.Frame(window) frame_scoring.grid(row=1, column=1) lbl_scoring = tk.Label(frame_scoring, text="Scores", font=const_fontsetting) lbl_scoring.grid(row=0) candidate_scores_entries = [] for i in range(len(points_to_compare)): entry_score = tk.Entry(frame_scoring, font=const_fontsetting) entry_score.grid(row=1 + i, column=0, sticky="we", pady=2.5) entry_score.insert(tk.END, f"{np.random.randint(0, 101)}") candidate_scores_entries.append(entry_score) # show nadir and ideal lbl_nadirandideal = tk.Label(window, text="Nadir and ideal points", font=const_fontsetting) lbl_nadirandideal.grid(row=1, column=2, sticky="we") make_table(["nadir", "ideal"], objective_names, scaler.inverse_transform(np.stack((nadir, ideal))), row=1, column=2) no_btn = tk.Button(window, text="Cancel", command=close_window) no_btn.grid(row=4, column=2) btn_plot = tk.Button(window, text="Plot", command=lambda: draw_parallel( points_to_compare, obj_names=objective_names)) btn_plot.grid(row=4, column=4) global candidate_scores candidate_scores = None def check_scores(): entry_txt_list = [ entry.get() for entry in candidate_scores_entries ] try: res = [int(txt) for txt in entry_txt_list] res = np.array(res) / 100 except ValueError as e: tk.messagebox.showerror( "Error in parsing candidate scores", f"Could not parse {entry_txt_list}. Are you sure the entries are integers?" ) return False if not np.all(0 <= res) or not np.all(res <= 1): tk.messagebox.showerror( "Invalid candidate score(s)", "The given candidate score(s)is not between the 0 and 100") return False # valid scores given global candidate_scores candidate_scores = res window.quit() return True next_btn = tk.Button(window, text="Next", command=check_scores) next_btn.grid(row=4, column=1) window.mainloop() # clear main window [child.destroy() for child in window.winfo_children()] tk.messagebox.showinfo( "Training...", "The BRB model will be trained now, this might take a while.") # train BRB brb.train( None, None, brb._flatten_parameters(), obj_args=(np.atleast_2d(nadir), np.atleast_2d(ideal), np.atleast_2d(points_to_compare), np.atleast_2d(candidate_scores)), use_de=True, ) print(brb) print(brb_score(brb, np.atleast_2d(points_to_compare))) print(candidate_scores) if variant == 2: # check fitness again dm_choices = ask_preference(window, brb, paretofront, scaler, nadir=nadir, ideal=ideal) fitness, brb_choices = calculate_fitness(window, brb, dm_choices) if fitness >= 80: tk.messagebox.showinfo("Success", "Success! Fitness of over 80% achieveved!") print("Top 5 best solutions are:") pf_scores = brb_score(brb, paretofront) best_5 = np.argsort(pf_scores)[::-1][:5] print( f"{paretofront_orig[best_5]}\n with scores {pf_scores[best_5]}" ) return tk.messagebox.showinfo( "Training...", "The BRB model will be trained now, this might take a while.") brb.train( None, None, brb._flatten_parameters(), obj_args=(np.atleast_2d(nadir), np.atleast_2d(ideal), None, None, dm_choices), use_de=True, ) while True: # clear main window [child.destroy() for child in window.winfo_children()] # show value funtion draw_utility(window, brb) window.mainloop() # clear main window [child.destroy() for child in window.winfo_children()] # show ranking draw_ranking(window, brb, paretofront) window.mainloop() # clear main window [child.destroy() for child in window.winfo_children()] # check fitness again dm_choices = ask_preference(window, brb, paretofront, scaler, nadir=nadir, ideal=ideal) fitness, brb_choices = calculate_fitness(window, brb, dm_choices) if fitness >= 80: tk.messagebox.showinfo("Success", "Success! Fitness of over 80% achieveved!") print("Top 5 best solutions are:") pf_scores = brb_score(brb, paretofront) best_5 = np.argsort(pf_scores)[::-1][:5] print( f"{paretofront_orig[best_5]}\n with scores {pf_scores[best_5]}" ) draw_parallel(paretofront[best_5]) window.mainloop() print(brb) break tk.messagebox.showinfo( "Training...", "The BRB model will be trained now, this might take a while.") if variant == 1: brb.train( None, None, brb._flatten_parameters(), obj_args=(np.atleast_2d(nadir), np.atleast_2d(ideal), np.atleast_2d(points_to_compare), np.atleast_2d(candidate_scores), dm_choices), use_de=True, ) if variant == 2: brb.train( None, None, brb._flatten_parameters(), obj_args=(np.atleast_2d(nadir), np.atleast_2d(ideal), None, None, dm_choices), use_de=True, ) print(brb) return 0
def create_graph_frame(master, *args, func_name, var_name, func, h, a, **kwargs): root = Frame(master, *args, **kwargs) figure = plt.Figure() canvas = tkagg.FigureCanvasTkAgg(master=root, figure=figure) axes = figure.add_subplot(1, 1, 1) axes.set_xlabel(var_name) axes.set_ylabel(func_name) toolbar_frame = Frame(root) tkagg.NavigationToolbar2TkAgg(canvas=canvas, window=toolbar_frame) sections_entry = PositiveNumEntry(root) plot_button = Button(root, text='plot') canvas.get_tk_widget().pack(fill='both', expand=True) toolbar_frame.pack(fill='x') plot_button.pack(side='bottom') Label(root, text='Number of sections:').pack(side='left', expand=True, anchor='e') sections_entry.pack(side='right', expand=True, anchor='w') if var_name == 'x': endpoint, fixed_var_endpoint = h, a fixed_var_name = 'y' else: endpoint, fixed_var_endpoint = a, h fixed_var_name = 'x' timer = Timer() plot_dots = linspace(0, endpoint, 200) # TODO: # 1) don't use fixed_var_name # 2) set_xlabel and ylabel: maybe you can remember it out of this function? # 3) last_used_values: how to make it simpler? last_used_values = dict() def butt_command(): axes.cla() axes.set_xlabel(var_name) axes.set_ylabel(func_name) print("Plotting graph...") timer.start() sections_num = int(sections_entry.get()) fixed_var_vals = linspace(0, fixed_var_endpoint, sections_num + 2) labels = create_lines_labels(var_name, sections_num) values = dict() for label, fixed_var in zip(labels, fixed_var_vals): if fixed_var in last_used_values: values[fixed_var] = last_used_values[fixed_var] else: values[fixed_var] = [ func(**{ var_name: var, fixed_var_name: fixed_var }) for var in plot_dots ] axes.plot(plot_dots, values[fixed_var], label=label) axes.legend(loc='best').draggable() canvas.draw() print(f'(done in {timer})') last_used_values.clear() last_used_values.update(values) plot_button.config(command=butt_command) return root
def __init__(self) -> None: """ Initializer. """ self.window = tk.Tk() self.window.title("Bounded Wavefunction in 1D") # Thanks to StackOverflow user rudivonstaden for # giving a way to get the colour of the tkinter widgets: # https://stackoverflow.com/questions/11340765/ # default-window-colour-tkinter-and-hex-colour-codes # # https://stackoverflow.com/q/11340765 # [Question by user user2063: # https://stackoverflow.com/users/982297/user2063] # # https://stackoverflow.com/a/11342481 # [Answer by user rudivonstaden: # https://stackoverflow.com/users/1453643/rudivonstaden] # colour = self.window.cget('bg') if colour == 'SystemButtonFace': colour = "#F0F0F0" # Set plot resolution # width = self.window.winfo_screenwidth() # print(width) # dpi = 250 C = Constants() x = np.linspace(C.x0, C.L + C.x0, C.N) # Defaults V = "(x)**2/2" psi = np.exp(-0.5 * ((x - 0.25) / 0.05)**2) # Other # V = rect(8*x) # psi = np.exp(-0.5*((x-0.25)/0.05)**2 - 160j*x*np.pi) # Initialize the inherited animation object QuantumAnimation.__init__(self, function=psi, potential=V) # Canvas # A quick example of how to integrate a matplotlib animation into a # tkinter gui is given by this Stack Overflow question and answer: # https://stackoverflow.com/q/21197728 # [Question by user3208454: # https://stackoverflow.com/users/3208454/user3208454] # https://stackoverflow.com/a/21198403 # [Answer by HYRY: # https://stackoverflow.com/users/772649/hyry] self.canvas = backend_tkagg.FigureCanvasTkAgg(self.figure, master=self.window) self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=19, columnspan=2) self.canvas.get_tk_widget().bind("<B1-Motion>", self.sketch) self.canvas.get_tk_widget().bind("<ButtonRelease-1>", self.sketch) # Thanks to StackOverflow user user1764386 for # giving a way to change the background colour of a plot. # # https://stackoverflow.com/q/14088687 # [Question by user user1764386: # https://stackoverflow.com/users/1764386/user1764386] # self.figure.patch.set_facecolor(colour) # Show Probability Distribution/Wavefunction # TODO: Don't use a long and unnecessary lambda function b = tk.Button(self.window, text='View Probability Distribution', command=lambda: [ self.display_probability(), self.change_view.config(text='View Wavefunction') ] if (self._display_probs is False) else [ self.display_wavefunction(), self.change_view.config(text='View ' 'Probability' ' Distribution') ]) self.change_view = b self.change_view.grid(row=1, column=3, columnspan=2, padx=(10, 10)) # Measurement label self.measurement_label = tk.Label(self.window, text="Measure:") self.measurement_label.grid(row=2, column=3, columnspan=3, sticky=tk.E + tk.W + tk.S, padx=(10, 10)) # Measure position button self.measure_position_button = tk.Button(self.window, text='Position', command=self.measure_position) self.measure_position_button.grid(row=3, column=3, columnspan=2, sticky=tk.E + tk.W + tk.N + tk.S, padx=(10, 10)) # Measure momentum button self.measure_momentum_button = tk.Button(self.window, text='Momentum', command=self.measure_momentum) self.measure_momentum_button.grid(row=4, column=3, columnspan=2, sticky=tk.E + tk.W + tk.N + tk.S, padx=(10, 10)) # Measure energy button self.measure_energy_button = tk.Button(self.window, text='Energy', command=self.measure_energy) self.measure_energy_button.grid(row=5, column=3, columnspan=2, sticky=tk.E + tk.W + tk.N, padx=(10, 10)) # Mouse menu dropdown self.mouse_menu_label = tk.Label(self.window, text="Mouse:") self.mouse_menu_label.grid(row=6, column=3, sticky=tk.W + tk.E + tk.S, padx=(10, 10), columnspan=2) # Mouse menu tuple self.mouse_menu_tuple = ("Reshape Wavefunction", "Reshape Wavefunction in Real Time", "Select Energy Level", "Reshape Potential V(x)") # Mouse menu string self.mouse_menu_string = tk.StringVar(self.window) self.mouse_menu_string.set("Reshape Wavefunction") self.mouse_menu = tk.OptionMenu(self.window, self.mouse_menu_string, *self.mouse_menu_tuple, command=self.mouse_menu_handler) self.mouse_menu.grid(row=7, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N, padx=(10, 10)) # Wavefunction entry field self.enter_function_label = tk.Label( self.window, text="Enter Wavefunction \u03C8(x)") self.enter_function_label.grid(row=8, column=3, columnspan=2, sticky=tk.E + tk.W + tk.S, padx=(10, 10)) self.enter_function = tk.Entry(self.window) self.enter_function.bind("<Return>", self.update_wavefunction_by_name) self.enter_function.grid(row=9, column=3, columnspan=2, sticky=tk.W + tk.E + tk.N + tk.S, padx=(11, 11)) # Update wavefunction button b2 = tk.Button(self.window, text='OK', command=self.update_wavefunction_by_name) self.update_wavefunction_button = b2 self.update_wavefunction_button.grid(row=10, column=3, columnspan=2, sticky=tk.N + tk.W + tk.E, padx=(10, 10) # pady=(10, 10) ) # Clear wavefunction button b3 = tk.Button(self.window, text='Clear Wavefunction', command=self.clear_wavefunction) self.clear_wavefunction_button = b3 self.clear_wavefunction_button.grid(row=11, column=3, columnspan=2, sticky=tk.W + tk.E, padx=(10, 10) # pady=(10, 10) ) # Drop down for preset potentials self.potential_menu_dict = { "Infinite Square Well": "0", "Simple Harmonic Oscillator": "x**2/2", # "Potential Barrier": "10*rect(32*x)", "Potential Well": "-rect(4*x)/2", "Potential Well and Barrier": "-2*rect(16*(x+1/4)) + 2*rect(16*(x-1/4))", # "Coulomb": "-1/(100*sqrt(x**2))", "Double Well": "(1-rect((21/10)*(x-1/4))-rect((21/10)*(x+1/4)))/10", "Triangular Well": "sqrt(x**2)" } self.potential_menu_string = tk.StringVar(self.window) self.potential_menu_string.set("Choose Preset Potential V(x)") self.previous_potential_menu_string = "Choose Preset Potential V(x)" self.potential_menu = tk.OptionMenu( self.window, self.potential_menu_string, *tuple(key for key in self.potential_menu_dict), # text="Choose a preset potential" command=self.update_potential_by_preset) self.potential_menu.grid(row=12, column=3, sticky=tk.W + tk.E, padx=(10, 10)) # Potential function entry field self.enter_potential_label = tk.Label(self.window, text="Enter Potential V(x)") self.enter_potential_label.grid(row=13, column=3, sticky=tk.W + tk.E + tk.S, padx=(10, 10)) self.enter_potential = tk.Entry(self.window) self.enter_potential.bind("<Return>", self.update_potential_by_name) self.enter_potential.grid(row=14, column=3, columnspan=3, sticky=tk.W + tk.E + tk.N + tk.S, padx=(10, 10)) # Update potential button b4 = tk.Button(self.window, text='OK', command=self.update_potential_by_name) self.update_potential_button = b4 self.update_potential_button.grid(row=15, column=3, columnspan=2, sticky=tk.N + tk.W + tk.E, padx=(10, 10) # pady=(10, 10) ) # Animation speed slider self.slider_speed_label = tk.LabelFrame(self.window, text="Animation Speed") self.slider_speed_label.grid(row=16, column=3, padx=(10, 10)) self.slider_speed = tk.Scale(self.slider_speed_label, from_=0, to=8, orient=tk.HORIZONTAL, length=200, command=self.change_animation_speed) self.slider_speed.grid(row=17, column=3, padx=(10, 10)) self.slider_speed.set(1) # Right click Menu self.menu = tk.Menu(self.window, tearoff=0) self.menu.add_command(label="Measure Position", command=self.measure_position) self.menu.add_command(label="Measure Momentum", command=self.measure_momentum) self.menu.insert_separator(3) self.menu.add_command(label="Reshape Wavefunction", command=self.rightclick_reshape_wavefunction) self.menu.add_command(label="Reshape Potential", command=self.rightclick_reshape_potential) self.menu.add_command(label="Select Energy Level", command=self.rightclick_select_energylevel) self.menu.insert_separator(7) self.menu.add_command(label="Toggle Show Energy Levels", command=self.rightclick_toggle_energylevel) self.menu.add_command(label="Toggle Expectation Values", command=self.toggle_expectation_values) self.menu.insert_separator(9) self.menu.add_command(label="Higher Stationary State", command=self.higher_energy_eigenstate) self.menu.add_command(label="Lower Stationary State", command=self.lower_energy_eigenstate) self.window.bind("<ButtonRelease-3>", self.popup_menu) # Quit button self.quit_button = tk.Button(self.window, text='QUIT', command=self.quit) self.quit_button.grid(row=18, column=3) self.window.bind("<Up>", self.higher_energy_eigenstate) self.window.bind("<Down>", self.lower_energy_eigenstate) self.animation_loop() # Store the animation speed before a pause self.fpi_before_pause = None self.scale_y = 0.0 self.potential_is_reshaped = False
def __init__(self, parent): self.estimator = parent.estimator # Shorthand for unit conversion self.conv = lambda value, conversion: \ self.estimator._converter.convert([value], conversion)[0] # --- SETUP WINDOW ----------------------------------------------- # Spectral data self.spec = sig.ft(self.estimator.get_data()) # Number of spectrum points self.n = self.spec.size # Transmitter frequency self.sfo = self.estimator.get_sfo()[0] # Nucleus identity self.nuc = self.estimator.get_nucleus()[0] # Sweep width, offset, and chemical shifts, in both ppm and Hz self.sw, self.off, self.shifts = {}, {}, {} for unit in ['hz', 'ppm']: self.sw[unit] = self.estimator.get_sw(unit=unit)[0] self.off[unit] = self.estimator.get_offset(unit=unit)[0] self.shifts[unit] = self.estimator.get_shifts(unit=unit)[0] # Units that are active in the app. # For frequencies, default is ppm (Hz also possible) # For degrees, default is radians (degrees also possible) self.active_units = {'freq': 'ppm', 'angle': 'rad'} # --- Region selection parameters -------------------------------- # Bounds for filtration and noise regions self.bounds = AutoVivification() # Initial values for region of interest and noise region init_bounds = [int(np.floor(x * self.n / 16)) for x in (7, 9, 1, 2)] for name, init in zip(['lb', 'rb', 'lnb', 'rnb'], init_bounds): # Save bounds to array index, ppm and hz units for unit in ['idx', 'hz', 'ppm']: if unit == 'idx': value, var_str = init, str(init) else: value = self.conv(init, f'idx->{unit}') var_str = f"{value:.4f}" self.bounds[name][unit] = value_var_dict(value, var_str) # Number of points the selected region is composed of self.region_size = \ self.bounds['rb']['idx']['value'] - \ self.bounds['lb']['idx']['value'] # --- Phase correction parameters -------------------------------- self.pivot = {} # Initialise pivot at center of spectrum pivot = int(self.n // 2) for unit in ['idx', 'hz', 'ppm']: # Set pivot in units of array index, Hz, and ppm if unit == 'idx': value, var_str = pivot, str(pivot) else: value = self.conv(pivot, f'idx->{unit}') var_str = f"{value:.4f}" self.pivot[unit] = value_var_dict(value, var_str) # Zero- and first-order correction parameters self.phases = AutoVivification() # Initialise correction parameters as zero in both radians and # degrees. for name in ['p0', 'p1']: for unit in ['rad', 'deg']: self.phases[name][unit] = value_var_dict(0., f"{0.:.4f}") # --- Various advanced settings ---------------------------------- # Specifies whether or not to cut the filtered spectral data self.cut = value_var_dict(True, 1) # Specifies the the ratio between cut signal size and filter # bandwidth self.cut_ratio = value_var_dict(3, '3') # Largest number of points permitted max_points = self.cut_size() self.max_points = value_var_dict(max_points, str(max_points)) # Number of points to be used for MPM and NLP. # By default, number of points will not exceed: # 4096 (MPM) # 8192 (NLP) self.trim = {} if max_points <= 4096: for name in ['mpm', 'nlp']: self.trim[name] = value_var_dict(max_points, str(max_points)) elif max_points <= 8192: self.trim['mpm'] = value_var_dict(4096, '4096') self.trim['nlp'] = value_var_dict(max_points, str(max_points)) else: self.trim['mpm'] = value_var_dict(4096, '4096') self.trim['nlp'] = value_var_dict(8192, '8192') # Number of oscillators # Initialise as 0 (use MDL) self.m = value_var_dict(0, '') # Specifies whether or not to use the MDL to estimate M self.mdl = value_var_dict(True, 1) # Idenitity of the NLP algorithm to use self.method = value_var_dict('trust_region', 'Trust Region') # Maximum iterations of NLP algorithm self.maxit = value_var_dict(200, '200') # Whether or not to include phase variance in NLP cost func self.phase_variance = value_var_dict(True, 1) # Whether or not to purge negligible oscillators self.use_amp_thold = value_var_dict(False, 0) # Amplitude threshold for purging negligible oscillators self.amp_thold = value_var_dict(0.001, '0.001') # --- Figure for setting up estimation --------------------------- self.setupfig = {} # Figure self.setupfig['fig'] = figure.Figure(figsize=(6, 3.5), dpi=170) # Axis self.setupfig['ax'] = \ self.setupfig['fig'].add_axes([0.05, 0.12, 0.9, 0.83]) # Plot spectrum # Generates a matplotlib.Line.Line2D object self.setupfig['plot'] = self.setupfig['ax'].plot( self.shifts['ppm'], np.real(self.spec), color='k', lw=0.6, )[0] # <- unpack from list # Set x-limits as edges of spectral window xlim = (self.shifts['ppm'][0], self.shifts['ppm'][-1]) self.setupfig['ax'].set_xlim(xlim) # Prevent user panning/zooming beyond spectral window # See Restrictor class for more info ↑ Restrictor(self.setupfig['ax'], x=lambda x: x <= xlim[0]) Restrictor(self.setupfig['ax'], x=lambda x: x >= xlim[1]) # Get current y-limit. Will reset y-limits to this value after the # very tall `noise_region` and `filter_region` rectangles have been # added to the plot ylim = self.setupfig['ax'].get_ylim() # Highlight the spectral region of intererst # matplotlib.patches.Rectangle's first 3 args: # (left, bottom), width, height bottom_left = (self.bounds['lb']['ppm']['value'], -20 * ylim[1]) width = \ self.bounds['rb']['ppm']['value'] - \ self.bounds['lb']['ppm']['value'] height = 40 * ylim[1] self.setupfig['region'] = patches.Rectangle( bottom_left, width, height, facecolor=REGIONCOLOR, ) self.setupfig['ax'].add_patch(self.setupfig['region']) # Highlight the noise region (height same as before) bottom_left = (self.bounds['lnb']['ppm']['value'], -20 * ylim[1]) width = \ self.bounds['rnb']['ppm']['value'] - \ self.bounds['lnb']['ppm']['value'] self.setupfig['noise_region'] = patches.Rectangle( bottom_left, width, height, facecolor=NOISEREGIONCOLOR) self.setupfig['ax'].add_patch(self.setupfig['noise_region']) # Plot pivot line x = 2 * [self.pivot['ppm']['value']] y = [-20 * ylim[1], 20 * ylim[1]] # `alpha` is set to 0 to make the pivot invisible initially self.setupfig['pivot'] = self.setupfig['ax'].plot( x, y, color=PIVOTCOLOR, alpha=0, lw=0.8, )[0] # Reset y limit self.setupfig['ax'].set_ylim(ylim) # Aesthetic tweaks to the plot self.setupfig['fig'].patch.set_facecolor(BGCOLOR) self.setupfig['ax'].set_facecolor(PLOTCOLOR) self.setupfig['ax'].tick_params(axis='x', which='major', labelsize=6) self.setupfig['ax'].locator_params(axis='x', nbins=10) self.setupfig['ax'].set_yticks([]) for direction in ('top', 'bottom', 'left', 'right'): self.setupfig['ax'].spines[direction].set_color('k') # xlabel of the form $^{<mass>}$<elem> (ppm) self.setupfig['ax'].set_xlabel( f"{latex_nucleus(self.nuc)} (ppm)", fontsize=8, ) # --- Construction of the setup GUI ------------------------------ super().__init__(parent) self.title('NMR-EsPy - Setup Calculation') self.resizable(True, True) # First column is adjusted upon change of window size # (plot_frame, toolbar_frame, tab_frame, logo_frame) self.columnconfigure(0, weight=1) # First row is adjusted upon change of window size # (plot_frame) self.rowconfigure(0, weight=1) self.protocol("WM_DELETE_WINDOW", self.click_cross) # Frame containing the plot self.plot_frame = MyFrame(self) # Make `plot_frame` resizable self.plot_frame.columnconfigure(0, weight=1) self.plot_frame.rowconfigure(0, weight=1) # Canvas for figure self.canvas = backend_tkagg.FigureCanvasTkAgg( self.setupfig['fig'], master=self.plot_frame, ) self.canvas.draw() self.canvas.get_tk_widget().grid(column=0, row=0, sticky='nsew') # Frame containing the navigation toolbar and advanced settings # button self.toolbar_frame = MyFrame(self) self.toolbar = MyNavigationToolbar( self.canvas, parent=self.toolbar_frame, ) self.toolbar.grid( row=0, column=0, sticky='w', padx=(10, 0), pady=(0, 5), ) # Frame containing notebook widget: for region selection and # phase correction self.tab_frame = MyFrame(self) # Make notebook adjustable horizontally self.tab_frame.columnconfigure(0, weight=1) self.notebook = MyNotebook(self.tab_frame) self.notebook.grid( row=0, column=0, sticky='ew', padx=10, pady=(0, 10), ) # Whenever tab is clicked, change plot so that either region # selection patches are visible, or phase pivot, depending on # tab selected self.notebook.bind( '<<NotebookTabChanged>>', lambda event: self.switch_tab(), ) # Frame with scale widgets for region selection self.region_frame = MyFrame(self.notebook, bg=NOTEBOOKCOLOR) self.notebook.add( self.region_frame, text='Region Selection', sticky='nsew', ) # Make scales expandable self.region_frame.columnconfigure(1, weight=1) # Scale labels self.region_labels = {} # Scales self.region_scales = {} # Entry widgets related to scales self.region_entries = {} for row, name in enumerate(('lb', 'rb', 'lnb', 'rnb')): # Construct text strings for scale titles text = '' for letter in name: if letter == 'l': text += 'left ' elif letter == 'r': text += 'right ' elif letter == 'n': text += 'noise ' else: text += 'bound' # Scale titles self.region_labels[name] = title = MyLabel( self.region_frame, text=text, bg=NOTEBOOKCOLOR, ) # Troughcolor of scale troughcolor = REGIONCOLOR if row < 2 else NOISEREGIONCOLOR self.region_scales[name] = scale = MyScale( self.region_frame, from_=0, to=self.n - 1, troughcolor=troughcolor, bg=NOTEBOOKCOLOR, command=(lambda idx, n=name: self.update_region_scale(idx, n)), ) scale.set(self.bounds[name]['idx']['value']) self.region_entries[name] = entry = MyEntry( self.region_frame, return_command=self.update_region_entry, return_args=(name, ), textvariable=self.bounds[name]['ppm']['var'], ) pady = (10, 0) if row != 3 else 10 title.grid(row=row, column=0, padx=(10, 0), pady=pady, sticky='w') scale.grid(row=row, column=1, padx=(10, 0), pady=pady, sticky='ew') entry.grid(row=row, column=2, padx=10, pady=pady, sticky='w') # Frame with scale widgets for region selection self.phase_frame = MyFrame(self.notebook, bg=NOTEBOOKCOLOR) self.notebook.add( self.phase_frame, text='Phase Correction', sticky='nsew', ) # Make scales expandable self.phase_frame.columnconfigure(1, weight=1) self.phase_titles = {} self.phase_scales = {} self.phase_entries = {} for row, (name, title) in enumerate( zip(('pivot', 'p0', 'p1'), ('pivot', 'φ₀', 'φ₁'))): # Scale titles self.phase_titles[name] = title = MyLabel(self.phase_frame, text=title, bg=NOTEBOOKCOLOR) # Pivot scale if name == 'pivot': troughcolor = PIVOTCOLOR from_ = 0 to = self.n - 1 resolution = 1 # p0 and p1 scales else: troughcolor = 'white' # TODO # PHASE SCALE WIDGET ISSUE # Would like this to be π or 10π, however tkinter seems to # convert the scale range to an int, and adjusts `to` to # accommodate this. from_ = -4 if name == 'p0' else -32. to = 4 if name == 'p0' else 32. resolution = 0.001 self.phase_scales[name] = scale = MyScale( self.phase_frame, troughcolor=troughcolor, from_=from_, to=to, resolution=resolution, bg=NOTEBOOKCOLOR, command=( lambda value, n=name: self.update_phase_scale(value, n)), ) if name == 'pivot': scale.set(self.pivot['idx']['value']) var = self.pivot['ppm']['var'] else: scale.set(0.0) var = self.phases[name]['rad']['var'] self.phase_entries[name] = entry = MyEntry( self.phase_frame, return_command=self.update_phase_entry, return_args=(name, ), textvariable=var, ) pady = (10, 0) if row != 2 else 10 title.grid(row=row, column=0, padx=(10, 0), pady=pady, sticky='w') scale.grid(row=row, column=1, padx=(10, 0), pady=pady, sticky='ew') entry.grid(row=row, column=2, padx=10, pady=pady, sticky='w') # Frame with NMR-EsPy an MF group logos self.logo_frame = LogoFrame(master=self, scale=0.72) # Frame with cancel/help/run/advanced settings buttons self.button_frame = SetupButtonFrame(master=self) # --- Configure frame placements --------------------------------- self.plot_frame.grid(row=0, column=0, columnspan=2, sticky='nsew') self.toolbar_frame.grid(row=1, column=0, columnspan=2, sticky='ew') self.tab_frame.grid(row=2, column=0, columnspan=2, sticky='ew') self.logo_frame.grid(row=3, column=0, padx=10, pady=10, sticky='w') self.button_frame.grid(row=3, column=1, sticky='s')
def __init__(self) -> None: """ The constructor. """ self.window = tk.Tk() self.window.title("Visualization of Fourier Series") width = self.window.winfo_screenwidth() dpi = int(150 * width // 1920) FourierAnimation.__init__(self, "3*rect(t)/2", dpi) # Thanks to StackOverflow user rudivonstaden for # giving a way to get the colour of the tkinter widgets: # https://stackoverflow.com/questions/11340765/ # default-window-colour-tkinter-and-hex-colour-codes # # https://stackoverflow.com/q/11340765 # [Question by user user2063: # https://stackoverflow.com/users/982297/user2063] # # https://stackoverflow.com/a/11342481 # [Answer by user rudivonstaden: # https://stackoverflow.com/users/1453643/rudivonstaden] # colour = self.window.cget('bg') if colour == 'SystemButtonFace': colour = "#F0F0F0" # Thanks to StackOverflow user user1764386 for # giving a way to change the background colour of a plot. # # https://stackoverflow.com/q/14088687 # [Question by user user1764386: # https://stackoverflow.com/users/1764386/user1764386] # try: self.figure.patch.set_facecolor(colour) except ValueError: print(colour) self.canvas = backend_tkagg.FigureCanvasTkAgg(self.figure, master=self.window) self.canvas.get_tk_widget().grid(row=1, column=0, rowspan=8, columnspan=3) self.function_dropdown_dict = { "sine": "sin(t)", "cosine": "cos(t)", "gaussian": "3*exp(-t**2/(2*sigma**2 ))/2 - 1/2", "sinc": "3*sinc(k*(6.5)*t)/2 - 1/2", "rectangle": "3*rect(t)/2", "sawtooth": "t/pi", "triangle": "abs(t)" } self.function_dropdown_string = tk.StringVar(self.window) self.function_dropdown_string.set("Preset Waveform f(t)") self.function_dropdown = tk.OptionMenu( self.window, self.function_dropdown_string, *tuple(key for key in self.function_dropdown_dict), command=self.set_function_dropdown) self.function_dropdown.grid(row=2, column=3, padx=(10, 10), pady=(0, 0)) self.enter_function_label = tk.Label( self.window, text="Enter waveform f(t)", ) self.enter_function_label.grid(row=3, column=3, sticky=tk.S + tk.E + tk.W, padx=(10, 10), pady=(0, 0)) self.enter_function = tk.Entry(self.window) self.enter_function.grid(row=4, column=3, sticky=tk.N + tk.E + tk.W + tk.S, padx=(10, 10)) self.enter_function.bind("<Return>", self.set_function_entry) self.update_button = tk.Button(self.window, text='OK', command=self.set_function_entry) self.update_button.grid(row=5, column=3, sticky=tk.N + tk.E + tk.W, padx=(10, 10), pady=(0, 0)) self.sliderslist = [] self.circles_slider = None self.slider_speed = None self._speed = 1 self.quit_button = None self._number_of_circles = 80 self._set_widgets_after_param_sliders()
def drawGraphs(self): deleteAllChildren(self.tab5) for a in self.mt.accounts: a.balance = 0 self.mt.transactions.sort(key=lambda tran: tran.dateTime) dates = [] for c in self.mt.categories: c.posSum = 0 c.negSum = 0 c.children = [mt.Category(c.name)] level1Categories = [] for c in self.mt.categories: if c.parent: c.parent.children.append(c) else: level1Categories.append(c) balancePerDay = [] for i in range(len(self.mt.transactions)): if self.mt.transactions[i].category: cat = self.mt.transactions[i].category if self.mt.transactions[i].amount > 0: cat.children[0].posSum += self.mt.transactions[i].amount else: cat.children[0].negSum -= self.mt.transactions[i].amount while cat: if self.mt.transactions[i].amount > 0: cat.posSum += self.mt.transactions[i].amount else: cat.negSum -= self.mt.transactions[i].amount cat = cat.parent if self.mt.transactions[i].account: self.mt.transactions[i].account.balance = self.mt.transactions[i].balance totalBalance = 0 for a in self.mt.accounts: totalBalance += a.balance if (i == len(self.mt.transactions)-1 or self.mt.transactions[i].dateTime != self.mt.transactions[i+1].dateTime): dates.append(self.mt.transactions[i].dateTime) balancePerDay.append(totalBalance) fig = matFig.Figure(figsize=(10, 10), dpi=100) graph1 = fig.add_subplot(211) graph1.plot_date(dates, balancePerDay, xdate=True, ls="-") graph1.set_ylabel("Total money") graph2 = fig.add_subplot(212) cmap = plt.get_cmap("tab20c") level1Values = [] level1Colors = [] level1Labels = [] level2Values = [] level2Colors = [] level2Labels = [] color = 0 for c in level1Categories: level1Values.append(c.negSum) level1Colors.append(color) level1Labels.append(c.name) childColor = color for c2 in c.children: level2Values.append(c2.negSum) level2Colors.append(childColor) level2Labels.append(c2.name) childColor += 1 if childColor % 4 == 0: childColor -= 4 color += 4 if color == 20: color = 0 graph2.pie(level1Values, colors=cmap(level1Colors), radius=1.0, wedgeprops=dict(width=0.5, edgecolor='w')) wedges, notUsed = graph2.pie(level2Values, colors=cmap(level2Colors), radius=0.8, wedgeprops=dict(width=0.3, edgecolor='w')) kw = dict(arrowprops=dict(arrowstyle="-"), va="center") for i, p in enumerate(wedges): ang = (p.theta2 - p.theta1) / 2. + p.theta1 y = numpy.sin(numpy.deg2rad(ang)) x = numpy.cos(numpy.deg2rad(ang)) horizontalAlignment = {-1: "right", 1: "left"}[int(numpy.sign(x))] connectionStyle = "angle,angleA=0,angleB={}".format(ang) kw["arrowprops"].update({"connectionstyle": connectionStyle}) graph2.annotate(level2Labels[i], xy=(x*0.65, y*0.65), xytext=(1.35 * numpy.sign(x), 1.4 * y), horizontalalignment=horizontalAlignment, **kw) canvas = matTkagg.FigureCanvasTkAgg(fig, master=self.tab5) canvas.draw() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
root = Tk.Tk() root.wm_title("Embedding in TK") fig = mfigure.Figure(figsize=(5, 4), dpi=100) ax = fig.add_subplot(111) t = np.arange(0.0, 3.0, 0.01) s = np.sin(2 * np.pi * t) ax.plot(t, s) ax.grid(True) ax.set_title('Tk embedding') ax.set_xlabel('time (s)') ax.set_ylabel('volts (V)') # a tk.DrawingArea canvas = backend.FigureCanvasTkAgg(fig, master=root) canvas.show() canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #toolbar = backend.NavigationToolbar2TkAgg( canvas, root ) #toolbar.update() #toolbar.pack(side=Tk.LEFT) def destroy(): raise SystemExit button = Tk.Button(master=root, text='Quit', command=destroy) button.pack(side=Tk.BOTTOM)
def plot_histogram(up_times_days, down_times_days, now=0.0, tk_frame=None): """Plot the histogram of the uploaded and downloaded blobs. The Y is the number of blobs uploaded or downloaded in a single hour. The X is the fraction of day (hour) when those blobs were uploaded. The days are negative because it assumes the blobs were downloaded in the past, meaning all values to the left correspond to days before the present time. Parameters ---------- up_times_days: list of float List of intervals in days from now to the past, when blobs were uploaded, `[-40, -30, -10, -5.235, -0.001]`. It is negative because these occurrences were in the past, that is, 40 days ago, 30 days ago, 10 days ago, etc. down_times_days: list of float List of intervals in days from now to the past, when blobs were downloaded. now: float, optional It defaults to `0.0`, in which case it calculates the time in this instance, `time.time()`. It is a float indicating the Unix epoch time, meaning seconds since 1970-01-01. This value represent the reference time for all values in `up_times_days` and `down_times_days`. """ if not now: now = time.time() now_txt = time.strftime("%Y-%m-%d_%H:%M:%S%z %A", time.localtime(now)) up_times_d = np.array(up_times_days) down_times_d = np.array(down_times_days) oldest_day = np.min(np.hstack([up_times_d, down_times_d])) # The bins for the histograms will be the fractions of day # representing hours of the day days_per_hour = 1/24 fractions_day = [0.0] while fractions_day[-1] > oldest_day: fractions_day.append(fractions_day[-1] - days_per_hour) # More negative values left and zero to the right fractions_day = fractions_day[::-1] blobs_up = len(up_times_d) blobs_down = len(down_times_d) ratio = 0.0 try: ratio = float(blobs_up)/blobs_down except ZeroDivisionError: pass xlabel = "Time (days ago)" ylabel = "Blobs per hour" opt = {"alpha": 0.9, "edgecolor": "k"} X0 = Y0 = [0] mk = {"label": now_txt, "marker": "o", "markeredgecolor": "k", "markersize": 9, "markeredgewidth": 2.0, "linestyle": ""} fig, axs = plt.subplots(2, 1, sharey=False, sharex=True) axs[0].hist(up_times_d, bins=fractions_day, color="g", label=f"Uploaded: {blobs_up}", **opt) axs[0].set_xlabel(xlabel) axs[0].set_ylabel(ylabel) axs[0].plot(X0, Y0, markerfacecolor="g", **mk) axs[0].legend() axs[0].set_title(f"Up/down ratio: {ratio:.4f}") axs[1].hist(down_times_d, bins=fractions_day, color="r", label=f"Downloaded: {blobs_down}", **opt) axs[1].set_xlabel(xlabel) axs[1].set_ylabel(ylabel) axs[1].plot(X0, Y0, markerfacecolor="r", **mk) axs[1].legend() if tk_frame: canvas = mbacks.FigureCanvasTkAgg(fig, master=tk_frame) canvas.draw() # canvas.get_tk_widget().grid(row=0, column=0) canvas.get_tk_widget().pack(fill="both", expand=True) tbar = mbacks.NavigationToolbar2Tk(canvas, tk_frame) tbar.update() # canvas.get_tk_widget().grid(row=1, column=0) canvas.get_tk_widget().pack(fill="both", expand=True) else: plt.show()
def __init__(self, env, render_size, fps=10, reward_history=20, observation_image_key='image', gif_writer=None, reward_border_width=10): """Constructor. Args: env: instance of moog.environment.Environment. The environment observations are assumed to have a key 'image' whose value is an image with height and width render_size. render_size: Int. Width and height of observation_image_key value of the environment observation image. fps: Int. Frames per second to run, if possible. Note: The tkinter gui interface and matplotlib rendering is slow, often taking about 40 milliseconds for 256x256 rendering. Furthermore, depending on the environment and physics, stepping the environent can take some time (usually no more than 10 milliseconds). Therefore, the fastest fps this gui can run is 20fps for 256x256 rendering, and if the given fps is higher than this it will be capped. This slowness is mostly due to matplotlib and tkinter, not the environment or rendering itself, and does not occur when training agents or using mworks for psychophysics. reward_history: Int. Number of history timesteps to plot the reward for. observation_image_key: String. Key of the observation that is the image. gif_writer: Optional instance of a gif writer. This writer should have a .close() method and an .add(frame) method. reward_border_width: Int. Width of the red/green border to render when a positive/negative reward is given. """ self._env = env self._ms_per_step = 1000. / fps self._reward_history = reward_history self._observation_image_key = observation_image_key self._gif_writer = gif_writer self._reward_border_width = reward_border_width # This will be used later to capture a section of the screen if self._gif_writer: self._screen_capture = mss.mss() # Create root Tk window and fix its size self.root = tk.Tk() frame_width = str(render_size) frame_height = str(int(_WINDOW_ASPECT_RATIO * render_size)) self.root.geometry(frame_width + 'x' + frame_height) # Bind escape key to terminate gif_writer and exit def _escape(event): if self._gif_writer: self._gif_writer.close() sys.exit() self.root.bind('<Escape>', _escape) ######################################################################## # Create the environment display and pack it into the top of the window. ######################################################################## image = env.reset().observation[self._observation_image_key] self._env_canvas = tk.Canvas( self.root, width=render_size, height=render_size) self._env_canvas.pack(side=tk.TOP) img = ImageTk.PhotoImage(image=Image.fromarray(image)) self._env_canvas.img = img self.image_on_canvas = self._env_canvas.create_image( 0, 0, anchor="nw", image=self._env_canvas.img) ######################################################################## # Create the gui frame and pack it into the bottom of the window. ######################################################################## canvas_half_width = render_size / 2 action_space = env.action_space if isinstance(action_space, action_spaces.Composite): num_agents = len(action_space.action_spaces) a_spaces = action_space.action_spaces.values() if (num_agents == 2 and all( isinstance(a, action_spaces.Grid) for a in a_spaces)): logging.info( '2-player Grid action space. One player uses arrow keys ' 'and the other uses [a, s, d, w].') # Two-player Grid action spaces self.gui_frame = gui_frames.TwoPlayerGridActions( self.root, canvas_half_width=canvas_half_width, player_0=action_space.action_keys[0], player_1=action_space.action_keys[1], ) elif (num_agents == 2 and all( isinstance(a, action_spaces.Joystick) for a in a_spaces)): logging.info( '2-player Joystick action space. One player uses arrow keys ' 'and the other uses [a, s, d, w].') # Two-player Joystick action spaces self.gui_frame = gui_frames.TwoPlayerJoystick( self.root, canvas_half_width=canvas_half_width, player_0=action_space.action_keys[0], player_1=action_space.action_keys[1], ) else: logging.info( 'Composite action space provided, human controls only the ' 'first agent.') action_space = list(action_space.action_spaces.values())[0] if isinstance(action_space, action_spaces.Joystick): logging.info( 'Joystick action space, drag and move the joystick at the ' 'bottom of the window.') self.gui_frame = gui_frames.JoystickFrame( self.root, canvas_half_width=canvas_half_width, motion_zone_radius=canvas_half_width - 5, ) elif isinstance(action_space, action_spaces.Grid): logging.info('Grid action space, use arrow keys.') self.gui_frame = gui_frames.GridActions( self.root, canvas_half_width=canvas_half_width, ) elif isinstance(action_space, action_spaces.SetPosition): logging.info('SetPosition action space, click on the frame to act.') self.gui_frame = gui_frames.SetPositionFrame( self._env_canvas, canvas_half_width=canvas_half_width, ) elif not isinstance(action_space, action_spaces.Composite): raise ValueError( 'Cannot demo action space {}'.format(env.action_space)) if not isinstance(action_space, action_spaces.SetPosition): self.gui_frame.canvas.pack(side=tk.BOTTOM) ######################################################################## # Create the reward plot and pack it into the middle of the window. ######################################################################## # This figuresize and the subplot adjustment is hand-crafted to make it # look okay for _WINDOW_ASPECT_RATIO 2.7. Ideally, we would infer the # space available for this reward plot and size the figure accordingly, # but I could not easily figure out how to do that --- it seems like # matplotlib doesn't count axis ticks and labels as part of the figure # size so those are cut off without handcrafting some subplot # adjustment. fig = plt.Figure(figsize=(2, 2), dpi=100) fig.subplots_adjust(bottom=0.5, left=0.25, right=0.95) self._ax_reward = fig.add_subplot(111) self._ax_reward.set_ylabel('Reward') self._ax_reward.set_xlabel('Time') self._ax_reward.axhline(y=0.0, color='lightgrey') # Plot rewards as a bar plot self._reset_rewards() reward_ticks = np.arange(-1 * self._reward_history + 1, 1) self.rewards_plot = self._ax_reward.bar(reward_ticks, self._rewards) # Create canvas in which to draw the reward plot and pack it # A tk.DrawingArea. self.rewards_canvas = backend_tkagg.FigureCanvasTkAgg( fig, master=self.root) self.rewards_canvas.draw() self.rewards_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH) ######################################################################## # Start run loop, automatically running the environment. ######################################################################## self.root.after(math.floor(self._ms_per_step), self.step) self.root.mainloop()
def plot_schedule(self, selected_artist=None): """Update the plotted schedule. Selected artist (defaults to none), can be set if an item is clicked which will mark it (and more later). """ if self.fig is None: self.fig = pltfig.Figure(figsize=(5, 4)) self.ax = self.fig.add_subplot(111) # Create the canvas self.canvas = tkagg.FigureCanvasTkAgg(self.fig, master=self.midFrame) self.canvas.show() self.canvas.get_tk_widget().pack() self.fig.canvas.mpl_connect('pick_event', self.click_schedule_block) # Set the font for labels matplotlib.rcParams.update({'font.size': 6}) # Plot each of the rects for ii in range(len(self.sched_frame)): rectval = self.sched_frame.loc[ii, 'rect'] edgecolor = 'none' fldMatch = self.fldPar[self.fldPar['objid'] == self.sched_frame.loc[ii, 'objid']] colorval = fldMatch['color'].values[0] if (selected_artist is not None): artist = self.sched_frame.loc[ii, 'artist'] if ((selected_artist[0] == artist[0]) and (abs(selected_artist[1] - artist[1]) == 0)): edgecolor = 'black' rect = mpatches.Rectangle((rectval[0], rectval[1]), rectval[2], rectval[3], edgecolor=edgecolor, facecolor=colorval, picker=True, linewidth=10, alpha=0.1) self.ax.add_artist(rect) self.ax.draw_artist(rect) self.ax.text(self.sched_frame.loc[ii, 'date'], self.sched_frame.loc[ii, 'startTime'] + 0.5 * self.sched_frame.loc[ii, 'duration'], self.sched_frame.loc[ii, 'fieldID'], va='center', ha='center') plot_limits = self.plot_limits.copy() # Set y limits if plot_limits[2] is None: plot_limits[2] = self.sched_frame['endTime'].max() + 1.0 if plot_limits[3] is None: plot_limits[3] = self.sched_frame['startTime'].min() - 1.0 # Set x limits if plot_limits[0] is None: plot_limits[0] = self.sched_frame['date'].min() - 0.6 if plot_limits[1] is None: plot_limits[1] = self.sched_frame['date'].max() + 0.6 self.ax.set_xlim(plot_limits[0:2]) self.ax.set_ylim(plot_limits[2:4])
tkvar.trace('w', change_dropdown) executebutton = Button(buttonFrame, text="Run", command=start) executebutton.pack(side=BOTTOM) ########### dataframe = Frame(root) dataframe.pack(side=LEFT) fig = plt.figure(1) plt.title('Estimated impulse response') plt.ylabel('Amplitude') plt.xlabel('Time [us]') canvas = tkagg.FigureCanvasTkAgg(fig, master=dataframe) plot_widget = canvas.get_tk_widget() plot_widget.pack(side=TOP) toolbar = tkagg.NavigationToolbar2TkAgg(canvas, dataframe) toolbar.pack(side=TOP) ###################### saveframe = Frame(dataframe) saveframe.pack(side=BOTTOM) lSaveFrame = Frame(saveframe) lSaveFrame.pack(side=LEFT) eSaveFrame = Frame(saveframe) eSaveFrame.pack(side=LEFT) sSaveFrame = Frame(saveframe) sSaveFrame.pack(side=LEFT)