def plot(x, y, types="直线", window="new", xname="X轴", yname="Y轴", title=""): if window == "new": window = Toplevel() window.title("命令画图") plotCanvas = Canvas(window) toolbar = Frame(window) fig = plt.figure(dpi=150) fPlot = fig.add_subplot(111) canvasSpice = FigureCanvasTkAgg(fig, plotCanvas) canvasSpice.get_tk_widget().place(x=0, y=0) plt.rcParams['font.sans-serif'] = 'SimHei' fPlot.clear() plt.xlabel(xname, size=20) plt.ylabel(yname, size=20) plt.title(title, size=20) if types == "散点": plt.scatter(x, y, alpha=0.6) elif types == "直线": plt.plot(x, y) plt.grid(True) canvasSpice.draw() wh = [] for i in canvasSpice.get_width_height(): wh.append(i) NavigationToolbar2Tk(canvasSpice, toolbar).update() plotCanvas.pack(expand=True) toolbar.pack(expand=True) window.config(width=wh[0], height=wh[1]) plotCanvas.config(width=wh[0], height=wh[1]) toolbar.config(width=wh[0]) window.resizable(width=False, height=False) return Models.UniMessage("画图完成!")
class DCanvas: def __init__(self, parent): self.map_figure = MapFigure((w, h)) self.figure = self.map_figure.get_figure() self.canvas = FigureCanvasTkAgg(self.figure, master=parent) self.canvas.get_tk_widget().pack(fill='both', expand=True) self.canvas.draw() def refresh(self, parent, point): self.map_figure.refresh(point) self.canvas.figure = self.map_figure.get_figure() self.canvas.draw() def get_size(self): return self.canvas.get_width_height()
class PlotApp(): _COLORS = ("#555555", "#F75D59", "#1589FF", "black", "red", "blue") _COLORS_LIGHT = ("#aaaaaa", "#F7bDb9","#a5a9FF", "#999999", "#FFaaaa", "#aaaaFF") _ALPHA_SEL = 1.0 _ALPHA_DESEL = 0.2 _LINEWEIGHT_SEL = 1.0 _LINEWEIGHT_DESEL = 0.2 def __init__(self, parent, plotdata, plotdata_files): self.parent = parent self.plots = plotdata # self.plots looks like this: # # { "dgde" : { 0 : PlotData_instance (from file 1), # 1 : PlotData_instance (from file 2), ... }, # "egap_l" : { 0 : PlotData_instance (from file 1), # 1 : PlotData_instance (from file 2), ... }, # ... } # where 0,1,... are indices of the filenames in plotdata_files # self.plotdata_files = plotdata_files # [ "/home/.../pro/qa.PlotData.pickle", "/home/.../wat/qa.PlotData.pickle" ] self.nrows = 1 self.ncols = 1 self.blocked_draw = False self.subplot_lines = {} self.legend_font = FontProperties(size="xx-small") self.lb1_entries = ODict() for plot_key, plot in self.plots.iteritems(): self.lb1_entries[ plot.values()[0].title ] = plot_key self.lb1 = Tk.Listbox(self.parent, selectmode=Tk.EXTENDED, exportselection=0) for plot_title in self.lb1_entries.keys(): self.lb1.insert(Tk.END, plot_title) self.lb1.pack(fill=Tk.Y, side=Tk.LEFT) self.lb2 = Tk.Listbox(self.parent, selectmode=Tk.EXTENDED, exportselection=0) self.lb2.pack(fill=Tk.Y, side=Tk.LEFT) self.figure = Figure(figsize=(5,4), dpi=100) self.canvas = FigureCanvasTkAgg(self.figure, master=self.parent) self.canvas.get_tk_widget().pack() self.canvas._tkcanvas.pack(fill=Tk.BOTH, expand=1) self.toolbar = NavigationToolbar2TkAgg( self.canvas, self.parent ) self.toolbar.update() self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) self.lb1.bind("<<ListboxSelect>>", self.on_select_lb1) self.lb2.bind("<<ListboxSelect>>", self.on_select_lb2) self.parent.bind("<Configure>", self.on_resize) def draw_legend(self): handls = [] labls = [] pos = "lower right" for i, plotdata_file in enumerate(self.plotdata_files): handls.append(mpatches.Patch(color=self._COLORS[i])) labls.append("%d: %s" % (i, plotdata_file)) self.figure.legend(handls, labls, pos, prop=self.legend_font) def change_geometry(self): indices = [ int(sel) for sel in self.lb1.curselection() ] if not indices: return if len(indices) == 1: nc,nr = 1,1 else: w,h = (float(x) for x in self.canvas.get_width_height()) # get first guess layout from window size ( ncols = width/ (height*1.5) ) nc = math.ceil(w/(h*2.5)) if nc > len(indices): nc = len(indices) nr = math.ceil(float(len(indices)) / nc) # check what the actual ratio of the plots is, and adjust accordingly if (w/nc) / (h/nr) > 2.5: nc += 1 elif (w/nc) / (h/nr) < 0.5: nc -= 1 if not nc: nc = 1 elif nc > len(indices): nc = len(indices) nr = math.ceil(float(len(indices)) / nc) # are they different then before? if nc != self.ncols or nr != self.nrows: self.ncols = nc self.nrows = nr return True return False def draw_plots(self): # clear the figure self.figure.clear() # clear the subplot_lines dictionary self.subplot_lines = {} # get keys for the selected plots in lb1 plot_keys = [ self.lb1_entries[ self.lb1.get(int(index)) ] for index in self.lb1.curselection() ] for i, key in enumerate(plot_keys): # example of plot_keys: [ "dgde", "egapl", "dgl", ... ] plots = self.plots[key] if plots[0].plot_type == "wireframe": plt = self.figure.add_subplot(self.nrows,self.ncols,i+1, projection='3d') else: plt = self.figure.add_subplot(self.nrows,self.ncols,i+1) # if the plot is a bar chart and if xvalues are string categories: # make a common list of categories from all plots since they # can be different (top 20 group contribs for example) bar_categories = [] if plots[0].plot_type == "bar" and \ isinstance(plots[0].subplots.values()[0]["xdata"][0], basestring): for plot in plots.values(): for subplots in plot.subplots.values(): for i_cat, cat in enumerate(subplots["xdata"]): if cat not in bar_categories: bar_categories.insert(i_cat, cat) # plot the plots # example of plots: # { 0: protein_plot, 1: protein2_plot, 2: water_plot } for plot_number, plot in plots.iteritems(): for subplot_label, subplot_data in plot.subplots.iteritems(): if plot.plot_type == "line": line, = plt.plot(subplot_data["xdata"], subplot_data["ydata"], color=self._COLORS[plot_number]) elif plot.plot_type == "bar": width = 0.9/(len(plots)) # string categories if isinstance(subplot_data["xdata"][0], basestring): # map values to category list made before xymap = dict(zip(subplot_data["xdata"], subplot_data["ydata"])) xyemap = dict(zip(subplot_data["xdata"], subplot_data["yerror"])) ydata = [] yerror = [] for cat in bar_categories: try: ydata.append(xymap[cat]) yerror.append(xyemap[cat]) except KeyError: ydata.append(0) yerror.append(0) xind = range(0, len(bar_categories)) xind = [x-0.45+plot_number*(width) for x in xind] line = plt.bar(xind, ydata, width=width, yerr=yerror, color=self._COLORS_LIGHT[plot_number]) plt.set_xticks(xind) plt.set_xticklabels(bar_categories, rotation=70) else: xind = [x-0.45+plot_number*(width) for x in subplot_data["xdata"]] line = plt.bar(xind, subplot_data["ydata"], width=width, yerr=subplot_data["yerror"], color=self._COLORS_LIGHT[plot_number] ) elif plot.plot_type == "scatter": line = plt.scatter(subplot_data["xdata"], subplot_data["ydata"], color=self._COLORS[plot_number], marker="s") elif plot.plot_type == "wireframe": line = plt.plot_wireframe(subplot_data["xdata"], subplot_data["ydata"], subplot_data["zdata"], color=self._COLORS[plot_number]) # add the line that was drawn to subplot_lines # so that we can change color if lb2 selection changes subplot_label = "%d/%s" % (plot_number, subplot_label) if subplot_label not in self.subplot_lines.keys(): self.subplot_lines[subplot_label] = [] self.subplot_lines[subplot_label].append(line) plt.set_title(plot.title) plt.set_xlabel(plot.xlabel) plt.set_ylabel(plot.ylabel) if plot_keys: self.draw_legend() padding = len(self.plotdata_files) * 0.03 try: self.figure.tight_layout(rect=[0, 0+padding, 1, 1]) except TypeError: # rect doesn't exist in ancient matplotlib versions self.figure.tight_layout() except ValueError: pass self.canvas.draw() self.blocked_draw = False def on_select_lb1(self,event): # remove and add all subplots to lb2 (1/rep_000,1/rep_001... 2/rep_000,2/rep_001...) self.lb2.delete(0, Tk.END) # get keys for the selected plots in lb1 plot_keys = [ self.lb1_entries[ self.lb1.get(int(index)) ] for index in self.lb1.curselection() ] # iterate through all the selected plots (lb1) # iterate through all the plots with the same key # (protein dG_dE, water dG_dE, mutant dG_dE, ...) # iterate through all subplot labels # (rep_000, rep_001) # if exists do not append it (subplots from different keys have the # same label - protein dG_dE, protein dG_lambda, ... and should be combined) for i,key in enumerate(plot_keys): subplots_labels = [] for plot_number, plot in self.plots[key].iteritems(): for subplot_label in sorted(plot.subplots.keys()): subplot_label = "%d/%s" % (plot_number, subplot_label) if subplot_label not in subplots_labels: subplots_labels.append(subplot_label) self.lb2.insert(0, *subplots_labels) self.lb2.selection_set(0, Tk.END) if not self.blocked_draw: self.blocked_draw = True self.change_geometry() self.draw_plots() def on_select_lb2(self,event): # get selected subplots from lb2 selected_subplots_keys = [ self.lb2.get(int(index)) for index in self.lb2.curselection() ] for subplot_key, subplot_line_list in self.subplot_lines.iteritems(): for subplot_line in subplot_line_list: plot_number = int(subplot_key.split("/")[0]) if subplot_key in selected_subplots_keys: alpha, lw = self._ALPHA_SEL, self._LINEWEIGHT_SEL else: alpha, lw = self._ALPHA_DESEL, self._LINEWEIGHT_DESEL try: subplot_line.set_alpha(alpha) subplot_line.set_linewidth(lw) except AttributeError: pass # bar chart doesn't support this self.canvas.draw() def on_resize(self,event): if not self.blocked_draw: if self.change_geometry(): self.blocked_draw = True # it would otherwise redraw the whole canvas with every change in geometry self.parent.after(500, self.draw_plots)
class SimulationPage(tk.Frame): def __init__(self, master=None): super(SimulationPage, self).__init__(master) self.parameter_frame = tk.LabelFrame(self, text="parameters") self.build_parameters() self.result_frame = tk.LabelFrame(self, text="result") self.fig = Figure() self.ax = self.fig.add_subplot(111) self.plot_window = FigureCanvasTkAgg(self.fig, self.result_frame) self.plot_window.draw() self.plot_window.get_tk_widget().pack() self.pack() self.run = tk.Button(self, text="Run algorithm", command=self.run) self.parameter_frame.grid(column=0, row=0) self.run.grid(column=0, row=1) self.result_frame.grid(column=1, row=0, columnspan=2, rowspan=2) def build_parameters(self): self.video = Parameter("video", bool, True) self.save_video = Parameter("save video", bool, True) self.parameters = [ Parameter("time_sim", int, 1000), Parameter("number_of_molecules", int, 100000), Parameter("monomer_pool", int, 3100000), Parameter("p_growth", float, 0.5), Parameter("p_death", float, 0.00005), Parameter("p_dead_react", float, 0.5), Parameter("l_exponent", float, 0.5), Parameter("d_exponent", float, 0.5), Parameter("l_naked", float, 0.5), Parameter("kill_spawns_new", bool, True), self.video, self.save_video ] [x.set_var(self) for x in self.parameters] for param in self.parameters: control = None param_type = param.get_type() if param_type in [int, str, float]: lab = tk.Label(self.parameter_frame, text=param.get_name()) lab.pack() control = tk.Entry(self.parameter_frame, validate='all', validatecommand=(validation[param_type], '%s', '%P', '%W'), name=param.get_name(), textvar=param.get_var()) elif param_type is bool: control = tk.Checkbutton(self.parameter_frame, text=param.get_name(), name=param.get_name()) control.pack() def run(self): values = [x.get_value() for x in self.parameters if x.get_name() not in ["video", "save video"]] self.run["text"] = "running" self.update() if self.save_video.get_value() and self.video.get_value(): name = str(round(time.time())) self.writer = imageio.get_writer(name + '.gif', mode='I', duration=0.3) if self.video.get_value(): result = polymer(*values, UI_vid=self.make_hist) else: result = polymer(*values) self.make_hist(result) if self.save_video.get_value() and self.video.get_value(): self.writer.close() self.run["text"] = "run" def make_hist(self, results, state=None, coloured=1): self.ax.clear() living, dead,coupled = results if state is not None: current_monomer, initial_monomer, time = state conversion = 1 - current_monomer / initial_monomer d = np.hstack((living, dead, coupled)) DPn = np.mean(d) DPw = np.sum(np.square(d)) / (DPn * d.shape[0]) PDI = DPw / DPn # dlmwrite('polymerOutput.txt',[time, conversion, DPn, DPw, PDI], '-append'); if coloured == 0: self.ax.hist(d, bins=int(np.max(d) - np.min(d)), facecolor='b') else: step = np.ceil((np.max(d) - np.min(d)) / 1000) binEdges = np.arange(np.min(d) - 0.5, np.max(d) + 0.5, step) midbins = binEdges[0:-1] + (binEdges[1:] - binEdges[0:-1]) / 2 if coupled.size == 0: c,b,e = self.ax.hist([dead, living], bins=midbins, histtype='barstacked', stacked=False, label=['Dead', 'Living']) # e[0]["color"] = "blue" # e[1]["color"] = "orange" matplotlib.pyplot.setp(e[0], color="blue") matplotlib.pyplot.setp(e[1], color="orange") # setp(e[0], color='blue') # setp(e[1], color='orange') else: self.ax.hist([coupled, dead, living], bins=midbins, histtype='bar', stacked=True, label=['Terminated', 'Dead', 'Living']) self.ax.set_xlabel('Length in units') self.ax.set_ylabel('Frequency') digits = 3 if state is not None: title = "conversion={}, t={}, DPI={}, DPn={}, DPw={}".format( round(conversion, digits), time, round(PDI, digits),round(DPn, digits),round(DPw, digits) ) self.ax.set_title(title) self.ax.legend() self.plot_window.draw() if self.save_video.get_value(): width, height = self.plot_window.get_width_height() image = np.fromstring(self.plot_window.tostring_rgb(), dtype=np.uint8).reshape((height, width, 3)) self.writer.append_data(image)
class ApplicationWindow(tk.Frame): def __init__(self, master): """ Creates the main window with all widgets needed. :param master: the window where the content should be placed """ tk.Frame.__init__(self, master) self.highlight_color = '#40A9CF' self.btn_config = { 'background': 'white', 'highlightbackground': self.highlight_color, 'foreground': 'black', } self.default_config = { 'background': 'white', } self.plot = Plot() self.bar = TabBar(self, "graph") fun_label = tk.Label(self, text="Differential Equation: y'=xy^2-3xy", font=("Times New Roman", 30)) fun_label.pack() # Create the form self.create_form() # Create the graph tab graph_tab = Tab(self, 'graph') # Draw a graph and put its figure into a canvas df = self.plot.draw_functions(ax=plt.figure(1).gca()) self.canvas1 = FigureCanvasTkAgg(plt.figure(1), master=graph_tab) self.canvas1.draw() self.canvas1.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES) # Create the local errors tab local_errors_tab = Tab(self, 'local errors') # Draw an errors graph and put its figure into a canvas self.plot.draw_local_errors(ax=plt.figure(2).gca()) self.canvas2 = FigureCanvasTkAgg(plt.figure(2), master=local_errors_tab) self.canvas2.draw() self.canvas2.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES) # Create the total approximation errors tab total_errors_tab = Tab(self, 'total errors') # Draw an errors graph and put its figure into a canvas self.plot.draw_approximation_errors(ax=plt.figure(3).gca()) self.canvas3 = FigureCanvasTkAgg(plt.figure(3), master=total_errors_tab) self.canvas3.draw() self.canvas3.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES) # Create the table tab and put a table inside it table_tab = Tab(self, 'table') width, height = self.canvas1.get_width_height() self.table = Table(table_tab, dataframe=df, width=width - 60, height=height - 20, editable=False, cellwidth=188) self.table.colselectedcolor = self.table.rowselectedcolor = self.highlight_color self.table.show() self.set_config([ self, self.bar, fun_label, graph_tab, local_errors_tab, total_errors_tab, table_tab ], self.default_config) # Add tabs to the tab bar self.bar.add(graph_tab, self.btn_config) self.bar.add(local_errors_tab, self.btn_config) self.bar.add(total_errors_tab, self.btn_config) self.bar.add(table_tab, self.btn_config) self.bar.show() def update_window(self, x0, y0, x, h): """ Updates the graphs and the table accroding to the given data :param x0: initial position on x-axis :param y0: f(x0) :param x: final position on x-axis :param h: a grid step :return: None """ x0_new, y0_new, x_new, h_new = float(x0.get()), float(y0.get()), float( x.get()), float(h.get()) if x0_new < x_new and h_new > 0 and y0_new > 0 and ( x_new - x0_new) / h_new <= 10000: plt.figure(1).gca().clear() plt.figure(2).gca().clear() plt.figure(3).gca().clear() df = self.plot.draw_functions( plt.figure(1).gca(), x0_new, y0_new, x_new, h_new) self.canvas1.draw() self.plot.draw_local_errors( plt.figure(2).gca(), x0_new, y0_new, x_new, h_new) self.canvas2.draw() self.plot.draw_approximation_errors( plt.figure(3).gca(), x0_new, y0_new, x_new) self.canvas3.draw() self.table.updateModel(TableModel(df)) self.table.show() def create_form(self): """ Creates the form for changing the initial data :return: None """ form = tk.Frame(self) x0_label = tk.Label(form, text="x0") x0_label.pack() x0 = tk.Entry(form, width=30) x0.insert(tk.END, str(Variant.x0)) x0.pack() y0_label = tk.Label(form, text="y0") y0_label.pack() y0 = tk.Entry(form, width=30) y0.insert(tk.END, str(Variant.y0)) y0.pack() x_label = tk.Label(form, text="X") x_label.pack() x = tk.Entry(form, width=30) x.insert(tk.END, str(Variant.x)) x.pack() h_label = tk.Label(form, text="Grid step") h_label.pack() h = tk.Entry(form, width=30) h.insert(tk.END, str(Variant.h)) h.pack() btn_plot = tk.Button(master=form, text='Plot', command=lambda: self.update_window(x0, y0, x, h)) btn_plot.pack() btn_quit = tk.Button(master=form, text='Quit', command=exit) btn_quit.pack() author = tk.Label(form, text="Author: Temur Kholmatov B17-5") author.pack(side=tk.RIGHT, fill=tk.X) self.set_config([form, x0_label, y0_label, x_label, h_label, author], self.default_config) self.set_config([x0, y0, x, h, btn_plot, btn_quit], self.btn_config) form.pack(side=tk.BOTTOM, fill=tk.X) @staticmethod def set_config(widgets, config): """ Sets the config of widgets :param widgets: widgets for changing the bg color :param config: configs to be set for widgets :return: None """ for widget in widgets: widget.configure(**config)