def __init__(self, city_name): Gtk.Window.__init__(self, title="Temparature Chart") filename = os.path.join(CSV_DRUMP_DIR, '%s.csv' % city_name) self.connect("destroy", self.on_destroy) self.set_position(Gtk.WindowPosition.CENTER) self.set_border_width(10) self.set_size_request(800, 600) self.data = [] self.date = [] self.temperature = [] with open(filename) as csvfile: reader = csv.DictReader(csvfile) for row in reader: self.data.append(row) self.date.append(row.get('dt')) self.temperature.append(row.get('temp')) fig = Figure(figsize=(5, 5), dpi=100) ax = fig.add_subplot(111) # ax.tick_params(axis='x', rotation=90) # plt.gcf().autofmt_xdate() ax.plot([date[5:16].replace(" ", "\n") for date in self.date[-15:]], [float(temp) for temp in self.temperature[-15:]]) canvas = FigureCanvas(fig) canvas.set_size_request(400, 400) self.add(canvas) self.show_all()
def draw_chart_forcast(time_arr, val_arr): # t = np.arange(0.0, 2.0, 0.01) # s = 1 + np.sin(2 * np.pi * t) # # fig, ax = plt.subplots() # ax.plot(t, s) # # ax.set(xlabel='time (s)', ylabel='voltage (mV)', # title='About as simple as it gets, folks') # ax.grid() # plt.show() myfirstwindow = Gtk.Window() myfirstwindow.connect("delete-event", Gtk.main_quit) myfirstwindow.set_default_size(400, 400) fig = Figure(figsize=(5, 5), dpi=100) ax = fig.add_subplot(111) items = ax.plot(time_arr, val_arr) for tick in ax.get_xticklabels(): tick.set_rotation(90) sw = Gtk.ScrolledWindow() myfirstwindow.add(sw) canvas = FigureCanvas(fig) canvas.set_size_request(400, 400) sw.add_with_viewport(canvas) myfirstwindow.show_all() Gtk.main()
def draw(self): x = [5,8,10] y = [12,16,6] x2 = [6,9,11] y2 = [6,15,7] fig, ax = plt.subplots() canvas = FigureCanvas(fig) canvas.set_size_request(600,600) canvas.set_parent(self._scrolledwindow) #self._scrolledwindow.add_with_viewport(canvas) ax.bar(x, y, align='center') ax.bar(x2, y2, color='y', align='center') ax.plot() plt.title('Epic Info') plt.ylabel('Y axis') plt.xlabel('X axis') #print(dir(fig.canvas)) #plt.draw() plt.show(block=False)
def __init__(self, application): """ Create a summary page containing various statistics such as the number of logs in the logbook, the logbook's modification date, etc. :arg application: The PyQSO application containing the main Gtk window, etc. """ self.application = application self.logbook = self.application.logbook self.builder = self.application.builder glade_file_path = join(realpath(dirname(__file__)), "res", "pyqso.glade") self.builder.add_objects_from_file(glade_file_path, ("summary_page",)) self.summary_page = self.builder.get_object("summary_page") self.items = {} # Database name in large font at the top of the summary page self.builder.get_object("database_name").set_markup("<span size=\"x-large\">%s</span>" % basename(self.logbook.path)) self.items["LOG_COUNT"] = self.builder.get_object("log_count") self.items["QSO_COUNT"] = self.builder.get_object("qso_count") self.items["DATE_MODIFIED"] = self.builder.get_object("date_modified") # Yearly statistics config = configparser.ConfigParser() have_config = (config.read(expanduser('~/.config/pyqso/preferences.ini')) != []) (section, option) = ("general", "show_yearly_statistics") if(have_config and config.has_option(section, option)): if(config.getboolean("general", "show_yearly_statistics") and have_matplotlib): hbox = Gtk.HBox() label = Gtk.Label(label="Display statistics for year: ", halign=Gtk.Align.START) hbox.pack_start(label, False, False, 6) year_select = Gtk.ComboBoxText() min_year, max_year = self.get_year_bounds() if min_year and max_year: for year in range(max_year, min_year-1, -1): year_select.append_text(str(year)) year_select.append_text("") year_select.connect("changed", self.on_year_changed) hbox.pack_start(year_select, False, False, 6) self.summary_page.pack_start(hbox, False, False, 4) self.items["YEARLY_STATISTICS"] = Figure() canvas = FigureCanvas(self.items["YEARLY_STATISTICS"]) canvas.set_size_request(800, 175) canvas.show() self.summary_page.pack_start(canvas, True, True, 0) # Summary tab label and icon. tab = Gtk.HBox(homogeneous=False, spacing=0) label = Gtk.Label(label="Summary ") icon = Gtk.Image.new_from_icon_name(Gtk.STOCK_INDEX, Gtk.IconSize.MENU) tab.pack_start(label, False, False, 0) tab.pack_start(icon, False, False, 0) tab.show_all() self.logbook.notebook.insert_page(self.summary_page, tab, 0) # Append as a new tab self.logbook.notebook.show_all() return
class DonutChart(): def __init__(self, *args): self.box = args[0] # gtkBox from builder self.radius, self.width = args[1] # donut radius and width self.getStat = args[2] # function that returns stat self.supTitle = args[3] # supertitle's title self.supXPos, self.supYPos = args[4] # supertitle x and y pos self.stat = self.getStat() # grabs current stat number self.old_stat = 0 # initialize a compare variable to avoid unnecessary redraws self.maxStat = args[5] # max range of donut self.statType = args[6] # type of stat (%, Mib, MHz, W) self.statFontSize, self.supFontSize = args[ 7] # stat and supertitle font sizes self.cnvsHeight, self.cnvsWidth = args[8] # canvas width and height self.a = plt.cm.Blues # fill color self.b = plt.cm.Greys # negative color self.fig, self.ax = plt.subplots(1) # sets a single subsplot self.fig.patch.set_facecolor('white') # sets background to white self.createDonut() # creates donut chart self.createAxis() # creates equal borders and sets title self.canvas = FigureCanvas(self.fig) # attach fig to a canvas self.canvas.set_size_request(self.cnvsHeight, self.cnvsWidth) # sets canvas size self.box.add(self.canvas) # adds canvas to specified gtkBox self.anim = animation.FuncAnimation( self.fig, self.update, interval=1000, blit=True) # runs animation to update stats def createDonut(self): self.donut, _ = self.ax.pie([self.stat, self.maxStat - self.stat], radius=self.radius, colors=[self.a(0.6), self.b(0.6)], counterclock=False, startangle=180) plt.setp(self.donut, width=0.2, edgecolor='white' ) # sets the circle width and adds a white border color def createAxis(self): self.ax.axis('equal') # sets donut to be even within frame self.ax.set_title("{0}{1}".format(self.stat, self.statType), fontsize=self.statFontSize, y=0.425) # main chart title def update(self, i): self.stat = self.getStat() # function that returns up-to-date stat if self.stat != self.old_stat: # rerenders donut if the stat has changed, otherwise no update self.ax.clear( ) # clears donut before rerendering -- otherwise it builds layers indefinitely self.createAxis() # recreate axis self.createDonut() # create new donut with new stat self.fig.suptitle(self.supTitle, fontsize=self.supFontSize, x=self.supXPos, y=self.supYPos) # super chart title self.old_stat = self.stat # updates old stat
def open_detatiled_station_window(self, station_name, x=0, y=0): latest_data = [] station_url = "" #Find the correct link for the requested station for link in self.every_station_link: if link[0] == station_name: #Perform detailed scrape latest_data = detailed_station_scrape(link[1], station_name) station_url = link[1] csv_url = get_csv_link(station_url, station_name) # Build new window based on Glade file. builder = Gtk.Builder() builder.add_from_file("Station Window.glade") builder.connect_signals(Handler()) builder.get_object("label1").set_text(station_name) builder.get_object("label7").set_text(latest_data[0]) builder.get_object("label8").set_text(latest_data[1]) builder.get_object("label9").set_text(latest_data[2]) builder.get_object("label10").set_text(latest_data[3]) builder.get_object("label11").set_text(latest_data[4]) builder.get_object("label18").set_text(latest_data[5]) builder.get_object("label19").set_text(latest_data[6]) builder.get_object("label20").set_text(latest_data[7]) builder.get_object("label21").set_text(latest_data[8]) builder.get_object("label22").set_text(latest_data[9]) builder.get_object("label26").set_text(latest_data[10]) builder.get_object("label27").set_text(latest_data[11]) builder.get_object("label28").set_text(latest_data[12]) display_station_win = builder.get_object("window1") display_station_win.set_title(station_name) display_station_win.move(x,y) refresh_butt = builder.get_object("button1") refresh_butt.connect("clicked", self.on_refresh_clicked) display_station_win.connect("delete-event", self.close_window_and_remove_reference) self.list_of_current_windows.append(display_station_win)#Dogfood # Stores current window in array so they can be iterated through when saving # Graph if csv_url != "no data": temperature_data = csv_scrap(csv_url) fig = temperature_graph(temperature_data) scroll_win = builder.get_object("scrolledwindow1") canvas = FigureCanvas(fig) canvas.set_size_request(400,400) scroll_win.add_with_viewport(canvas) display_station_win.show_all()
def __init__(self, date, temp): super(Gtk.ListBoxRow, self).__init__() fig = Figure(figsize=(5, 5), dpi=100) ax = fig.add_subplot(111) ax.ylabel = 'Temperature' ax.xmargin = 2 # ax.tick_params(axis='x', rotation=90) # plt.gcf().autofmt_xdate() ax.plot(date, temp) canvas = FigureCanvas(fig) canvas.set_size_request(400, 400) self.add(canvas)
def plot_test_cost(test_cost, num_epochs, test_cost_xmin, vbox): fig = plt.figure() ax = fig.add_subplot(111) ax.plot(np.arange(test_cost_xmin, num_epochs), test_cost[test_cost_xmin:num_epochs], color='#2A6EA6') ax.set_xlim([test_cost_xmin, num_epochs]) ax.grid(True) ax.set_xlabel('Epoch') ax.set_title('Cost on the test data') canvas = FigureCanvas(fig) canvas.set_size_request(1400, 600) vbox.pack_start(canvas, True, True, 0)
def __init__(self, ylim_correct=[-50, 16], ylim_wrong=[-50, 2]): scale = 3 myfirstwindow = Gtk.Window() myfirstwindow.connect("delete-event", Gtk.main_quit) myfirstwindow.connect('destroy', lambda win: Gtk.main_quit()) myfirstwindow.set_default_size(800, 600) self.updated_correct_values_cnt = 0 self.updated_wrong_values_cnt = 0 self.figure = plt.figure(figsize=(4 * scale, 3 * scale)) self.figure.suptitle("SenSys'17 - Packetized-LTE PHY", fontsize=16) self.ax1 = self.figure.add_subplot(2, 1, 1) plt.grid(True) self.ax2 = self.figure.add_subplot(2, 1, 2) plt.grid(True) # draw and show it self.ax1.set_title("Successful Statistics") self.line1_correct, = self.ax1.plot(self.correct_rssi_vector, visible=True, label='RSSI [dBm]') self.line2_correct, = self.ax1.plot(self.correct_cqi_vector, visible=True, label='CQI') self.line3_correct, = self.ax1.plot(self.correct_noise_vector, visible=True, label='Noise [dBm]') self.ax1.legend() self.ax1.set_ylim(ylim_correct) self.ax2.set_title("Unsuccessful Statistics") self.line1_wrong, = self.ax2.plot(self.error_rssi_vector, visible=True, label='RSSI [dBm]') self.line2_wrong, = self.ax2.plot(self.error_noise_vector, visible=True, label='Noise [dBm]') self.ax2.legend() self.ax2.set_ylim(ylim_wrong) self.figure.canvas.draw() plt.ion() sw = Gtk.ScrolledWindow() myfirstwindow.add(sw) canvas = FigureCanvas(self.figure) canvas.set_size_request(1600, 1200) sw.add_with_viewport(canvas) myfirstwindow.show_all() Gtk.main()
class PlotWidget(Widgets.WidgetBase): def __init__(self, plot, width=500, height=500): super(PlotWidget, self).__init__() self.widget = FigureCanvas(plot.get_figure()) self.plot = plot self.widget.set_size_request(width, height) self.widget.show_all() def configure_window(self, wd, ht): self.logger.debug("canvas resized to %dx%d" % (wd, ht)) fig = self.plot.get_figure() fig.set_size_inches(float(wd) / fig.dpi, float(ht) / fig.dpi)
def plot_test_accuracy(test_accuracy, num_epochs, test_accuracy_xmin, vbox): fig = plt.figure() ax = fig.add_subplot(111) ax.plot(np.arange(test_accuracy_xmin, num_epochs), [ accuracy / 100.0 for accuracy in test_accuracy[test_accuracy_xmin:num_epochs] ], color='#2A6EA6') ax.set_xlim([test_accuracy_xmin, num_epochs]) ax.grid(True) ax.set_xlabel('Epoch') ax.set_title('Accuracy (%) on the test data') canvas = FigureCanvas(fig) canvas.set_size_request(1400, 600) vbox.pack_start(canvas, True, True, 0)
def update_torch_data(self, str_txt): self.torch_lock.acquire() input_data = self.torch_show_data["torch_in"] fulconv_data = self.torch_show_data["torch_out"] self.torch_show_data.clear() self.torch_lock.release() self.torch_busy = 0 strbuf = Gtk.TextBuffer() strbuf.set_text("") self.show_text_view.set_buffer(strbuf) fig = Figure(figsize=(5, 4), dpi=80) ax01 = fig.add_subplot(2, 2, 1) ax01.set_title(self.str_img_fn) ax01.imshow(input_data, cmap='gray', origin='lower') #ax01.axis('off') ax02 = fig.add_subplot(2, 2, 2) np_weight = self.np_convs_weights[0] wpe = np_weight.shape draw_conv = draw_data( np_weight.reshape(wpe[0] * wpe[1], wpe[2], wpe[3])) #draw_conv = draw_data(np_weight.reshape(wpe[0],wpe[1],wpe[2]) ) ax02.imshow(draw_conv, cmap='gray', origin='lower') ax02.set_title("conv_weight") ax03 = fig.add_subplot(2, 2, 3) ax03.set_title(self.str_labels[0]) ax03.imshow(fulconv_data[0][0], cmap='hot', origin='lower') ax04 = fig.add_subplot(2, 2, 4) ax04.imshow(fulconv_data[0][1], cmap='cool', origin='lower') ax04.set_title(self.str_labels[1]) canvas = FigureCanvas(fig) # a Gtk.DrawingArea canvas.set_size_request(800, 620) self.show_win.remove(self.show_view) self.show_win.add(canvas) self.show_win.show_all() self.show_view = canvas return False
def create_ui(self): self.fig = Figure(figsize=(8, 8), dpi=100) self.axes = [] sw = Gtk.ScrolledWindow() plot_box = Gtk.VBox() sw.add_with_viewport(plot_box) canvas = FigureCanvas(self.fig) canvas.set_size_request(500, 600) plot_box.pack_start(canvas, True, True, 0) toolbar = NavigationToolbar2(canvas, sw) self.widget.pack_start(toolbar, False, False, 0) self.widget.add(sw)
def onGoPressed(self, button): symbol = self.symbol.get_text() asset = pd.io.data.DataReader(symbol, 'yahoo') figure = Figure(figsize=(5, 4), dpi=100, frameon=False) subplot = figure.add_subplot(1, 1, 1) subplot.plot(asset.index, asset['Adj Close']) subplot.autoscale_view(True, True, True) canvas = FigureCanvas(figure) canvas.set_size_request(500, 250) sw = self.app.builder.get_object('scrolledwindow1') # remove old children for child in sw.get_children(): sw.remove(child) sw.add(canvas) sw.show_all()
class PlotterGUI: def __init__(self): self.builder = Gtk.Builder() self.builder.add_from_file("plotter.xml") self.window = self.builder.get_object("plotter_window") cdt = plotter.get_dict_from_file("data/test.txt") plt = plotter.get_plot_from_dict(cdt) plt.draw() self.canvas = FigureCanvas(plt.gcf()) self.canvas.set_size_request(750, 550) self.builder.get_object("plotter_plot_scrollable").add_with_viewport( self.canvas) self.toolbar = NavigationToolbar(self.canvas, self.window) self.builder.get_object( "plotter_toolbar_scrollable").add_with_viewport(self.toolbar) self.window.show_all() def destroy(self): self.window.destroy()
def plot_overlay(test_accuracy, training_accuracy, num_epochs, xmin, training_set_size, vbox): fig = plt.figure() ax = fig.add_subplot(111) ax.plot(np.arange(xmin, num_epochs), [accuracy / 100.0 for accuracy in test_accuracy], color='#2A6EA6', label="Accuracy on the test data") ax.plot(np.arange(xmin, num_epochs), [ accuracy * 100.0 / training_set_size for accuracy in training_accuracy ], color='#FFA933', label="Accuracy on the training data") ax.grid(True) ax.set_xlim([xmin, num_epochs]) ax.set_xlabel('Epoch') ax.set_ylim([90, 100]) plt.legend(loc="lower right") #plt.show() canvas = FigureCanvas(fig) canvas.set_size_request(1400, 600) vbox.pack_start(canvas, True, True, 0)
def __init__(self): Gtk.Window.__init__(self, title="ADC View Window") self.set_default_size(800, 800) self.figure = Figure(figsize=(8, 8), dpi=100) sw = Gtk.ScrolledWindow() self.add(sw) # A scrolled window border goes outside the scrollbars and viewport sw.set_border_width(10) canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea canvas.set_size_request(750, 750) sw.add_with_viewport(canvas) self.show_all() self.sw = sw self.canvas = canvas self.femb = None self.reset()
def plot_trend(self, column0, column1, column): if column == "Atomic Radius": table = "Crystal" if column == "Covalent Radius": table = "Crystal" if column == "Van der Waals Radius": table = "Crystal" if column == "Electron Affinity": table = "Overview" con = lite.connect(sqlfile) ind = [] val = [] name = [] with con: cur = con.cursor() cstr = "SELECT * from " + table cur.execute(cstr) while True: # names = row[1] row = cur.fetchone() if row == None: break if column == "Atomic Radius": col = row[2] unit = " ($\AA$)" if column == "Covalent Radius": col = row[3] unit = " ($\AA$)" if column == "Van der Waals Radius": col = row[4] unit = " ($\AA$)" if column == "Electron Affinity": col = row[7] unit = " (kJ/mol)" try: float(col) ind.append(int(row[0])) val.append(float(col)) name.append(str(row[1])) except ValueError: name.append(str(row[1])) ind.append(int(row[0])) val.append("NaN") x = np.array(ind).astype(np.double) y = np.array(val).astype(np.double) # Plot # plt.style.use('ptbl') p_window = Gtk.Window() p_window.set_default_size(750, 500) p_header = Gtk.HeaderBar() p_window.set_titlebar(p_header) p_header.set_subtitle("Periodic Table") p_header.set_title(column) p_header.set_show_close_button(True) c = np.random.randint(1, 50, size=120) fig = Figure(figsize=(10, 6), dpi=100) ax = fig.add_subplot(111) ax.set_ylabel(column + unit, fontsize=20) ax.set_xlabel("Atomic Number") for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] + ax.get_xticklabels() + ax.get_yticklabels()): item.set_fontsize(14) item.set_fontweight("bold") for axis in ['top', 'bottom', 'left', 'right']: ax.spines[axis].set_linewidth(2.5) ax.grid(True) ax.set_xticks([1, 11, 19, 37, 55, 87]) sc = ax.scatter(x, y) ax.plot(x, y, "-") annot = ax.annotate("", xy=(0, 0), xytext=(20, 20), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), weight="bold", color="#ffffff") annot.set_visible(False) def update_annot(ind): pos = sc.get_offsets()[ind["ind"][0]] annot.xy = pos namel = (str([name[n] for n in ind["ind"]])) vall = str([val[n] for n in ind["ind"]]) text = "{}, {}".format(namel[2:-2], vall[1:-1]) annot.set_text(text) annot.get_bbox_patch().set_facecolor("#5777C0") annot.get_bbox_patch().set_alpha(0.9) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = sc.contains(event) if cont: update_annot(ind) annot.set_visible(True) fig.canvas.draw_idle() else: if vis: annot.set_visible(False) fig.canvas.draw_idle() canvas = FigureCanvas(fig) fig.canvas.mpl_connect("motion_notify_event", hover) sw = Gtk.ScrolledWindow() p_window.add(sw) canvas.set_size_request(750, 500) sw.add_with_viewport(canvas) p_window.show_all()
class App(Gtk.Application): def __init__(self): ''' Build GUI ''' # build GUI from glade file self.builder = Gtk.Builder() self.glade_file = os.path.join(curr_dir, 'kfit.glade') self.builder.add_from_file(self.glade_file) # get the necessary ui objects self.main_window = self.builder.get_object('main_window') self.graph_box = self.builder.get_object('graph_box') self.gau_sw = self.builder.get_object('param_scroll_gau') self.lor_sw = self.builder.get_object('param_scroll_lor') self.voi_sw = self.builder.get_object('param_scroll_voi') self.lin_sw = self.builder.get_object('param_scroll_lin') self.param_viewport_gau = self.builder.get_object('param_viewport_gau') self.param_viewport_lor = self.builder.get_object('param_viewport_lor') self.param_viewport_voi = self.builder.get_object('param_viewport_voi') self.param_viewport_lin = self.builder.get_object('param_viewport_lin') self.statusbar_viewport = self.builder.get_object('statusbar_viewport') self.data_treeview = self.builder.get_object('data_treeview') self.column_entry_x = self.builder.get_object('column_entry_x') self.column_entry_y = self.builder.get_object('column_entry_y') self.graph_box = self.builder.get_object('graph_box') self.fname_textview = self.builder.get_object('fname_textview') self.fit_button = self.builder.get_object('fit_button') self.reset_button = self.builder.get_object('reset_button') self.settings_button = self.builder.get_object('settings_button') self.import_button = self.builder.get_object('import_button') self.export_button = self.builder.get_object('export_button') self.help_button = self.builder.get_object('help_button') self.output_textview = self.builder.get_object('output_textview') self.settings_dialog = self.builder.get_object('settings_dialog') self.sep_entry = self.builder.get_object('sep_entry') self.header_entry = self.builder.get_object('header_entry') self.skiprows_entry = self.builder.get_object('skiprows_entry') self.dtype_entry = self.builder.get_object('dtype_entry') self.encoding_entry = self.builder.get_object('encoding_entry') self.fit_method_entry = self.builder.get_object('fit_method_entry') self.add_gau = self.builder.get_object('add_gau') self.rem_gau = self.builder.get_object('rem_gau') self.add_lor = self.builder.get_object('add_lor') self.rem_lor = self.builder.get_object('rem_lor') self.add_voi = self.builder.get_object('add_voi') self.rem_voi = self.builder.get_object('rem_voi') self.add_lin = self.builder.get_object('add_lin') self.rem_lin = self.builder.get_object('rem_lin') # define other class attributes self.title = 'kfit' self.file_name = '' self.xcol_idx = 0 self.ycol_idx = 1 self.cmode_state = 0 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # configure help button self.help_button.set_label(' Help') help_image = Gtk.Image() help_image.set_from_file( os.path.join(curr_dir, '../images/dialog-question-symbolic.svg') ) self.help_button.set_image(help_image) self.help_button.set_always_show_image(True) # for graph... x = np.linspace(0, 10, 500) y = models.gauss(x, 0.5, 4, 0.4) + \ models.gauss(x, 0.8, 5, 0.2) + \ models.gauss(x, 0.4, 6, 0.3) + 0.2 self.data = pd.DataFrame([x, y]).T self.data.columns = ['x', 'y'] self.x = self.data['x'].values self.y = self.data['y'].values self.xmin = self.data['x'].min() self.xmax = self.data['x'].max() plt.style.use(os.path.join(curr_dir, 'kfit.mplstyle')) self.figure = Figure(figsize=(10, 4), dpi=60) self.canvas = FigureCanvas(self.figure) self.canvas.set_size_request(900, 400) self.toolbar = NavigationToolbar(self.canvas, self.main_window) self.graph_box.pack_start(self.toolbar, True, True, 0) self.graph_box.pack_start(self.canvas, True, True, 0) self.cmode_toolitem = Gtk.ToolItem() self.cmode_box = Gtk.Box() self.cmode_box.set_margin_start(24) self.cmode_box.set_margin_end(36) self.cmode_radio_off = Gtk.RadioButton.new_with_label_from_widget( None, label='off' ) self.cmode_radio_off.connect('toggled', self.toggle_copy_mode) self.cmode_radio_x = Gtk.RadioButton.new_from_widget( self.cmode_radio_off ) self.cmode_radio_x.set_label('x') self.cmode_radio_x.connect('toggled', self.toggle_copy_mode) self.cmode_radio_y = Gtk.RadioButton.new_from_widget( self.cmode_radio_off ) self.cmode_radio_y.set_label('y') self.cmode_radio_y.connect('toggled', self.toggle_copy_mode) self.cmode_box.pack_start( Gtk.Label(label='Copy mode:'), False, False, 0 ) self.cmode_box.pack_start(self.cmode_radio_off, False, False, 0) self.cmode_box.pack_start(self.cmode_radio_x, False, False, 0) self.cmode_box.pack_start(self.cmode_radio_y, False, False, 0) self.cmode_toolitem.add(self.cmode_box) self.toolbar.insert(self.cmode_toolitem, -1) # for fit... self.fit_method = 'least_squares' self.model = None self.result = None self.yfit = None self.ngau = 0 self.nlor = 0 self.nvoi = 0 self.nlin = 1 self.curves_df = None self.params_df = None self.params = Parameters() self.guesses = { 'value': {}, 'min': {}, 'max': {} } self.usr_vals = { 'value': {}, 'min': {}, 'max': {} } self.usr_entry_widgets = {} self.cid = None # for data view... self.fname_buffer = Gtk.TextBuffer() self.display_data() # for output... self.output_buffer = Gtk.TextBuffer() self.output_textview.set_buffer(self.output_buffer) # file import settings self.sep = ',' self.header = 'infer' self.index_col = None self.skiprows = None self.dtype = None self.encoding = None # show initial plot self.plot() # add statusbar self.statusbar = Gtk.Statusbar() self.statusbar.set_margin_top(0) self.statusbar.set_margin_bottom(0) self.statusbar.set_margin_start(0) self.statusbar.set_margin_end(0) self.statusbar_viewport.add(self.statusbar) # connect signals events = { 'on_fit_button_clicked': self.fit, 'on_import_button_clicked': self.get_data, 'on_settings_button_clicked': self.run_settings_dialog, 'on_reset_button_clicked': self.hard_reset, 'on_add_gau_clicked': self.on_add_gau_clicked, 'on_rem_gau_clicked': self.on_rem_gau_clicked, 'on_add_lor_clicked': self.on_add_lor_clicked, 'on_rem_lor_clicked': self.on_rem_lor_clicked, 'on_add_voi_clicked': self.on_add_voi_clicked, 'on_rem_voi_clicked': self.on_rem_voi_clicked, 'on_add_lin_clicked': self.on_add_lin_clicked, 'on_rem_lin_clicked': self.on_rem_lin_clicked, 'on_column_entry_changed': self.get_column_index, 'on_export_button_clicked': self.export_data, } self.builder.connect_signals(events) # add accelerators / keyboard shortcuts self.accelerators = Gtk.AccelGroup() self.main_window.add_accel_group(self.accelerators) self.add_accelerator(self.fit_button, '<Control>f') self.add_accelerator(self.reset_button, '<Control>r') self.add_accelerator(self.settings_button, '<Control>p') self.add_accelerator(self.import_button, '<Control>o') self.add_accelerator(self.export_button, '<Control>s') self.add_accelerator(self.add_gau, 'g') self.add_accelerator(self.rem_gau, '<Shift>g') self.add_accelerator(self.add_lor, 'l') self.add_accelerator(self.rem_lor, '<Shift>l') self.add_accelerator(self.add_voi, 'v') self.add_accelerator(self.rem_voi, '<Shift>v') self.add_accelerator(self.add_lin, 'n') self.add_accelerator(self.rem_lin, '<Shift>n') # configure interface self.main_window.connect('destroy', Gtk.main_quit) self.init_param_widgets() # show the app window self.main_window.show_all() def plot(self): self.figure.clear() self.axis = self.figure.add_subplot(111) self.set_xlims() if len(self.x) >= 1000: self.axis.plot( self.x, self.y, c='#af87ff', linewidth=12, label='data' ) else: self.axis.scatter( self.x, self.y, s=200, c='#af87ff', edgecolors='black', linewidth=1, label='data' ) if self.result is not None: self.yfit = self.result.best_fit self.axis.plot(self.x, self.yfit, c='r', linewidth=2.5) cmap = cm.get_cmap('gnuplot') components = self.result.eval_components() for i, comp in enumerate(components): self.axis.plot( self.x, components[comp], linewidth=2.5, linestyle='--', c=cmap(i/len(components)), label=comp[:comp.find('_')] ) self.axis.set_xlabel(self.data.columns[self.xcol_idx]) self.axis.set_ylabel(self.data.columns[self.ycol_idx]) self.axis.legend(loc='best') self.axis.set_xlim([self.xmin, self.xmax]) self.canvas.draw() def fit(self, source=None, event=None): self.cmode_radio_off.set_active(True) self.toggle_copy_mode(self.cmode_radio_off) self.set_xrange_to_zoom() self.filter_nan() self.set_params() self.result = self.model.fit( data=self.y, params=self.params, x=self.x, method=self.fit_method ) self.output_buffer.set_text(self.result.fit_report()) self.plot() # overwrite widgets to clear input (not ideal method..) self.init_param_widgets() def init_model(self): # note: increment() ensures nlin >= 1 self.model = models.line_mod(self.nlin) if self.ngau != 0: self.model += models.gauss_mod(self.ngau) if self.nlor != 0: self.model += models.lor_mod(self.nlor) if self.nvoi != 0: self.model += models.voigt_mod(self.nvoi) self.statusbar.push( self.statusbar.get_context_id('info'), "Model updated: " + str([self.ngau, self.nlor, self.nvoi, self.nlin]) ) def init_param_widgets(self): self.init_model() self.usr_entry_widgets = { 'value': {}, 'min': {}, 'max': {} } labels = {} rnd = 3 # decimals to round to in placeholder text self.clear_param_viewports() # main boxes to hold user entry widgets self.vbox_gau = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_lor = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_voi = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_lin = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) for param_name in self.model.param_names: # set param label text labels[param_name] = Gtk.Label() labels[param_name].set_text(param_name) # make user entry widgets for key in self.usr_entry_widgets: self.usr_entry_widgets[key][param_name] = Gtk.Entry() if param_name in self.usr_vals[key]: self.usr_entry_widgets[key][param_name]\ .set_placeholder_text( str(round(self.usr_vals[key][param_name], rnd)) ) else: self.usr_entry_widgets[key][param_name]\ .set_placeholder_text(key) # set up connections self.usr_entry_widgets[key][param_name].connect( 'changed', self.update_usr_vals, self.usr_entry_widgets ) # add widgets to respective layouts vbox_sub = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) for key in self.usr_entry_widgets: vbox_sub.pack_start( self.usr_entry_widgets[key][param_name], False, False, pad ) if param_name.find('gau') != -1: self.vbox_gau.pack_start(labels[param_name], False, False, pad) self.vbox_gau.pack_start(vbox_sub, False, False, pad) self.vbox_gau.set_halign(Gtk.Align.CENTER) if param_name.find('lor') != -1: self.vbox_lor.pack_start(labels[param_name], False, False, pad) self.vbox_lor.pack_start(vbox_sub, False, False, pad) self.vbox_lor.set_halign(Gtk.Align.CENTER) if param_name.find('voi') != -1: self.vbox_voi.pack_start(labels[param_name], False, False, pad) self.vbox_voi.pack_start(vbox_sub, False, False, pad) self.vbox_voi.set_halign(Gtk.Align.CENTER) if param_name.find('lin') != -1: self.vbox_lin.pack_start(labels[param_name], False, False, pad) self.vbox_lin.pack_start(vbox_sub, False, False, pad) self.vbox_lin.set_halign(Gtk.Align.CENTER) # Resize all of the entry widgets for key in self.usr_entry_widgets: for param, widget in self.usr_entry_widgets[key].items(): widget.set_width_chars(7) # add/replace box in viewport self.param_viewport_gau.add(self.vbox_gau) self.param_viewport_lor.add(self.vbox_lor) self.param_viewport_voi.add(self.vbox_voi) self.param_viewport_lin.add(self.vbox_lin) for viewport in [self.param_viewport_gau, self.param_viewport_lor, self.param_viewport_voi, self.param_viewport_lin]: viewport.show_all() if self.result is not None: self.set_params() self.update_param_widgets() def update_usr_vals(self, widget, entry_widget_dict): # get text input from each usr_entry_widget for val_type, param_dict in entry_widget_dict.items(): for param, param_widget in param_dict.items(): try: self.usr_vals[val_type][param] = \ float(param_widget.get_text()) except Exception: pass def update_param_widgets(self): rnd = 3 # the 'value' placeholder text is the result for that param # taken from self.result # the 'min' and 'max' text is from either the self.guesses # or from self.usr_vals for param in self.params: if param in self.result.best_values: self.usr_entry_widgets['value'][param].set_placeholder_text( str(round(self.result.best_values[param], rnd)) ) self.usr_entry_widgets['min'][param].set_placeholder_text( str(round(self.params[param].min, rnd)) ) self.usr_entry_widgets['max'][param].set_placeholder_text( str(round(self.params[param].max, rnd)) ) def guess_params(self, source=None, event=None): for comp in self.model.components: if comp.prefix.find('gau') != -1 or \ comp.prefix.find('lor') != -1 or \ comp.prefix.find('voi') != -1: # need to define explicitly to make proper guesses c = comp.prefix + 'center' a = comp.prefix + 'amplitude' s = comp.prefix + 'sigma' f = comp.prefix + 'fraction' self.guesses['value'][c] = \ self.data.iloc[:, self.xcol_idx].mean() self.guesses['value'][a] = \ self.data.iloc[:, self.ycol_idx].mean() self.guesses['value'][s] = \ self.data.iloc[:, self.xcol_idx].std() self.guesses['min'][c] = None self.guesses['min'][a] = 0 self.guesses['min'][s] = 0 self.guesses['max'][c] = None self.guesses['max'][a] = None self.guesses['max'][s] = None if comp.prefix.find('voi') != -1: self.guesses['value'][f] = 0.5 self.guesses['min'][f] = 0 self.guesses['max'][f] = 1 else: slope = comp.prefix + 'slope' intc = comp.prefix + 'intercept' for p in [slope, intc]: self.guesses['value'][p] = \ self.data.iloc[:, self.ycol_idx].mean() self.guesses['min'][p] = None self.guesses['max'][p] = None def set_params(self, source=None, event=None): self.params = Parameters() self.guess_params() self.update_usr_vals(None, self.usr_entry_widgets) vals = {} # fill params with any user-entered values # fill in blanks with guesses for param_name in self.model.param_names: for val_type in ['value', 'min', 'max']: if param_name in self.usr_vals[val_type]: vals[val_type] = self.usr_vals[val_type][param_name] else: vals[val_type] = self.guesses[val_type][param_name] self.params.add( name=param_name, value=vals['value'], vary=True, min=vals['min'], max=vals['max'] ) def set_xlims(self, source=None, event=None): self.xmin = np.min(self.x) - 0.02*(np.max(self.x) - np.min(self.x)) self.xmax = np.max(self.x) + 0.02*(np.max(self.x) - np.min(self.x)) def set_xrange_to_zoom(self): self.xmin, self.xmax = self.axis.get_xlim() range_bool = (self.x >= self.xmin) & (self.x <= self.xmax) self.x = self.x[range_bool] self.y = self.y[range_bool] def filter_nan(self): if True in np.isnan(self.x) or True in np.isnan(self.y): nanbool = (~np.isnan(self.x) & ~np.isnan(self.y)) self.x = self.x[nanbool] self.y = self.y[nanbool] def increment(self, val, add): if add: if val == 'gau': self.ngau += 1 if val == 'lor': self.nlor += 1 if val == 'voi': self.nvoi += 1 if val == 'lin': self.nlin += 1 if not add: if val == 'gau': self.ngau -= 1 if val == 'lor': self.nlor -= 1 if val == 'voi': self.nvoi -= 1 if val == 'lin': self.nlin -= 1 # make sure value doesn't go below zero if self.ngau < 0: self.ngau = 0 if self.nlor < 0: self.nlor = 0 if self.nvoi < 0: self.nvoi = 0 if self.nlin < 1: self.nlin = 1 def clear_param_viewports(self): # clear any existing widgets from viewports for viewport in [self.param_viewport_gau, self.param_viewport_lin, self.param_viewport_lor, self.param_viewport_voi]: if viewport.get_child(): viewport.remove(viewport.get_child()) def hard_reset(self, source=None, event=None): self.clear_param_viewports() self.ngau = 0 self.nlor = 0 self.nvoi = 0 self.nlin = 1 self.init_model() self.params = Parameters() self.result = None self.params_df = None self.curves_df = None self.guesses = { 'value': {}, 'min': {}, 'max': {} } self.usr_vals = { 'value': {}, 'min': {}, 'max': {} } self.output_buffer.set_text('') self.init_param_widgets() self.get_column_index() self.plot() self.cmode_radio_off.set_active(True) self.toggle_copy_mode(self.cmode_radio_off) def on_add_gau_clicked(self, source=None, event=None): self.increment('gau', True) self.init_param_widgets() def on_rem_gau_clicked(self, source=None, event=None): self.increment('gau', False) self.init_param_widgets() def on_add_lor_clicked(self, source=None, event=None): self.increment('lor', True) self.init_param_widgets() def on_rem_lor_clicked(self, source=None, event=None): self.increment('lor', False) self.init_param_widgets() def on_add_voi_clicked(self, source=None, event=None): self.increment('voi', True) self.init_param_widgets() def on_rem_voi_clicked(self, source=None, event=None): self.increment('voi', False) self.init_param_widgets() def on_add_lin_clicked(self, source=None, event=None): self.increment('lin', True) self.init_param_widgets() def on_rem_lin_clicked(self, source=None, event=None): self.increment('lin', False) self.init_param_widgets() def get_data(self, source=None, event=None): self.cmode_radio_off.set_active(True) self.toggle_copy_mode(self.cmode_radio_off) # reset column indices self.xcol_idx = 0 self.column_entry_x.set_text(str(self.xcol_idx)) self.ycol_idx = 1 self.column_entry_y.set_text(str(self.ycol_idx)) # open file dialog self.dialog = Gtk.FileChooserDialog( title='Import data file...', parent=self.main_window, action=Gtk.FileChooserAction.OPEN, ) self.dialog.add_buttons( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK ) filter_csv = Gtk.FileFilter() filter_csv.set_name('.csv files') filter_csv.add_mime_type('text/csv') self.dialog.add_filter(filter_csv) filter_any = Gtk.FileFilter() filter_any.set_name('All files') filter_any.add_pattern("*") self.dialog.add_filter(filter_any) self.dialog.set_default_size(800, 400) response = self.dialog.run() if response == Gtk.ResponseType.OK: self.file_name = self.dialog.get_filename() try: df = tools.to_df( self.file_name, sep=self.sep, header=self.header, index_col=self.index_col, skiprows=self.skiprows, dtype=self.dtype, encoding=self.encoding ) df.iloc[:, self.xcol_idx] df.iloc[:, self.ycol_idx] except Exception: self.statusbar.push( self.statusbar.get_context_id('import_error'), file_import_error_msg ) self.dialog.destroy() return else: self.file_name = None self.statusbar.push( self.statusbar.get_context_id('import_canceled'), 'Import canceled.' ) self.dialog.destroy() return self.dialog.destroy() self.data = df self.display_data() self.result = None # reset x, y, and xlim self.x = self.data.iloc[:, self.xcol_idx].values self.y = self.data.iloc[:, self.ycol_idx].values self.filter_nan() self.set_xlims() self.plot() self.statusbar.push( self.statusbar.get_context_id('import_finished'), 'Imported {}'.format(self.file_name) ) def display_data(self): # remove any pre-existing columns from treeview for col in self.data_treeview.get_columns(): self.data_treeview.remove_column(col) # create model # TODO: allow for other types, and infer from data col_types = [float for col in self.data.columns] list_store = Gtk.ListStore(*col_types) # fill model with data for row in self.data.itertuples(): list_store.append( [row[i+1] for i, col in enumerate(self.data.columns)] ) # set it as TreeView model self.data_treeview.set_model(list_store) # Create and append columns for i, col in enumerate(self.data.columns): renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn(col, renderer, text=i) self.data_treeview.append_column(column) self.fname_buffer.set_text('Source: {}'.format(self.file_name)) self.fname_textview.set_buffer(self.fname_buffer) def export_data(self, source=None, event=None): ''' Export fit data and parameters to .csv ''' self.file_export_dialog = Gtk.FileChooserDialog( title='Export results file...', parent=self.main_window, action=Gtk.FileChooserAction.SAVE, ) self.file_export_dialog.add_buttons( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK ) filter_csv = Gtk.FileFilter() filter_csv.set_name('.csv files') filter_csv.add_mime_type('text/csv') self.file_export_dialog.add_filter(filter_csv) response = self.file_export_dialog.run() if response == Gtk.ResponseType.OK: export_filename = self.file_export_dialog.get_filename() if export_filename.find('.csv') == -1: export_filename += '.csv' self.process_results() self.curves_df.to_csv(export_filename) self.params_df.to_csv( '{}.params.csv'.format( export_filename[:export_filename.find('.csv')] ) ) self.statusbar.push( self.statusbar.get_context_id('export_results'), 'Exported: {}'.format(export_filename) ) else: self.statusbar.push( self.statusbar.get_context_id('export_canceled'), 'Export canceled.' ) self.file_export_dialog.hide() def process_results(self): if self.result is not None: self.params_df = pd.DataFrame.from_dict( self.result.best_values, orient='index' ) self.params_df.index.name = 'parameter' self.params_df.columns = ['value'] curves_dict = { 'data': self.y, 'total_fit': self.result.best_fit, } components = self.result.eval_components() for i, comp in enumerate(components): curves_dict[comp[:comp.find('_')]] = components[comp] self.curves_df = pd.DataFrame.from_dict(curves_dict) self.curves_df.index = self.x self.curves_df.index.name = self.data.columns[self.xcol_idx] else: self.statusbar.push( self.statusbar.get_context_id('no_fit_results'), 'No fit results to export!' ) self.file_export_dialog.hide() def get_column_index(self, source=None, event=None): # make sure user enters index that can be converted to int try: idx_x = int(self.column_entry_x.get_text()) except ValueError: self.statusbar.push( self.statusbar.get_context_id('idx_type_error'), idx_type_error_msg ) self.column_entry_x.set_text('') return try: idx_y = int(self.column_entry_y.get_text()) except ValueError: self.statusbar.push( self.statusbar.get_context_id('idx_type_error'), idx_type_error_msg ) self.column_entry_y.set_text('') return self.xcol_idx = idx_x self.ycol_idx = idx_y self.result = None # make sure user enters an index that's in the data range try: self.x = self.data.iloc[:, self.xcol_idx] except IndexError: self.statusbar.push( self.statusbar.get_context_id('idx_range_error'), idx_range_error_msg ) self.column_entry_x.set_text(None) return try: self.y = self.data.iloc[:, self.ycol_idx] except IndexError: self.statusbar.push( self.statusbar.get_context_id('idx_range_error'), idx_range_error_msg ) self.column_entry_y.set_text(None) return self.xmin = np.min(self.x) self.xmax = np.max(self.x) self.statusbar.push( self.statusbar.get_context_id('new_idx_success'), 'Column Index (X) = ' + str(self.xcol_idx) + ', ' + 'Column Index (Y) = ' + str(self.ycol_idx) ) self.plot() def run_settings_dialog(self, source=None, event=None): ''' Opens the settings dialog window and controls its behavior. ''' # set label text for help button # couldn't do this in glade for some reason... import_help_button = self.builder.get_object('import_help_button') import_help_button.set_label('help') fit_help_button = self.builder.get_object('fit_help_button') fit_help_button.set_label('help') # run the dialog response = self.settings_dialog.run() if response == Gtk.ResponseType.APPLY: self.sep = self.sep_entry.get_text() if self.header_entry.get_text() != 'infer': self.header = int(self.header_entry.get_text()) else: self.header = 'infer' if self.skiprows_entry.get_text() == 'None': self.skiprows = None else: self.skiprows = int(self.skiprows_entry.get_text()) if self.dtype_entry.get_text() == 'None': self.dtype = None else: self.dtype = self.dtype_entry.get_text() if self.encoding_entry.get_text() == 'None': self.encoding = None else: self.encoding = self.encoding_entry.get_text() if self.fit_method_entry.get_text() != 'least_squares': self.fit_method = self.fit_method_entry.get_text() else: self.fit_method = 'least_squares' else: self.settings_dialog.hide() self.settings_dialog.hide() def toggle_copy_mode(self, button): state_messages = { 0: 'Copy mode off', 1: 'Copy mode on | x-value', 2: 'Copy mode on | y-value', } if button.get_active(): if button.get_label() == 'x': self.cmode_state = 1 self.mpl_cursor = Cursor( self.axis, lw=1, c='red', linestyle='--' ) self.cid = self.canvas.mpl_connect( 'button_press_event', self.get_coord_click ) elif button.get_label() == 'y': self.cmode_state = 2 self.mpl_cursor = Cursor( self.axis, lw=1, c='red', linestyle='--' ) self.cid = self.canvas.mpl_connect( 'button_press_event', self.get_coord_click ) else: # copy mode off self.cmode_state = 0 self.mpl_cursor = None self.canvas.mpl_disconnect(self.cid) self.statusbar.push( self.statusbar.get_context_id('cmode_state'), state_messages[self.cmode_state] ) def get_coord_click(self, event): x_copy, y_copy = str(round(event.xdata, 3)), str(round(event.ydata, 3)) if self.cmode_state == 1: self.clipboard.set_text(x_copy, -1) self.statusbar.push( self.statusbar.get_context_id('copied_x'), 'Copied X=' + str(x_copy) + ' to clipboard!' ) if self.cmode_state == 2: self.clipboard.set_text(y_copy, -1) self.statusbar.push( self.statusbar.get_context_id('copied_y'), 'Copied Y=' + str(y_copy) + ' to clipboard!' ) def add_accelerator(self, widget, accelerator, signal="activate"): ''' Adds keyboard shortcuts ''' if accelerator is not None: key, mod = Gtk.accelerator_parse(accelerator) widget.add_accelerator( signal, self.accelerators, key, mod, Gtk.AccelFlags.VISIBLE )
class BpcvMain: def __init__(self): imgs_dir = "./imgs_comp_box" imgs_mask_dir = "./imgs_mask_box" self.str_imgs_fns = [] self.str_mask_fns = [] dirs = [] for parent, dirnames, filenames in os.walk(imgs_mask_dir): for dirname in dirnames: dirs.append(dirname) for str_dir in dirs: str_dir_path = imgs_mask_dir + "/" + str_dir for parent, dirnames, filenames in os.walk(str_dir_path): for filename in filenames: str_path = str_dir_path + "/" + filename self.str_mask_fns.append(str_path) idx = filename.find(".png") str_img_path = imgs_dir + "/" + str_dir + "/" + filename[: idx] + ".png" self.str_imgs_fns.append(str_img_path) self.autoencoder = AutoEncoder() self.win = Gtk.Window() self.win.connect("delete-event", self.win_quit) self.win.set_default_size(1000, 600) self.win.set_title("show imgs") self.sw = Gtk.ScrolledWindow() self.win.add(self.sw) self.sw.set_border_width(2) fig = Figure(figsize=(8, 8), dpi=80) self.canvas = FigureCanvas(fig) self.canvas.set_size_request(1000, 600) self.sw.add(self.canvas) self.win.show_all() self.torch_lock = threading.Lock() self.torch_show_data = {} self.n_test_imgs = 5 self.torch_show_data["mess_quit"] = False thread_torch = Encoder_Thread(self.update_torch_data, self.torch_lock, self.autoencoder, self.str_imgs_fns, self.str_mask_fns, self.torch_show_data, wh=97, max_n_loop=1, n_loop=0, idx_segment=0) thread_torch.start() def update_torch_data(self, str_txt): self.torch_lock.acquire() np_imgs = self.torch_show_data["np_imgs"] np_mask_imgs = self.torch_show_data["np_mask_imgs"] np_decoded = self.torch_show_data["np_decoded"] self.torch_lock.release() np_imgs = np_imgs.transpose((0, 2, 3, 1)) self.sw.remove(self.canvas) axs = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] fig = Figure(figsize=(8, 8), dpi=80) for n in range(3): for i in range(self.n_test_imgs): axs[n][i] = fig.add_subplot(3, self.n_test_imgs, n * self.n_test_imgs + i + 1) for i in range(self.n_test_imgs): axs[0][i].imshow(np_imgs[i] * 0.5 + 0.5, cmap='gray') axs[1][i].imshow(np_mask_imgs[i][0], cmap='gray') axs[2][i].imshow(np_decoded[i][0], cmap='gray') self.canvas = FigureCanvas(fig) self.canvas.set_size_request(1000, 600) self.sw.add(self.canvas) self.sw.show_all() def win_quit(self, _a, _b): self.torch_lock.acquire() self.torch_show_data["mess_quit"] = True self.torch_lock.release() Gtk.main_quit()
class Profile(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Profile") #f = Figure(figsize=(5,4), dpi=100) f = Figure() self.axes = f.add_subplot(111) self.axes.set_xlabel('Time (sec.)') self.axes.set_ylabel('Temperature (C)') self.axes.set_xlim(0, 5*60) self.axes.set_ylim(20, 300) self.axes.grid() self.axes.xaxis.set_major_formatter(FuncFormatter(self.format_xaxis)) self.x = [] self.y = [] self.plot, = self.axes.plot(self.x, self.y, 'o-', picker=5) self.minutes = False self.file_name = None self.canvas = FigureCanvas(f) self.canvas.set_size_request(800,600) self.canvas.mpl_connect('button_press_event', self.onclick) self.canvas.mpl_connect('button_release_event', self.onrelease) self.canvas.mpl_connect('pick_event', self.onpick) self.canvas.mpl_connect('motion_notify_event', self.onmotion) self.picking = None self.store = Gtk.ListStore(str, str) self.tree = Gtk.TreeView(self.store) renderer = Gtk.CellRendererText() renderer.set_property("editable", True) renderer.connect('edited', self.on_time_edited) column = Gtk.TreeViewColumn("Time", renderer, text=0) self.tree.append_column(column) renderer = Gtk.CellRendererText() renderer.set_property("editable", True) renderer.connect('edited', self.on_temp_edited) column = Gtk.TreeViewColumn("Temperature", renderer, text=1) self.tree.append_column(column) self.box = Gtk.Box() self.box.pack_start(self.canvas, False, False, 0) self.box.pack_start(self.tree, True, True, 0) action_group = Gtk.ActionGroup("profile_actions") action_group.add_actions([ ("FileMenu", None, "File", None, None, None), ("FileNew", Gtk.STOCK_NEW, "_New", "<control>N", None, self.on_file_new), ("FileOpen", Gtk.STOCK_OPEN, "_Open", "<control>O", None, self.on_file_open), ("FileSave", Gtk.STOCK_SAVE, "_Save", "<control>S", None, self.on_file_save), ("FileSaveAs", Gtk.STOCK_SAVE_AS, "Save _As…", "<shift><control>S", None, self.on_file_save_as), ("FileQuit", Gtk.STOCK_QUIT, "_Quit", "<control>Q", None, Gtk.main_quit) ]) uimanager = Gtk.UIManager() uimanager.add_ui_from_string(UI_INFO) accelgroup = uimanager.get_accel_group() self.add_accel_group(accelgroup) uimanager.insert_action_group(action_group) menubar = uimanager.get_widget("/MenuBar") self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox.pack_start(menubar, False, False, 0) self.vbox.pack_start(self.box, True, True, 0) self.statusbar = Gtk.Statusbar() self.status_pos = self.statusbar.get_context_id("position") self.vbox.pack_start(self.statusbar, False, False, 0) self.add(self.vbox) def open_file(self, name): reader = csv.reader(open(name, 'rb')) x, y = zip(*reader) x = [ float(i) for i in x] y = [ float(i) for i in y] self.x, self.y = x, y self.file_name = name self.set_title('Profile - ' + name) self.update_data() self.update_scale() self.canvas.draw() def save_file(self, name): writer = csv.writer(open(name, 'wd')) writer.writerows(zip(self.x, self.y)) self.file_name = name self.set_title('Profile - ' + name) def on_file_new(self, widget): self.file_name = None self.set_title('Profile') self.x = [] self.y = [] self.store.clear() self.update_data() self.update_scale() self.canvas.draw() def on_file_open(self, widget): dialog = Gtk.FileChooserDialog("", self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_current_folder_uri(Gio.file_new_for_path(os.curdir).get_uri()) response = dialog.run() if response == Gtk.ResponseType.OK: try: self.open_file(dialog.get_filename()) except: pass dialog.destroy() def on_file_save(self, widget): if self.file_name is None: self.on_file_save_as(widget) else: self.save_file(self.file_name) def on_file_save_as(self, widget): dialog = Gtk.FileChooserDialog("", self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE_AS, Gtk.ResponseType.OK)) dialog.set_current_folder_uri(Gio.file_new_for_path(os.curdir).get_uri()) response = dialog.run() if response == Gtk.ResponseType.OK: self.save_file(dialog.get_filename()) dialog.destroy() def format_xaxis(self, x, pos): return self.format_x(x) def format_x(self, val): m, s = 0, val if self.minutes: m = int(val / 60) s = val % 60 if m: return '%dm%.1fs'%(m,s) else: return '%.1fs'%s def format_y(self, val): return '%.1f°C'%val def on_time_edited(self, widget, path, text): treeiter = self.store.get_iter(path) try: m, s = "0", "0" if 'm' in text: m, text = text.split('m') if 's' in text: s, text = text.split('s') else: text = "" assert len(text) == 0 val = int(m) * 60.0 + round(float(s), 1) except: return at = max(0, int(path)) if at != 0: val = max(val, self.x[at-1]) if at != len(self.x)-1: val = min(val, self.x[at+1]) self.store.set(treeiter, 0, self.format_x(val)) self.x[int(path)] = val self.update_data() self.update_scale() self.canvas.draw() def on_temp_edited(self, widget, path, text): treeiter = self.store.get_iter(path) try: if '°' in text: text, _ = text.split('°') if 'c' in text.lower(): text, _ = text.lower().split('c') val = round(float(text), 1) except: return val = min(300.0, val) val = max(20.0, val) self.store.set(treeiter, 1, self.format_y(val)) self.y[int(path)] = val self.update_data() self.canvas.draw() def update_data(self): self.plot.set_data(self.x, self.y) def update_scale(self): if len(self.x) and self.x[-1] + 30 > 5 * 60: minutes = int((self.x[-1] + 90) / 60) else: minutes = 5 self.axes.set_xlim(0, minutes*60) def onclick(self, event): if self.picking is not None or event.button != 1: return xdata = round(event.xdata, 1) ydata = round(event.ydata, 1) at = bisect.bisect(self.x, xdata) self.x.insert(at, xdata) self.y.insert(at, ydata) self.store.insert(at, [self.format_x(xdata), self.format_y(ydata)]) self.update_data() self.update_scale() self.canvas.draw() def onrelease(self, event): if self.picking is None: return self.update_scale() self.canvas.draw() self.picking = None def onpick(self, event): on = event.artist ind = event.ind[0] if event.mouseevent.button == 1: self.picking = ind elif event.mouseevent.button == 3: self.x.pop(ind) self.y.pop(ind) self.store.remove(self.store.get_iter(Gtk.TreePath(ind))) self.update_data() self.update_scale() self.canvas.draw() def onmotion(self, event): self.statusbar.remove_all(self.status_pos) if event.xdata is None or event.ydata is None: return self.statusbar.push(self.status_pos, self.format_x(event.xdata) + ', ' + self.format_y(event.ydata)) if self.picking is None: return xdata = max(0, round(event.xdata, 1)) ydata = round(event.ydata, 1) ydata = min(300.0, ydata) ydata = max(20.0, ydata) if self.picking != 0: xdata = max(xdata, self.x[self.picking-1]) if self.picking != len(self.x)-1: xdata = min(xdata, self.x[self.picking+1]) self.x[self.picking] = xdata self.y[self.picking] = ydata treeiter = self.store.get_iter(Gtk.TreePath(self.picking)) self.store.set(treeiter, 0, self.format_x(xdata), 1, self.format_y(ydata)) self.update_data() self.canvas.draw()
class ATWindow(Gtk.Window): def __init__(self, pid): Gtk.Window.__init__(self, title="Auto-tune") self.pid = pid vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) f = matplotlib.figure.Figure() self.axes = f.add_subplot(111) self.axes.set_xlabel('Time (sec.)') self.axes.set_ylabel('Temperature (C)') self.axes.autoscale() self.out_axes = self.axes.twinx() self.out_axes.set_ylabel('OUT (%)') self.out_axes.autoscale() self.axes.grid() self.pv_x = [] self.pv_y = [] self.sv_x = [] self.sv_y = [] self.out_x = [] self.out_y = [] self.pv_plot, = self.axes.plot(self.pv_x, self.pv_y, 'b--') #b self.sv_plot, = self.axes.plot(self.sv_x, self.sv_y, 'k-') #k self.out_plot, = self.out_axes.plot(self.out_x, self.out_y, 'r:') #r self.canvas = FigureCanvas(f) self.canvas.set_size_request(800,600) vbox.add(self.canvas) hbox = Gtk.Box() self.start = Gtk.Button('Start', Gtk.STOCK_EXECUTE) self.start.connect('clicked', self.on_start) self.start.set_sensitive(False) hbox.pack_start(self.start, False, False, 0) self.stop = Gtk.Button('Stop', Gtk.STOCK_STOP) self.stop.connect('clicked', self.on_stop) self.stop.set_sensitive(False) hbox.pack_start(self.stop, False, False, 0) button = Gtk.Button('Close', Gtk.STOCK_CLOSE) button.connect('clicked', self.on_close) hbox.pack_end(button, False, False, 0) vbox.add(hbox) self.add(vbox) self.run = True self.start_at = True self.stop_at = False self.d = self.loop() self.d.addErrback(lambda x: None) self.connect('delete-event', self.on_delete) def on_start(self, widget): self.start_at = True def on_stop(self, widget): self.stop_at = True def on_delete(self, widget, event): self.run = False def on_close(self, widget): self.emit('delete-event', None) self.destroy() @twisted.internet.defer.inlineCallbacks def loop(self): start = time.time() while self.run: try: d = yield self.pid.flags() active = d['AT'] if active: self.stop.set_sensitive(True) self.start.set_sensitive(False) if self.stop_at: yield self.pid.coil('NAT') pv, mult = yield self.pid.holding_read('PV') self.pv_x.append(time.time() - start) self.pv_y.append(pv) self.pv_plot.set_data(self.pv_x, self.pv_y) self.axes.relim() self.axes.autoscale() self.canvas.draw() sv, mult = yield self.pid.holding_read('dSV') self.sv_x.append(time.time() - start) self.sv_y.append(sv) self.sv_plot.set_data(self.sv_x, self.sv_y) self.axes.relim() self.axes.autoscale() self.canvas.draw() out, mult = yield self.pid.holding_read('OUT') self.out_x.append(time.time() - start) self.out_y.append(out) self.out_plot.set_data(self.out_x, self.out_y) self.out_axes.relim() self.out_axes.autoscale() self.canvas.draw() else: self.start.set_sensitive(True) self.stop.set_sensitive(False) if self.start_at: yield self.pid.raw('ModL', 'SV') yield self.pid.raw('At', 'On') start = time.time() self.pv_x = [] self.pv_y = [] self.sv_x = [] self.sv_y = [] self.out_x = [] self.out_y = [] self.start_at = False self.stop_at = False except: pass d = twisted.internet.defer.Deferred() twisted.internet.reactor.callLater(1, d.callback, None) yield d yield self.pid.coil('NAT')
#MATPLOTLIB ANIMATION #plotwindow = Gtk.Window() #plotwindow.set_default_size(400, 400) fig1 = Figure(figsize=(5,5), dpi=100) ax1 = fig1.add_subplot(111) ax1.set_xlim(0, 300) ax1.set_ylim(0, g.num_vertices() ) ax1.set_xlabel('time') ax1.set_title('SIR Time Plot') #sw = Gtk.ScrolledWindow() #plotwindow.add(sw) canvas = FigureCanvas(fig1) canvas.set_size_request(400,400) #sw.add_with_viewport(canvas) else: count = 0 win = Gtk.OffscreenWindow() win.set_default_size(1000, 700) win.graph = GraphWidget(g, pos, edge_color=[0.6, 0.6, 0.6, 1], vertex_fill_color=state, vertex_halo=newly_infected, vertex_halo_color=[0.8, 0, 0, 0.6]) win.add(win.graph) # This function will be called repeatedly by the GTK+ main loop, and we use it
class MainWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_default_size(1000, 600) self.set_position(Gtk.WindowPosition.CENTER) self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) self.add(self.hbox) self.temperature = Gtk.Label() self.rel_humidity = Gtk.Label() self.create_left_panel() self.sep = Gtk.Separator() self.sep.set_orientation(Gtk.Orientation.VERTICAL) self.sep.get_style_context().add_class("sidebar-separator") self.hbox.pack_start(self.sep, False, True, 0) self.plot_canvas = None self.axTemperature = None self.axHumidity = None self.create_graph() self.show_all() def update_values(self, environmental_data_last): self.temperature.set_markup( '<span font="30">' + "{0:.1f}".format(environmental_data_last.temperature) + ' °C</span>') self.rel_humidity.set_markup( '<span font="30">' + "{0:.1f}".format(environmental_data_last.rel_humidity) + ' %</span>') def update_graph(self, environmental_data_history, time_scale): self.set_graph_axis(time_scale) time_array = [o.datetime for o in environmental_data_history] temp_array = [o.temperature for o in environmental_data_history] hum_array = [o.rel_humidity for o in environmental_data_history] self.axTemperature.plot(time_array, temp_array, 'r') self.axHumidity.plot(time_array, hum_array, 'C0') self.plot_canvas.draw() def create_left_panel(self): vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.hbox.pack_start(vbox, False, True, 10) spacer1 = Gtk.Label() vbox.pack_start(spacer1, False, True, 15) temperature = Gtk.Label() temperature.set_markup('Temperature') vbox.pack_start(temperature, False, True, 0) self.temperature.set_markup('<span font="30">00.0 °C</span>') vbox.pack_start(self.temperature, False, True, 0) spacer2 = Gtk.Label() vbox.pack_start(spacer2, False, True, 10) humidity = Gtk.Label() humidity.set_markup('Rel. Humidity') vbox.pack_start(humidity, False, True, 0) self.rel_humidity.set_markup('<span font="30">00 %</span>') vbox.pack_start(self.rel_humidity, False, True, 0) def create_graph(self): fig = Figure() self.axTemperature = fig.add_subplot(111, xlabel="Temps [s]") self.axHumidity = self.axTemperature.twinx() self.set_graph_axis(TimeScale.SECONDS) sw = Gtk.ScrolledWindow() vbox_graph = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) vbox_graph.pack_start(sw, True, True, 10) self.plot_canvas = FigureCanvas(fig) self.plot_canvas.set_size_request(400, 400) sw.add_with_viewport(self.plot_canvas) self.hbox.pack_start(vbox_graph, True, True, 5) def set_graph_axis(self, time_scale): if time_scale == TimeScale.SECONDS: xfmt = md.DateFormatter('%H:%M:%S') else: xfmt = md.DateFormatter('%m/%d %H:%M') self.axTemperature.clear() self.axTemperature.set_ylim([10, 40]) self.axTemperature.set_ylabel('Temperature [°C]', color='r') self.axTemperature.xaxis_date() labels = self.axTemperature.get_xticklabels() for l in labels: l.update({'rotation': 25}) self.axTemperature.xaxis.set_major_formatter(xfmt) self.axHumidity.clear() self.axHumidity.xaxis_date() self.axHumidity.set_ylim([35, 80]) self.axHumidity.set_ylabel('Relative humidity [%]', color='C0') self.axHumidity.xaxis.set_major_formatter(xfmt)
class GraphBase(object): """ A basic graph provider for using :py:mod:`matplotlib` to create graph representations of campaign data. This class is meant to be subclassed by real providers. """ name = 'Unknown' """The name of the graph provider.""" name_human = 'Unknown' """The human readable name of the graph provider used for UI identification.""" graph_title = 'Unknown' """The title that will be given to the graph.""" is_available = True def __init__(self, application, size_request=None, style_context=None): """ :param tuple size_request: The size to set for the canvas. """ self.application = application self.style_context = style_context self.config = application.config """A reference to the King Phisher client configuration.""" self.figure, _ = pyplot.subplots() self.figure.set_facecolor(self.get_color('bg', ColorHexCode.WHITE)) self.axes = self.figure.get_axes() self.canvas = FigureCanvas(self.figure) self.manager = None self.minimum_size = (380, 200) """An absolute minimum size for the canvas.""" if size_request is not None: self.resize(*size_request) self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed) self.canvas.show() self.navigation_toolbar = NavigationToolbar(self.canvas, self.application.get_active_window()) self.popup_menu = managers.MenuManager() self.popup_menu.append('Export', self.signal_activate_popup_menu_export) self.popup_menu.append('Refresh', self.signal_activate_popup_refresh) menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar') menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar) self._menu_item_show_toolbar = menu_item self.popup_menu.append_item(menu_item) self.navigation_toolbar.hide() self._legend = None @property def rpc(self): return self.application.rpc @staticmethod def _ax_hide_ticks(ax): for tick in ax.yaxis.get_major_ticks(): tick.tick1On = False tick.tick2On = False @staticmethod def _ax_set_spine_color(ax, spine_color): for pos in ('top', 'right', 'bottom', 'left'): ax.spines[pos].set_color(spine_color) def add_legend_patch(self, legend_rows, fontsize=None): if self._legend is not None: self._legend.remove() self._legend = None fontsize = fontsize or self.fontsize_scale legend_bbox = self.figure.legend( tuple(patches.Patch(color=patch_color) for patch_color, _ in legend_rows), tuple(label for _, label in legend_rows), borderaxespad=1.25, fontsize=fontsize, frameon=True, handlelength=1.5, handletextpad=0.75, labelspacing=0.3, loc='lower right' ) legend_bbox.legendPatch.set_linewidth(0) self._legend = legend_bbox def get_color(self, color_name, default): """ Get a color by its style name such as 'fg' for foreground. If the specified color does not exist, default will be returned. The underlying logic for this function is provided by :py:func:`~.gui_utilities.gtk_style_context_get_color`. :param str color_name: The style name of the color. :param default: The default color to return if the specified one was not found. :return: The desired color if it was found. :rtype: tuple """ color_name = 'theme_color_graph_' + color_name sc_color = gui_utilities.gtk_style_context_get_color(self.style_context, color_name, default) return (sc_color.red, sc_color.green, sc_color.blue) def make_window(self): """ Create a window from the figure manager. :return: The graph in a new, dedicated window. :rtype: :py:class:`Gtk.Window` """ if self.manager is None: self.manager = FigureManager(self.canvas, 0) self.navigation_toolbar.destroy() self.navigation_toolbar = self.manager.toolbar self._menu_item_show_toolbar.set_active(True) window = self.manager.window window.set_transient_for(self.application.get_active_window()) window.set_title(self.graph_title) return window @property def fontsize_scale(self): scale = self.markersize_scale if scale < 5: fontsize = 'xx-small' elif scale < 7: fontsize = 'x-small' elif scale < 9: fontsize = 'small' else: fontsize = 'medium' return fontsize @property def markersize_scale(self): bbox = self.axes[0].get_window_extent().transformed(self.figure.dpi_scale_trans.inverted()) return bbox.width * self.figure.dpi * 0.01 def mpl_signal_canvas_button_pressed(self, event): if event.button != 3: return self.popup_menu.menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time()) return True def signal_activate_popup_menu_export(self, action): dialog = extras.FileChooserDialog('Export Graph', self.application.get_active_window()) file_name = self.config['campaign_name'] + '.png' response = dialog.run_quick_save(file_name) dialog.destroy() if not response: return destination_file = response['target_path'] self.figure.savefig(destination_file, dpi=200, facecolor=self.figure.get_facecolor(), format='png') def signal_activate_popup_refresh(self, event): self.refresh() def signal_toggled_popup_menu_show_toolbar(self, widget): if widget.get_property('active'): self.navigation_toolbar.show() else: self.navigation_toolbar.hide() def resize(self, width=0, height=0): """ Attempt to resize the canvas. Regardless of the parameters the canvas will never be resized to be smaller than :py:attr:`.minimum_size`. :param int width: The desired width of the canvas. :param int height: The desired height of the canvas. """ min_width, min_height = self.minimum_size width = max(width, min_width) height = max(height, min_height) self.canvas.set_size_request(width, height)
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas myfirstwindow = Gtk.Window() myfirstwindow.connect("delete-event", Gtk.main_quit) myfirstwindow.set_default_size(400, 400) fig = Figure(figsize=(5, 5), dpi=100) ax = fig.add_subplot(111, projection='polar') N = 20 theta = linspace(0.0, 2 * pi, N, endpoint=False) radii = 10 * random.rand(N) width = pi / 4 * random.rand(N) bars = ax.bar(theta, radii, width=width, bottom=0.0) for r, bar in zip(radii, bars): bar.set_facecolor(cm.jet(r / 10.)) bar.set_alpha(0.5) ax.plot() sw = Gtk.ScrolledWindow() myfirstwindow.add(sw) canvas = FigureCanvas(fig) canvas.set_size_request(400, 400) sw.add_with_viewport(canvas) myfirstwindow.show_all() Gtk.main()
class StatPerspective(Gtk.Box, Ide.Perspective): """ Sets up the stats perspective and handles the signals. This class sets up the containers of the perspective and the matplotlib figure and canvas. An asynchronous method iterates over the project and gathers the data for the plot. """ def __init__(self, workdir, *args, **kwargs): super().__init__(*args, **kwargs) self.workdir = workdir # main containers scr_win = Gtk.ScrolledWindow(visible=True) pad_box = Gtk.Box(visible=True) pad_box.pack_start(scr_win, True, True, 20) main_box = Gtk.Box(visible=True, orientation=Gtk.Orientation.VERTICAL) scr_win.add_with_viewport(main_box) # content lbl_head = '<span font="36.0"><b>Project Stats</b></span>' heading = Gtk.Label(label=lbl_head, expand=True, visible=True) heading.set_use_markup(True) main_box.pack_start(heading, False, False, 0) line = Gtk.Separator(visible=True) main_box.pack_start(line, False, False, 0) self.fig = Figure(facecolor='none') self.ax = self.fig.add_subplot(111, axisbg='#ffffff') self.canvas = FigCanvas(self.fig) self.canvas.set_size_request(800, 600) self.canvas.draw() self.canvas.show() main_box.pack_start(self.canvas, True, True, 0) self.add(pad_box) self.titlebar = Ide.WorkbenchHeaderBar(visible=True) # Gather stats thread = threading.Thread(target=self.gather_stats) thread.daemon = True thread.start() def gather_stats(self): file_types = {} for root, subfolders, files in os.walk(self.workdir): for file in files: try: with open(root + "/" + file) as fl: line_count = 0 for line in fl: line_count += 1 splt_str = file.split(".") if len(splt_str) > 1: file_ext = splt_str[-1] else: continue if file_ext in file_types: # key exists, add line count file_types[file_ext] = file_types[file_ext] + line_count else: # key doesn't exist, create new key file_types[file_ext] = line_count except: continue keys = [] values = [] for key, value in file_types.items(): keys.append(key) values.append(value) key_ar = np.array(keys) val_ar = np.array(values).astype(int) ar = np.vstack((key_ar, val_ar)).T ar = ar[ar[:,1].astype(int).argsort()] rows = ar.shape[0] val_pos = np.arange(1, ar.shape[0]+1) self.ax.barh(val_pos, ar[:,1].astype(int), 0.8, align="center") # facecolor='yellow' self.ax.set_yticks(val_pos) self.ax.tick_params(axis="both", which="major", pad=15) self.ax.set_yticklabels(ar[:,0], fontsize="16", weight="bold") self.ax.tick_params(axis="x", which="major", labelsize="16") self.canvas.set_size_request(800, (rows * 20 + 50)) self.canvas.draw() def do_get_id(self): return 'hello-world2' def do_get_title(self): return 'Hello' def do_get_priority(self): return 10000 def do_get_icon_name(self): return "utilities-system-monitor-symbolic" def do_get_titlebar(self): return self.titlebar
class App: def __init__(self): self.xsize, self.ysize = 600, 600 self.xmin, self.xmax = -1.5, 1.5 self.ymin, self.ymax = -1.5, 1.5 self.x, self.y = (-0.4, 0.6) self.n = 2 self.zmax = 4.0 self.niter = 256 self.dpi = 100 self.cmap = 'Set3' self.digits = 12 self.entries = {} # create app interface self.setup_interface() self.display_image() def setup_interface(self): # create main window self.main_window = Gtk.Window(title="Julia Fractals") self.main_window.set_border_width(10) self.main_window.connect("delete-event", Gtk.main_quit) # setup header bar self.setup_header_bar() box = Gtk.Box(orientation='horizontal', spacing=10) self.main_window.add(box) sep = Gtk.Separator(orientation='vertical') box.add(sep) # setup left panel -- container with image parameters self.left_box = Gtk.Box(orientation='vertical', spacing=10) self.setup_left_box() box.add(self.left_box) sep = Gtk.Separator(orientation='vertical') box.add(sep) # setup right panel -- container with image parameters self.right_box = Gtk.Box(orientation='vertical', spacing=10) self.setup_right_box() box.add(self.right_box) for name, entry in self.entries.items(): # copy current values to the defaults setattr(self, name + "_default", getattr(self, name)) self.set_entry_value(entry) sep = Gtk.Separator(orientation='vertical') box.add(sep) # setup image panel -- container with image output self.image_box = Gtk.Box(orientation='vertical') self.setup_image_box() box.add(self.image_box) def setup_header_bar(self): ''' ''' self.hb = Gtk.HeaderBar() self.hb.set_show_close_button(True) self.hb.props.title = "Julia Fractal" self.main_window.set_titlebar(self.hb) self.button_save = Gtk.Button(label='Save') self.button_save.connect("clicked", self.on_button_save_clicked) self.hb.pack_end(self.button_save) def setup_left_box(self): # box for box = Gtk.Box(orientation='vertical', spacing=6) self.left_box.pack_start(box, False, False, 0) sep = Gtk.Separator(orientation='horizontal') box.add(sep) self.namecombo = Gtk.ComboBoxText() self.namecombo.connect("changed", self.on_namecombo_changed) for item in ['Julia', 'Mandelbrot']: self.namecombo.append_text(item) self.namecombo.set_active(0) box.pack_start(self.namecombo, True, True, 0) label = Gtk.Label("z = z**n + C", halign=Gtk.Align.START) box.pack_start(label, True, True, 0) label = Gtk.Label("C = x + yi", halign=Gtk.Align.START) box.pack_start(label, True, True, 0) names = ['n', 'x', 'y', 'zmax', 'niter'] entries = {name: self.create_labeled_entry(name, box, orientation='vertical', spacing=5, xpad=8) for name in names} self.entries.update(entries) sep = Gtk.Separator(orientation='horizontal') box.add(sep) # apply rotation button_apply = Gtk.Button(label='Apply') button_apply.connect("clicked", self.on_button_apply_clicked) self.left_box.pack_start(button_apply, False, False, 0) # reset rotation button_reset = Gtk.Button(label='Reset') button_reset.connect("clicked", self.on_button_reset_clicked) self.left_box.pack_start(button_reset, False, False, 0) def setup_right_box(self): # box for box = Gtk.Box(orientation='vertical', spacing=10) self.right_box.pack_start(box, False, False, 0) sep = Gtk.Separator(orientation='horizontal') box.add(sep) names = ['xmin', 'xmax', 'ymin', 'ymax', 'xsize', 'ysize'] entries = {name: self.create_labeled_entry(name, box, orientation='horizontal') for name in names} self.entries.update(entries) sep = Gtk.Separator(orientation='horizontal') box.add(sep) label = Gtk.Label("Colormap", halign=Gtk.Align.START) box.pack_start(label, True, True, 0) cmapstore = Gtk.ListStore(str, GdkPixbuf.Pixbuf) cmaps = sorted(pl.cm.datad) for item in cmaps: cmapstore.append([item, None]) self.cmapcombo = Gtk.ComboBox.new_with_model(cmapstore) self.cmapcombo.connect("changed", self.on_cmapcombo_changed) self.cmapcombo.set_active(0) renderer = Gtk.CellRendererText() self.cmapcombo.pack_start(renderer, True) self.cmapcombo.add_attribute(renderer, "text", 0) renderer = Gtk.CellRendererPixbuf() self.cmapcombo.pack_start(renderer, False) self.cmapcombo.add_attribute(renderer, "pixbuf", 1) box.pack_start(self.cmapcombo, True, True, 0) def setup_image_box(self): xx = self.xsize / float(self.dpi) # inches yy = self.ysize / float(self.dpi) # inches # TODO: make it resizable self.fig = Figure(figsize=(xx, yy), dpi=self.dpi) self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea # setup drawing canvas self.canvas.set_size_request(self.xsize, self.ysize) self.canvas.connect('button-press-event' , self.on_canvas_button_press) self.canvas.connect('button-release-event', self.on_canvas_button_release) self.canvas.connect('motion-notify-event' , self.on_canvas_motion_notify) self.image_box.add(self.canvas) def create_labeled_entry(self, name, parent, orientation='horizontal', spacing=10, xpad=0): box = Gtk.Box(orientation=orientation, spacing=spacing) parent.pack_start(box, True, True, 0) label = Gtk.Label(label=name, halign=Gtk.Align.START, xpad=xpad) box.pack_start(label, True, False, 0) entry = Gtk.Entry(name=name) box.pack_start(entry, True, True, 0) return entry def set_entry_value(self, entry): name = entry.get_name() value = getattr(self, name) if int(value) == value: value_str = "{0}".format(value) else: value_str = "{0:.{1}f}".format(value, self.digits).rstrip("0") entry.set_text(value_str) def get_entry_value(self, entry, dtype): text = entry.get_text() try: val = float(text) if dtype == int: val = int(val) except ValueError: val = None return val def on_button_save_clicked(self, widget): pass def on_cmapcombo_changed(self, widget): tree_iter = widget.get_active_iter() if tree_iter != None: model = widget.get_model() name, image = model[tree_iter] self.cmap = name if hasattr(self, 'fig'): self.display_image() self.canvas.draw_idle() def on_namecombo_changed(self, widget): text = widget.get_active_text() print(text) if text == 'Mandelbrot': self.x = 0 self.y = 0 self.set_entry_value(self.entries['x']) self.set_entry_value(self.entries['y']) if hasattr(self, 'fig'): self.update_image() def on_button_apply_clicked(self, widget): self.update_image() def on_button_reset_clicked(self, widget): for name, entry in self.entries.items(): setattr(self, name, getattr(self, name + "_default")) self.set_entry_value(entry) def on_canvas_button_release(self, widget, event): mapping = {1: 0.75, 3: 1.5} if event.button in mapping: if (self.posx1, self.posy1) == (self.posx2, self.posy2): factor = mapping[event.button] xc = np.interp(event.x, [0, self.xsize-1], [self.xmin, self.xmax]) yc = np.interp(event.y, [0, self.ysize-1], [self.ymin, self.ymax]) xlen = factor * (self.xmax - self.xmin) ylen = factor * (self.ymax - self.ymin) self.xmin = xc - xlen/2.0 self.xmax = xc + xlen/2.0 self.ymin = yc - ylen/2.0 self.ymax = yc + ylen/2.0 else: self.xmin = self.posx1 self.xmax = self.posx2 self.ymin = self.posy1 self.ymax = self.posy2 for entry in self.entries.values(): self.set_entry_value(entry) self.update_image() def on_canvas_motion_notify(self, widget, event): self.posx2 = np.interp(event.x, [0, self.xsize-1], [self.xmin, self.xmax]) self.posy2 = np.interp(event.y, [0, self.ysize-1], [self.ymin, self.ymax]) if event.state & Gdk.EventMask.BUTTON_PRESS_MASK: if event.state & Gdk.ModifierType.CONTROL_MASK: self.posy2 = self.posy1 + self.posx2 - self.posx1 if hasattr(self, 'rectangle1'): if self.rectangle1 in self.fig.gca().patches: self.rectangle1.remove() self.rectangle2.remove() self.rectangle1 = Rectangle((self.posx2, (self.ymax + self.ymin) - self.posy2), (self.posx1 - self.posx2), -(self.posy1 - self.posy2), fill=False, edgecolor='white', linewidth=0.5) self.rectangle2 = Rectangle((self.posx2, (self.ymax + self.ymin) - self.posy2), (self.posx1 - self.posx2), -(self.posy1 - self.posy2), fill=False, edgecolor='black', linestyle='dotted', linewidth=0.5) ax = self.fig.gca() ax.add_patch(self.rectangle1) ax.add_patch(self.rectangle2) self.canvas.draw_idle() def on_canvas_button_press(self, widget, event): self.posx1 = np.interp(event.x, [0, self.xsize-1], [self.xmin, self.xmax]) self.posy1 = np.interp(event.y, [0, self.ysize-1], [self.ymin, self.ymax]) self.posx2 = self.posx1 self.posy2 = self.posy1 #self.posx = self.transform_x(event.x) #self.posy = self.transform_y(event.y) def run(self): self.main_window.show_all() Gtk.main() def transform_x(self, xval): return two_point_interp(xval, 0, self.xsize-1, self.xmin, self.xmin) def transform_y(self, yval): return two_point_interp(yval, 0, self.ysize-1, self.ymin, self.ymin) def compute_image(self): C = complex(self.x, self.y) xlim = (self.xmin, self.xmax) ylim = (self.ymin, self.ymax) zz = complex_grid(xlim, ylim, self.xsize, self.ysize) text = self.namecombo.get_active_text() if text == 'Julia': return fractal(zz, C, self.n, self.zmax, self.niter) elif text == 'Mandelbrot': return fractal(C, zz, self.n, self.zmax, self.niter) def display_image(self): # plot and save the image img = self.compute_image() # clear previous figure self.fig.clf() # setup plot ax = Axes(self.fig, [0, 0, 1, 1]) # remove outer border ax.set_axis_off() # disable axis ax.set_xlim((self.xmin, self.xmax)) ax.set_ylim((self.ymin, self.ymax)) ax.set_xticklabels([]) ax.set_yticklabels([]) ax.imshow(img, cmap=pl.get_cmap(self.cmap), interpolation='nearest', extent=[self.xmin, self.xmax, self.ymin, self.ymax], origin='upper', aspect=1.0) self.fig.add_axes(ax) def update_image(self): for name, entry in self.entries.items(): dtype = int if name in ['n', 'niter', 'xsize', 'ysize'] else float val = self.get_entry_value(entry, dtype) if val is not None: setattr(self, name, val) for entry in self.entries.values(): self.set_entry_value(entry) self.display_image() self.canvas.draw_idle()
def __init__(self, notebook): self._notebook = notebook self.data = None self.params = None ########## # Time Domain ########## self.time_domain = Figure() self.time_domain_ax = self.time_domain.add_subplot('111') #self.time_domain.tight_layout() grid = Gtk.Grid() grid.set_hexpand(True) grid.set_vexpand(True) label = Gtk.Label() label.set_markup("<b>Time Domain</b>") canvas = FigureCanvas(self.time_domain) canvas.set_size_request(200, 200) canvas.set_hexpand(True) canvas.set_vexpand(True) toolbar = NavigationToolbar(canvas, notebook.get_toplevel()) grid.attach(canvas, 0, 0, 1, 1) grid.attach(toolbar, 0, 1, 1, 1) notebook.append_page(grid, label) ########## # FFT ########## self.fft = Figure() self.fft_ax = self.fft.add_subplot('111') grid = Gtk.Grid() grid.set_hexpand(True) grid.set_vexpand(True) label = Gtk.Label() label.set_markup("<b>FFT</b>") canvas = FigureCanvas(self.fft) canvas.set_size_request(200, 200) canvas.set_hexpand(True) canvas.set_vexpand(True) toolbar = NavigationToolbar(canvas, notebook.get_toplevel()) grid.attach(canvas, 0, 0, 1, 1) grid.attach(toolbar, 0, 1, 1, 1) notebook.append_page(grid, label) ########## # Phase Error ########## self.phase_error = Figure() self.phase_error_ax = self.phase_error.add_subplot('111') grid = Gtk.Grid() grid.set_hexpand(True) grid.set_vexpand(True) label = Gtk.Label() label.set_markup("<b>Phase Error</b>") canvas = FigureCanvas(self.phase_error) canvas.set_size_request(200, 200) canvas.set_hexpand(True) canvas.set_vexpand(True) toolbar = NavigationToolbar(canvas, notebook.get_toplevel()) grid.attach(canvas, 0, 0, 1, 1) grid.attach(toolbar, 0, 1, 1, 1) notebook.append_page(grid, label) notebook.show_all()
def __init__(self, device): super(Plot, self).__init__() self.device = device self.set_hexpand(True) self.set_vexpand(True) fig = Figure() fig.subplots_adjust(top=1, bottom=0.09, right=1, left=0.065, hspace=0.2, wspace=0.2) self.ax = fig.add_subplot(111, fc='black') self._def_axis(self.ax) canvas = FigureCanvas(fig) canvas.set_size_request(600, 600) self.add(canvas) parent_conn, self.child_conn = Pipe( duplex=False) # Pipe to pump the label data through def update_self(source, condition): """ watches pipe and when data changes, changes the label """ print('source = ', source, 'condition = ', condition) assert parent_conn.poll() data = parent_conn.recv() samples = data['values'] ys = [] tmp = 0 sample_time = 1 / device.get_sampling_speed() val = 0 vals = ['S', 'mS', 'uS', 'nS', 'pS'] for val in range(0, len(vals)): if sample_time > 10: break sample_time = sample_time * 1000 print('scaled and vals set to ', vals[val]) tmp = 0 for y in range(len(samples)): ys.append(tmp) tmp = tmp + 1 / sample_time self._def_axis(self.ax) self.ax.set_xlabel('Time [%s]' % vals[val]) self.ax.plot(ys, samples, **self.graph_properties) if data['trig_low'] is not None: self.ax.axhline(y=data['trig_low'], color='b', linestyle=':') if data['trig_up'] is not None: self.ax.axhline(y=data['trig_up'], color='b', linestyle=':') if data['trig_place'] is not None: self.ax.axvline(x=data['trig_place'] * sample_time, color='r', linestyle=':') self.queue_draw() return True GObject.io_add_watch(parent_conn.fileno(), GObject.IO_IN, update_self)
class Plot: # TODO scaling of size when resizing # TODO tighter fit of plot # TODO BUG: weird redrawing issue on changing panes, probably should not redraw graph on changing panes # Plot object used GUI def __init__(self, builder, GPUs, maxpoints, precision, linux_kernelmain, linux_kernelsub): # Can used for kernel specific workarounds self.linux_kernelmain = linux_kernelmain self.linux_kernelsub = linux_kernelsub self.precision = precision self.builder = builder self.GPUs = GPUs self.GPU = GPUs[0] self.maxpoints = maxpoints self.fig = Figure(figsize=(1000, 150), dpi=100, facecolor="#00000000") self.fig.set_tight_layout(True) self.ax = self.fig.add_subplot(111) # enable, name, unit, mean, max, current self.signalstore = Gtk.ListStore(bool, bool, bool, str, str, str, str, str, str, str) self.Plotsignals = self.init_signals(self.GPU) # Set top panel height in accordance to number of signals (with saturation) height_top_panel = len(self.Plotsignals) * 32.5 if height_top_panel < 150: self.builder.get_object("MainPane").set_position(150) elif height_top_panel > 235: self.builder.get_object("MainPane").set_position(235) else: self.builder.get_object("MainPane").set_position(height_top_panel) self.init_treeview() self.update_signals() self.canvas = FigureCanvas(self.fig) self.canvas.set_size_request(1000, 150) self.object = self.builder.get_object("matplot") self.object.add(self.canvas) self.object.show_all() def change_GPU(self, cardnr): print(f"Changing plot to GPU {self.GPUs[cardnr].fancyname}") self.GPU = self.GPUs[cardnr] self.Plotsignals = self.init_signals(self.GPU) self.init_treeview() self.update_signals() def init_signals(self, GPU): Plotsignals = [] # Define signals with: names units max min path plotenable plotnormalise plotcolor parser and outputargument used from parser if GPU.gpu_clock != 'N/A': Plotsignals.append( Plotsignal("GPU Clock", "[MHz]", GPU.pstate_clock[-1], GPU.pstate_clock[0], "/pp_dpm_sclk", True, True, "#1f77b4", GPU.get_current_clock, 0)) Plotsignals.append( Plotsignal("GPU State", "[-]", len(GPU.pstate_clock) - 1, 0, "/pp_dpm_sclk", True, True, "#ff7f0e", GPU.get_current_clock, 1)) if GPU.mem_clock != 'N/A': Plotsignals.append( Plotsignal("MEM Clock", "[MHz]", GPU.pmem_clock[-1], GPU.pmem_clock[0], "/pp_dpm_mclk", True, True, "#d62728", GPU.get_current_clock, 0)) Plotsignals.append( Plotsignal("MEM State", "[-]", len(GPU.pmem_clock) - 1, 0, "/pp_dpm_mclk", True, True, "#9467bd", GPU.get_current_clock, 1)) self.add_available_signal(GPU.sensors, Plotsignals, hwmonpath=GPU.hwmonpath) # GPU busy percent only properly available in linux version 4.19+ if (self.linux_kernelmain == 4 and self.linux_kernelsub > 18) or (self.linux_kernelmain >= 5): Plotsignals.append( Plotsignal("GPU Usage", "[-]", 100, 0, "/gpu_busy_percent", True, True, "#2ca02c", GPU.read_sensor)) # as final check remove signals that return None: checked_plotlist = [] for i, signal in enumerate(Plotsignals): signal.retrieve_data(self.maxpoints) if signal.get_last_value() is not None: checked_plotlist.append(signal) else: print( f"Removing {signal.name} from plotsignals, returning Nonetype" ) if len(checked_plotlist) == 0: print("Nothing to plot! Hiding the plot pane.") self.builder.get_object("Plot").hide() return checked_plotlist def add_available_signal(self, signals, Plotsignals, hwmonpath="", subsystem="", stop_recursion=False): for key, value in signals.items(): if key in subsystem_unit_color: subsystem = key stop_recursion = False if "path" in value: if subsystem == "": continue if any(path_sensor_to_plot in value["path"] for path_sensor_to_plot in sensors_to_plot): signallabel = value["path"][1:].split("_")[0] signalmax = 0 signalmin = 0 signalpath = hwmonpath + value["path"] if "min" in signals: signalmin = signals['min']['value'] stop_recursion = True if "max" in signals: signalmax = signals['max']['value'] stop_recursion = True if "crit" in signals: signalmax = signals['crit']['value'] stop_recursion = True if "label" in signals: signallabel = signals["label"]["value"] if signallabel == "vddgfx" and len( self.GPU.volt_range) > 0: signalmax = self.GPU.volt_range[1] signalmin = 0 stop_recursion = True if "cap" in signals: signalmax = signals["cap"]["value"] stop_recursion = True if "pwm" in value["path"]: signalmax = 255 signallabel = "(fan)" + signallabel Plotsignals.append( Plotsignal(signallabel, subsystem_unit_color[subsystem]["unit"], signalmax, signalmin, signalpath, True, True, subsystem_unit_color[subsystem]["color"], read)) else: if not stop_recursion: self.add_available_signal(value, Plotsignals, hwmonpath=hwmonpath, subsystem=subsystem, stop_recursion=stop_recursion) else: continue def init_treeview(self): textrenderer = Gtk.CellRendererText() self.plotrenderer = Gtk.CellRendererToggle() self.plotrenderer.connect("toggled", self.on_plot_toggled) self.normaliserenderer = Gtk.CellRendererToggle() self.normaliserenderer.connect("toggled", self.on_normalise_toggled) self.tree = self.builder.get_object("Signal Selection") self.tree.append_column( Gtk.TreeViewColumn("Plot", self.plotrenderer, active=0)) self.tree.append_column( Gtk.TreeViewColumn("Scale", self.normaliserenderer, active=1, activatable=2)) columnnames = ["Name", "Unit", "min", "mean", "max", "current"] for i, column in enumerate(columnnames): tcolumn = Gtk.TreeViewColumn(column, textrenderer, text=i + 3, foreground=9) self.tree.append_column(tcolumn) for plotsignal in self.Plotsignals: self.signalstore.append([ plotsignal.plotenable, plotsignal.plotnormalise, True, plotsignal.name, convert_to_si(plotsignal.unit)[0], '0', '0', '0', '0', plotsignal.plotcolor ]) self.tree.set_model(self.signalstore) def update_signals(self): # Retrieve signal and set appropriate values in signalstore to update left pane in GUI for i, Plotsignal in enumerate(self.Plotsignals): Plotsignal.retrieve_data(self.maxpoints) disable_scaling = len( Plotsignal.get_values()) > 3 and Plotsignal.all_equal( ) and Plotsignal.plotnormalise and (Plotsignal.max == Plotsignal.min) self.signalstore[i][2] = not disable_scaling if disable_scaling: print( f"cannot scale values of {self.signalstore[i][3]} disabling scaling" ) self.on_normalise_toggled(self.normaliserenderer, i, disable_refresh=True) if disable_plots_if_scaling_error: print( f"disabling {self.signalstore[i][3]} plot since disable_plots_if_scaling_error is set" ) self.on_plot_toggled(self.plotrenderer, i) self.signalstore[i][5] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_min())[1], self.precision)) self.signalstore[i][6] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_mean())[1], self.precision)) self.signalstore[i][7] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_max())[1], self.precision)) self.signalstore[i][8] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_last_value())[1], self.precision)) def on_plot_toggled(self, widget, path, disable_refresh=False): self.signalstore[path][0] = not self.signalstore[path][0] self.Plotsignals[int( path)].plotenable = not self.Plotsignals[int(path)].plotenable if not disable_refresh: self.update_plot() def on_normalise_toggled(self, widget, path, disable_refresh=False): self.signalstore[path][1] = not self.signalstore[path][1] self.Plotsignals[int(path)].plotnormalise = not self.Plotsignals[int( path)].plotnormalise if not disable_refresh: self.update_plot() def update_plot(self): if len(self.Plotsignals) == 0: return self.ax.clear() for Plotsignal in self.Plotsignals: if Plotsignal.plotenable: if Plotsignal.plotnormalise: data = Plotsignal.get_normalised_values() * 100 self.ax.plot(data, color=Plotsignal.plotcolor) else: data = Plotsignal.get_values() self.ax.plot(convert_to_si(Plotsignal.unit, data)[1], color=Plotsignal.plotcolor) self.ax.grid(True) self.ax.get_yaxis().tick_right() self.ax.get_yaxis().set_label_position("right") self.ax.get_yaxis().set_visible(True) self.ax.get_xaxis().set_visible(False) all_normalised = True all_same_unit = True unit = "" iter = self.signalstore.get_iter(0) while iter is not None: if self.signalstore[iter][0] == True: if unit == "": unit = self.signalstore[iter][4] if self.signalstore[iter][1] == False: all_normalised = False if self.signalstore[iter][4] != unit: all_same_unit = False if not all_normalised and not all_same_unit: break iter = self.signalstore.iter_next(iter) if all_normalised: self.ax.set_yticks(np.arange(0, 101, step=25)) self.ax.set_ylabel('Percent [%]') else: self.ax.yaxis.set_major_locator(AutoLocator()) if all_same_unit: self.ax.set_ylabel(unit) else: self.ax.set_ylabel("") self.canvas.draw() self.canvas.flush_events() def refresh(self): # This is run in thread self.update_signals() self.update_plot()
class CampaignGraph(object): """ A basic graph provider for using :py:mod:`matplotlib` to create graph representations of campaign data. This class is meant to be subclassed by real providers. """ name = 'Unknown' """The name of the graph provider.""" name_human = 'Unknown' """The human readable name of the graph provider used for UI identification.""" graph_title = 'Unknown' """The title that will be given to the graph.""" table_subscriptions = [] """A list of tables from which information is needed to produce the graph.""" is_available = True def __init__(self, config, parent, size_request=None): """ :param dict config: The King Phisher client configuration. :param parent: The parent window for this object. :type parent: :py:class:`Gtk.Window` :param tuple size_request: The size to set for the canvas. """ self.config = config """A reference to the King Phisher client configuration.""" self.parent = parent """The parent :py:class:`Gtk.Window` instance.""" self.figure, _ = pyplot.subplots() self.axes = self.figure.get_axes() self.canvas = FigureCanvas(self.figure) self.manager = None if size_request: self.canvas.set_size_request(*size_request) self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed) self.canvas.show() self.navigation_toolbar = NavigationToolbar(self.canvas, self.parent) self.popup_menu = Gtk.Menu.new() menu_item = Gtk.MenuItem.new_with_label('Export') menu_item.connect('activate', self.signal_activate_popup_menu_export) self.popup_menu.append(menu_item) menu_item = Gtk.MenuItem.new_with_label('Refresh') menu_item.connect('activate', lambda action: self.refresh()) self.popup_menu.append(menu_item) menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar') menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar) self._menu_item_show_toolbar = menu_item self.popup_menu.append(menu_item) self.popup_menu.show_all() self.navigation_toolbar.hide() def _load_graph(self, info_cache): raise NotImplementedError() def _graph_bar_set_yparams(self, top_lim): min_value = top_lim + (top_lim * 0.075) if min_value <= 25: scale = 5 else: scale = scale = 10 ** (len(str(int(min_value))) - 1) inc_scale = scale while scale <= min_value: scale += inc_scale top_lim = scale ax = self.axes[0] yticks = set((round(top_lim * 0.5), top_lim)) ax.set_yticks(tuple(yticks)) ax.set_ylim(top=top_lim) return def _graph_null_pie(self, title): ax = self.axes[0] ax.pie((100,), labels=(title,), colors=(MPL_COLOR_NULL,), autopct='%1.0f%%', shadow=True, startangle=90) ax.axis('equal') return def add_legend_patch(self, legend_rows, fontsize=None): handles = [] if not fontsize: scale = self.markersize_scale if scale < 5: fontsize = 'xx-small' elif scale < 7: fontsize = 'x-small' elif scale < 9: fontsize = 'small' else: fontsize = 'medium' for row in legend_rows: handles.append(patches.Patch(color=row[0], label=row[1])) self.axes[0].legend(handles=handles, fontsize=fontsize, loc='lower right') def graph_bar(self, bars, color=None, xticklabels=None, ylabel=None): """ Create a standard bar graph with better defaults for the standard use cases. :param list bars: The values of the bars to graph. :param color: The color of the bars on the graph. :type color: list, str :param list xticklabels: The labels to use on the x-axis. :param str ylabel: The label to give to the y-axis. :return: The bars created using :py:mod:`matplotlib` :rtype: `matplotlib.container.BarContainer` """ color = color or MPL_COLOR_NULL width = 0.25 ax = self.axes[0] self._graph_bar_set_yparams(max(bars) if bars else 0) bars = ax.bar(range(len(bars)), bars, width, color=color) ax.set_xticks([float(x) + (width / 2) for x in range(len(bars))]) if xticklabels: ax.set_xticklabels(xticklabels, rotation=30) for col in bars: height = col.get_height() ax.text(col.get_x() + col.get_width() / 2.0, height, "{0:,}".format(height), ha='center', va='bottom') if ylabel: ax.set_ylabel(ylabel) self.figure.subplots_adjust(bottom=0.25) return bars def make_window(self): """ Create a window from the figure manager. :return: The graph in a new, dedicated window. :rtype: :py:class:`Gtk.Window` """ if self.manager == None: self.manager = FigureManager(self.canvas, 0) self.navigation_toolbar.destroy() self.navigation_toolbar = self.manager.toolbar self._menu_item_show_toolbar.set_active(True) window = self.manager.window window.set_transient_for(self.parent) window.set_title(self.graph_title) return window @property def markersize_scale(self): bbox = self.axes[0].get_window_extent().transformed(self.figure.dpi_scale_trans.inverted()) return max(bbox.width, bbox.width) * self.figure.dpi * 0.01 def mpl_signal_canvas_button_pressed(self, event): if event.button != 3: return self.popup_menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time()) return True def signal_activate_popup_menu_export(self, action): dialog = gui_utilities.UtilityFileChooser('Export Graph', self.parent) file_name = self.config['campaign_name'] + '.png' response = dialog.run_quick_save(file_name) dialog.destroy() if not response: return destination_file = response['target_path'] self.figure.savefig(destination_file, format='png') def signal_toggled_popup_menu_show_toolbar(self, widget): if widget.get_property('active'): self.navigation_toolbar.show() else: self.navigation_toolbar.hide() def load_graph(self): """Load the graph information via :py:meth:`.refresh`.""" self.refresh() def refresh(self, info_cache=None, stop_event=None): """ Refresh the graph data by retrieving the information from the remote server. :param dict info_cache: An optional cache of data tables. :param stop_event: An optional object indicating that the operation should stop. :type stop_event: :py:class:`threading.Event` :return: A dictionary of cached tables from the server. :rtype: dict """ info_cache = (info_cache or {}) if not self.parent.rpc: return info_cache for table in self.table_subscriptions: if stop_event and stop_event.is_set(): return info_cache if not table in info_cache: info_cache[table] = tuple(self.parent.rpc.remote_table('campaign/' + table, self.config['campaign_id'])) for ax in self.axes: ax.clear() self._load_graph(info_cache) self.axes[0].set_title(self.graph_title, y=1.03) self.canvas.draw() return info_cache
class MyWindow(Gtk.Window): def __init__(self): #Janela Gtk.Window.__init__(self, title="Testando") self.set_resizable(False) self.set_size_request(600, 600) self.set_position(Gtk.WindowPosition.CENTER) self.set_border_width(10) principal = Gtk.Box(spacing=10) principal.set_homogeneous(False) vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox_left.set_homogeneous(False) vbox_right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox_right.set_homogeneous(False) ### Boxes que ficarão dentro da vbox_left ### hbox_MDIST = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_MDIST.set_homogeneous(False) hbox_labels = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_labels.set_homogeneous(False) hbox_RDIST = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_RDIST.set_homogeneous(True) hbox_TOTEX = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_TOTEX.set_homogeneous(True) hbox_MVELO = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_MVELO.set_homogeneous(True) #criando os elementos das boxes Mdist, Labels, Rdist, TOTEX, Mvelo ##MDIST## label_Mdist = Gtk.Label('MDIST') self.entry_Mdist = Gtk.Entry() self.entry_Mdist.set_editable(False) self.entry_Mdist.set_max_length(max=8) ##LABELS## label_vazia = Gtk.Label(' ') label_AP = Gtk.Label('AP') label_ML = Gtk.Label('ML') label_TOTAL = Gtk.Label('TOTAL') ##RDIST## label_Rdist = Gtk.Label('RDIST') self.entry_Rdist_AP = Gtk.Entry() self.entry_Rdist_AP.set_editable(False) self.entry_Rdist_AP.set_max_length(max=8) self.entry_Rdist_ML = Gtk.Entry() self.entry_Rdist_ML.set_editable(False) self.entry_Rdist_ML.set_max_length(max=8) self.entry_Rdist_TOTAL = Gtk.Entry() self.entry_Rdist_TOTAL.set_editable(False) self.entry_Rdist_TOTAL.set_max_length(max=8) ##TOTEX## label_TOTEX = Gtk.Label('TOTEX') self.entry_TOTEX_AP = Gtk.Entry() self.entry_TOTEX_AP.set_editable(False) self.entry_TOTEX_AP.set_max_length(max=8) self.entry_TOTEX_ML = Gtk.Entry() self.entry_TOTEX_ML.set_editable(False) self.entry_TOTEX_ML.set_max_length(max=8) self.entry_TOTEX_TOTAL = Gtk.Entry() self.entry_TOTEX_TOTAL.set_editable(False) self.entry_TOTEX_TOTAL.set_max_length(max=8) ##MVELO## label_MVELO = Gtk.Label('MVELO') self.entry_MVELO_AP = Gtk.Entry() self.entry_MVELO_AP.set_editable(False) self.entry_MVELO_AP.set_max_length(max=8) self.entry_MVELO_ML = Gtk.Entry() self.entry_MVELO_ML.set_editable(False) self.entry_MVELO_ML.set_max_length(max=8) self.entry_MVELO_TOTAL = Gtk.Entry() self.entry_MVELO_TOTAL.set_editable(False) self.entry_MVELO_TOTAL.set_max_length(max=8) #colocando cada elemento dentro da sua box hbox_MDIST.pack_start(label_Mdist,True,True,0) hbox_MDIST.pack_start(self.entry_Mdist,True,True,0) hbox_labels.pack_start(label_vazia,True,True,0) hbox_labels.pack_start(label_AP,True,True,0) hbox_labels.pack_start(label_ML,True,True,0) hbox_labels.pack_start(label_TOTAL,True,True,0) hbox_RDIST.pack_start(label_Rdist,True,True,0) hbox_RDIST.pack_start(self.entry_Rdist_AP,True,True,0) hbox_RDIST.pack_start(self.entry_Rdist_ML,True,True,0) hbox_RDIST.pack_start(self.entry_Rdist_TOTAL,True,True,0) hbox_TOTEX.pack_start(label_TOTEX, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_AP, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_ML, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_TOTAL, True, True, 0) hbox_MVELO.pack_start(label_MVELO, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_AP, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_ML, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_TOTAL, True, True, 0) #colocando as boxes pequenas dentro das box vbox_left vbox_left.pack_start(hbox_MDIST, True, True, 0) vbox_left.pack_start(hbox_labels, True, True, 0) vbox_left.pack_start(hbox_RDIST, True, True, 0) vbox_left.pack_start(hbox_TOTEX, True, True, 0) vbox_left.pack_start(hbox_MVELO, True, True, 0) #elementos da vbox_right) #Notebook self.notebook = Gtk.Notebook() self.fig = plt.figure() self.axis = self.fig.add_subplot(111) self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.canvas = FigureCanvas(self.fig) self.canvas.set_size_request(500, 500) self.page1 = Gtk.Box() self.page1.set_border_width(10) self.page1.add(self.canvas) self.notebook.append_page(self.page1, Gtk.Label('Gráfico do CoP')) ##aqui fica a segunda janela do notebook self.fig2 = plt.figure() self.axis2 = self.fig2.add_subplot(111) self.axis2.set_ylabel('ML') self.axis2.set_xlabel('AP') self.canvas2 = FigureCanvas(self.fig2) self.canvas2.set_size_request(500, 500) self.page2 = Gtk.Box() self.page2.set_border_width(10) self.page2.add(self.canvas2) self.notebook.append_page(self.page2, Gtk.Label('Gráfico na frequência')) #criando os botoes hbox_botoes = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_botoes.set_homogeneous(True) self.button1 = Gtk.Button(label="Capturar") self.button1.connect("clicked", self.on_button1_clicked) self.button2 = Gtk.Button(label="Processar") self.button2.connect("clicked", self.on_button2_clicked) #self.set_resizable(True #colocando os botoes nas boxes hbox_botoes.pack_start(self.button1, True, True,0) hbox_botoes.pack_start(self.button2, True, True, 0) vbox_right.pack_start(self.notebook, True, True, 0) vbox_right.pack_start(hbox_botoes, True, True, 0) # colocando as boxes verticais dentro da box principal principal.pack_start(vbox_left, True, True, 0) principal.pack_start(vbox_right, True, True, 0) #Adicionano os elementos na box exterior self.add(principal) def on_button1_clicked(self, widget): global APs, MLs pos_AP = [] pos_ML = [] AP_aux = [] ML_aux = [] ref_arquivo_x_diferente = open("/home/thales/wiibalance/cwiid/python/xdiferente.txt", "r") ref_arquivo_y_diferente = open("/home/thales/wiibalance/cwiid/python/ydiferente.txt", "r") for linhax in ref_arquivo_x_diferente: AP_aux.append(ref_arquivo_x_diferente.readline(13)) for linhay in ref_arquivo_y_diferente: ML_aux.append(ref_arquivo_y_diferente.readline(13)) ref_arquivo_x_diferente.close() ref_arquivo_y_diferente.close() for i in range(len(AP_aux)): e = AP_aux[i] try: APs.append(float(e)) except: #print('posicao de x que nao conseguiu pegar o valor real:', i) pos_AP.append(i) for j in range(len(ML_aux)): e = ML_aux[j] try: MLs.append(float(e)) except: #print('posicao de y que nao conseguiu pegar o valor real:', j) pos_ML.append(j) #APs, MLs = calc.geraNumeroAleatorio(-3, 7, -4, 6, 40) if calc.diferentes(APs,MLs): if len(APs) > len(MLs): APs = calc.delEleAP(APs, pos_ML) else: MLs =calc.delEleML(MLs, pos_AP) max_absoluto_AP = calc.valorAbsoluto(min(APs), max(APs)) max_absoluto_ML = calc.valorAbsoluto(min(MLs), max(MLs)) print('max_absoluto_AP:',max_absoluto_AP,'max_absoluto_ML:',max_absoluto_ML) self.axis.clear() self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.axis.set_xlim(-max_absoluto_AP, max_absoluto_AP) self.axis.set_ylim(-max_absoluto_ML, max_absoluto_ML) self.axis.plot(APs, MLs,'-',color='r') self.canvas.draw() def on_button2_clicked(self, widget): global APs, MLs APs, MLs = calc.geraAP_ML(APs, MLs) dis_resultante_total = calc.distanciaResultante(APs, MLs) dis_resultante_AP = calc.distanciaResultanteParcial(APs) dis_resultante_ML = calc.distanciaResultanteParcial(MLs) dis_media = calc.distanciaMedia(dis_resultante_total) dis_rms_total = calc.dist_RMS(dis_resultante_total) dis_rms_AP = calc.dist_RMS(dis_resultante_AP) dis_rms_ML = calc.dist_RMS(dis_resultante_ML) totex_total = calc.totex(APs, MLs) totex_AP = calc.totexParcial(APs) totex_ML = calc.totexParcial(MLs) mvelo_total = calc.mVelo(totex_total, 20) mvelo_AP = calc.mVelo(totex_AP, 20) mvelo_ML = calc.mVelo(totex_ML, 20) self.entry_Mdist.set_text(str(dis_media)) self.entry_Rdist_TOTAL.set_text(str(dis_rms_total)) self.entry_Rdist_AP.set_text(str(dis_rms_AP)) self.entry_Rdist_ML.set_text(str(dis_rms_ML)) self.entry_TOTEX_TOTAL.set_text(str(totex_total)) self.entry_TOTEX_AP.set_text(str(totex_AP)) self.entry_TOTEX_ML.set_text(str(totex_ML)) self.entry_MVELO_TOTAL.set_text(str(mvelo_total)) self.entry_MVELO_AP.set_text(str(mvelo_AP)) self.entry_MVELO_ML.set_text(str(mvelo_ML)) max_absoluto_AP = calc.valorAbsoluto(min(APs), max(APs)) max_absoluto_ML = calc.valorAbsoluto(min(MLs), max(MLs)) print('max_absoluto_AP:', max_absoluto_AP, 'max_absoluto_ML:', max_absoluto_ML) self.axis.clear() self.axis.set_xlim(-max_absoluto_AP, max_absoluto_AP) self.axis.set_ylim(-max_absoluto_ML, max_absoluto_ML) self.axis.plot(APs, MLs,'.-',color='g') self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.canvas.draw()
class StatPerspective(Gtk.Box, Ide.Perspective): """ Sets up the stats perspective and handles the signals. This class sets up the containers of the perspective and the matplotlib figure and canvas. An asynchronous method iterates over the project and gathers the data for the plot. """ def __init__(self, workdir, *args, **kwargs): super().__init__(*args, **kwargs) self.workdir = workdir # main containers scr_win = Gtk.ScrolledWindow(visible=True) pad_box = Gtk.Box(visible=True) pad_box.pack_start(scr_win, True, True, 20) main_box = Gtk.Box(visible=True, orientation=Gtk.Orientation.VERTICAL) scr_win.add_with_viewport(main_box) # content lbl_head = '<span font="36.0"><b>Project Stats</b></span>' heading = Gtk.Label(label=lbl_head, expand=True, visible=True) heading.set_use_markup(True) main_box.pack_start(heading, False, False, 0) line = Gtk.Separator(visible=True) main_box.pack_start(line, False, False, 0) self.fig = Figure(facecolor='none') self.ax = self.fig.add_subplot(111, axisbg='#ffffff') self.canvas = FigCanvas(self.fig) self.canvas.set_size_request(800, 600) self.canvas.draw() self.canvas.show() main_box.pack_start(self.canvas, True, True, 0) self.add(pad_box) self.titlebar = Ide.WorkbenchHeaderBar(visible=True) # Gather stats thread = threading.Thread(target=self.gather_stats) thread.daemon = True thread.start() def gather_stats(self): file_types = {} for root, subfolders, files in os.walk(self.workdir): for file in files: try: with open(root + "/" + file) as fl: line_count = 0 for line in fl: line_count += 1 splt_str = file.split(".") if len(splt_str) > 1: file_ext = splt_str[-1] else: continue if file_ext in file_types: # key exists, add line count file_types[ file_ext] = file_types[file_ext] + line_count else: # key doesn't exist, create new key file_types[file_ext] = line_count except: continue keys = [] values = [] for key, value in file_types.items(): keys.append(key) values.append(value) key_ar = np.array(keys) val_ar = np.array(values).astype(int) ar = np.vstack((key_ar, val_ar)).T ar = ar[ar[:, 1].astype(int).argsort()] rows = ar.shape[0] val_pos = np.arange(1, ar.shape[0] + 1) self.ax.barh(val_pos, ar[:, 1].astype(int), 0.8, align="center") # facecolor='yellow' self.ax.set_yticks(val_pos) self.ax.tick_params(axis="both", which="major", pad=15) self.ax.set_yticklabels(ar[:, 0], fontsize="16", weight="bold") self.ax.tick_params(axis="x", which="major", labelsize="16") self.canvas.set_size_request(800, (rows * 20 + 50)) self.canvas.draw() def do_get_id(self): return 'hello-world2' def do_get_title(self): return 'Hello' def do_get_priority(self): return 10000 def do_get_icon_name(self): return "utilities-system-monitor-symbolic" def do_get_titlebar(self): return self.titlebar
class GraphBase(object): """ A basic graph provider for using :py:mod:`matplotlib` to create graph representations of campaign data. This class is meant to be subclassed by real providers. """ name = 'Unknown' """The name of the graph provider.""" name_human = 'Unknown' """The human readable name of the graph provider used for UI identification.""" graph_title = 'Unknown' """The title that will be given to the graph.""" table_subscriptions = [] """A list of tables from which information is needed to produce the graph.""" is_available = True def __init__(self, application, size_request=None, style_context=None): """ :param tuple size_request: The size to set for the canvas. """ self.application = application self.style_context = style_context self.config = application.config """A reference to the King Phisher client configuration.""" self.figure, _ = pyplot.subplots() self.figure.set_facecolor(self.get_color('bg', ColorHexCode.WHITE)) self.axes = self.figure.get_axes() self.canvas = FigureCanvas(self.figure) self.manager = None self.minimum_size = (380, 200) """An absolute minimum size for the canvas.""" if size_request is not None: self.resize(*size_request) self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed) self.canvas.show() self.navigation_toolbar = NavigationToolbar( self.canvas, self.application.get_active_window()) self.popup_menu = Gtk.Menu.new() menu_item = Gtk.MenuItem.new_with_label('Export') menu_item.connect('activate', self.signal_activate_popup_menu_export) self.popup_menu.append(menu_item) menu_item = Gtk.MenuItem.new_with_label('Refresh') menu_item.connect('activate', self.signal_activate_popup_refresh) self.popup_menu.append(menu_item) menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar') menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar) self._menu_item_show_toolbar = menu_item self.popup_menu.append(menu_item) self.popup_menu.show_all() self.navigation_toolbar.hide() self._legend = None @property def rpc(self): return self.application.rpc @staticmethod def _ax_hide_ticks(ax): for tick in ax.yaxis.get_major_ticks(): tick.tick1On = False tick.tick2On = False @staticmethod def _ax_set_spine_color(ax, spine_color): for pos in ('top', 'right', 'bottom', 'left'): ax.spines[pos].set_color(spine_color) def add_legend_patch(self, legend_rows, fontsize=None): if self._legend is not None: self._legend.remove() self._legend = None fontsize = fontsize or self.fontsize_scale legend_bbox = self.figure.legend(tuple( patches.Patch(color=patch_color) for patch_color, _ in legend_rows), tuple(label for _, label in legend_rows), borderaxespad=1.25, fontsize=fontsize, frameon=True, handlelength=1.5, handletextpad=0.75, labelspacing=0.3, loc='lower right') legend_bbox.legendPatch.set_linewidth(0) self._legend = legend_bbox def get_color(self, color_name, default): """ Get a color by its style name such as 'fg' for foreground. If the specified color does not exist, default will be returned. The underlying logic for this function is provided by :py:func:`~.gui_utilities.gtk_style_context_get_color`. :param str color_name: The style name of the color. :param default: The default color to return if the specified one was not found. :return: The desired color if it was found. :rtype: tuple """ color_name = 'theme_color_graph_' + color_name sc_color = gui_utilities.gtk_style_context_get_color( self.style_context, color_name, default) return (sc_color.red, sc_color.green, sc_color.blue) def make_window(self): """ Create a window from the figure manager. :return: The graph in a new, dedicated window. :rtype: :py:class:`Gtk.Window` """ if self.manager is None: self.manager = FigureManager(self.canvas, 0) self.navigation_toolbar.destroy() self.navigation_toolbar = self.manager.toolbar self._menu_item_show_toolbar.set_active(True) window = self.manager.window window.set_transient_for(self.application.get_active_window()) window.set_title(self.graph_title) return window @property def fontsize_scale(self): scale = self.markersize_scale if scale < 5: fontsize = 'xx-small' elif scale < 7: fontsize = 'x-small' elif scale < 9: fontsize = 'small' else: fontsize = 'medium' return fontsize @property def markersize_scale(self): bbox = self.axes[0].get_window_extent().transformed( self.figure.dpi_scale_trans.inverted()) return bbox.width * self.figure.dpi * 0.01 def mpl_signal_canvas_button_pressed(self, event): if event.button != 3: return self.popup_menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time()) return True def signal_activate_popup_menu_export(self, action): dialog = extras.FileChooserDialog('Export Graph', self.application.get_active_window()) file_name = self.config['campaign_name'] + '.png' response = dialog.run_quick_save(file_name) dialog.destroy() if not response: return destination_file = response['target_path'] self.figure.savefig(destination_file, dpi=200, facecolor=self.figure.get_facecolor(), format='png') def signal_activate_popup_refresh(self, event): self.refresh() def signal_toggled_popup_menu_show_toolbar(self, widget): if widget.get_property('active'): self.navigation_toolbar.show() else: self.navigation_toolbar.hide() def resize(self, width=0, height=0): """ Attempt to resize the canvas. Regardless of the parameters the canvas will never be resized to be smaller than :py:attr:`.minimum_size`. :param int width: The desired width of the canvas. :param int height: The desired height of the canvas. """ min_width, min_height = self.minimum_size width = max(width, min_width) height = max(height, min_height) self.canvas.set_size_request(width, height)
class CampaignGraph(object): """ A basic graph provider for using :py:mod:`matplotlib` to create graph representations of campaign data. This class is meant to be subclassed by real providers. """ name = 'Unknown' """The name of the graph provider.""" name_human = 'Unknown' """The human readable name of the graph provider used for UI identification.""" graph_title = 'Unknown' """The title that will be given to the graph.""" table_subscriptions = [] """A list of tables from which information is needed to produce the graph.""" is_available = True def __init__(self, application, size_request=None, style_context=None): """ :param tuple size_request: The size to set for the canvas. """ self.application = application self.style_context = style_context self.config = application.config """A reference to the King Phisher client configuration.""" self.figure, _ = pyplot.subplots() self.figure.set_facecolor(self.get_color('bg', ColorHexCode.WHITE)) self.axes = self.figure.get_axes() self.canvas = FigureCanvas(self.figure) self.manager = None if size_request: self.canvas.set_size_request(*size_request) self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed) self.canvas.show() self.navigation_toolbar = NavigationToolbar(self.canvas, self.application.get_active_window()) self.popup_menu = Gtk.Menu.new() menu_item = Gtk.MenuItem.new_with_label('Export') menu_item.connect('activate', self.signal_activate_popup_menu_export) self.popup_menu.append(menu_item) menu_item = Gtk.MenuItem.new_with_label('Refresh') menu_item.connect('activate', lambda action: self.refresh()) self.popup_menu.append(menu_item) menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar') menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar) self._menu_item_show_toolbar = menu_item self.popup_menu.append(menu_item) self.popup_menu.show_all() self.navigation_toolbar.hide() self._legend = None @property def rpc(self): return self.application.rpc @staticmethod def _ax_hide_ticks(ax): for tick in ax.yaxis.get_major_ticks(): tick.tick1On = False tick.tick2On = False @staticmethod def _ax_set_spine_color(ax, spine_color): for pos in ('top', 'right', 'bottom', 'left'): ax.spines[pos].set_color(spine_color) def _load_graph(self, info_cache): raise NotImplementedError() def add_legend_patch(self, legend_rows, fontsize=None): if self._legend is not None: self._legend.remove() self._legend = None if fontsize is None: scale = self.markersize_scale if scale < 5: fontsize = 'xx-small' elif scale < 7: fontsize = 'x-small' elif scale < 9: fontsize = 'small' else: fontsize = 'medium' legend_bbox = self.figure.legend( tuple(patches.Patch(color=patch_color) for patch_color, _ in legend_rows), tuple(label for _, label in legend_rows), borderaxespad=1.25, fontsize=fontsize, frameon=True, handlelength=1.5, handletextpad=0.75, labelspacing=0.3, loc='lower right' ) legend_bbox.legendPatch.set_linewidth(0) self._legend = legend_bbox def get_color(self, color_name, default): """ Get a color by its style name such as 'fg' for foreground. If the specified color does not exist, default will be returned. The underlying logic for this function is provided by :py:func:`~.gui_utilities.gtk_style_context_get_color`. :param str color_name: The style name of the color. :param default: The default color to return if the specified one was not found. :return: The desired color if it was found. :rtype: tuple """ color_name = 'theme_color_graph_' + color_name sc_color = gui_utilities.gtk_style_context_get_color(self.style_context, color_name, default) return (sc_color.red, sc_color.green, sc_color.blue) def make_window(self): """ Create a window from the figure manager. :return: The graph in a new, dedicated window. :rtype: :py:class:`Gtk.Window` """ if self.manager is None: self.manager = FigureManager(self.canvas, 0) self.navigation_toolbar.destroy() self.navigation_toolbar = self.manager.toolbar self._menu_item_show_toolbar.set_active(True) window = self.manager.window window.set_transient_for(self.application.get_active_window()) window.set_title(self.graph_title) return window @property def markersize_scale(self): bbox = self.axes[0].get_window_extent().transformed(self.figure.dpi_scale_trans.inverted()) return bbox.width * self.figure.dpi * 0.01 def mpl_signal_canvas_button_pressed(self, event): if event.button != 3: return self.popup_menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time()) return True def signal_activate_popup_menu_export(self, action): dialog = gui_utilities.FileChooser('Export Graph', self.application.get_active_window()) file_name = self.config['campaign_name'] + '.png' response = dialog.run_quick_save(file_name) dialog.destroy() if not response: return destination_file = response['target_path'] self.figure.savefig(destination_file, format='png') def signal_toggled_popup_menu_show_toolbar(self, widget): if widget.get_property('active'): self.navigation_toolbar.show() else: self.navigation_toolbar.hide() def load_graph(self): """Load the graph information via :py:meth:`.refresh`.""" self.refresh() def refresh(self, info_cache=None, stop_event=None): """ Refresh the graph data by retrieving the information from the remote server. :param dict info_cache: An optional cache of data tables. :param stop_event: An optional object indicating that the operation should stop. :type stop_event: :py:class:`threading.Event` :return: A dictionary of cached tables from the server. :rtype: dict """ info_cache = (info_cache or {}) if not self.rpc: return info_cache for table in self.table_subscriptions: if stop_event and stop_event.is_set(): return info_cache if not table in info_cache: info_cache[table] = tuple(self.rpc.remote_table(table, query_filter={'campaign_id': self.config['campaign_id']})) for ax in self.axes: ax.clear() if self._legend is not None: self._legend.remove() self._legend = None self._load_graph(info_cache) self.figure.suptitle( self.graph_title, color=self.get_color('fg', ColorHexCode.BLACK), size=14, weight='bold', y=0.97 ) self.canvas.draw() return info_cache
class ODEGui(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="ODE Solver") #Main Box self.grid = Gtk.Grid(column_spacing=6) #Dopdown for kind of solver self.combo_solver = Gtk.ComboBoxText() self.combo_solver.set_entry_text_column(0) self.solvers = ["Euler explicit", "Heun explicit", "Runge-Kutta explicit","Midpoint implicit","Heun implicit"] for solver in self.solvers: self.combo_solver.append_text(solver) self.combo_solver.set_active(0) #Entrys self.function_entry = Gtk.Entry(text="test") self.x0_entry = Gtk.Entry(text="1,2") self.t0_entry = Gtk.Entry(text="0") self.T_entry = Gtk.Entry(text="5") self.N_entry = Gtk.Entry(text="100") self.eps_entry = Gtk.Entry(text="0.1") #Labels self.function_label = Gtk.Label("Function Name:") self.x0_label = Gtk.Label("Starting Point:") self.t0_label = Gtk.Label("Starting Time:") self.T_label = Gtk.Label("Ending Time:") self.N_label = Gtk.Label("Number of Steps:") self.eps_label = Gtk.Label("Stopping Criterium:") #Buttons self.plot_button = Gtk.Button(label="Plot") self.reset_plot_button = Gtk.Button(label="Reset Plot") self.plot_button.connect("clicked",self.on_plot_clicked) self.reset_plot_button.connect("clicked",self.reset) #Box on right side self.boxRight = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) #Plot self.fig = Figure(figsize=(5,4), dpi=100) self.ax = self.fig.add_subplot(111) self.ax.plot() self.canvas = FigureCanvas(self.fig) self.canvas.set_size_request(400,400) self.sw = Gtk.ScrolledWindow() self.sw.add_with_viewport(self.canvas) self.sw.set_min_content_width(500) self.sw.set_min_content_height(500) self.boxRight.pack_start(self.sw,True,True,0) self.toolbar = NavigationToolbar(self.canvas,self) self.boxRight.pack_start(self.toolbar,False,True,0) self.foo = Gtk.Label("") #Left Side self.gridLeft = Gtk.Grid(row_spacing=6) #Put it together self.gridLeft.attach(self.combo_solver,0,0,1,1) self.gridLeft.attach(self.foo,0,1,1,1) self.gridLeft.attach(self.function_label,0,2,1,1) self.gridLeft.attach(self.function_entry,0,3,1,1) self.gridLeft.attach(self.x0_label,0,4,1,1) self.gridLeft.attach(self.x0_entry,0,5,1,1) self.gridLeft.attach(self.t0_label,0,6,1,1) self.gridLeft.attach(self.t0_entry,0,7,1,1) self.gridLeft.attach(self.T_label,0,8,1,1) self.gridLeft.attach(self.T_entry,0,9,1,1) self.gridLeft.attach(self.N_label,0,10,1,1) self.gridLeft.attach(self.N_entry,0,11,1,1) self.gridLeft.attach(self.eps_label,0,12,1,1) self.gridLeft.attach(self.eps_entry,0,13,1,1) self.gridLeft.attach(self.plot_button,0,14,1,1) self.gridLeft.attach(self.reset_plot_button,0,15,1,1) # self.boxLeft.pack_start(self.function_entry,True,True,0) # self.boxLeft.pack_start(self.x0_entry,True,True,0) # self.boxLeft.pack_start(self.t0_entry,True,True,0) # self.boxLeft.pack_start(self.T_entry,True,True,0) # self.boxLeft.pack_start(self.N_entry,True,True,0) # self.boxLeft.pack_start(self.eps_entry,True,True,0) # self.boxLeft.pack_start(self.plot_button,True,True,0) # self.boxLeft.pack_start(self.reset_plot_button,True,True,0) self.grid.attach(self.gridLeft,0,0,2,6) self.grid.attach(self.boxRight,2,0,4,6) self.add(self.grid) #Definition of methods A_euler_explicit = np.array([0]) b_euler_explicit = np.array([1]) c_euler_explicit = np.array([0]) self.euler_explicit = (A_euler_explicit,b_euler_explicit,c_euler_explicit) A_heun_explicit = np.array([[0,0],[1,0]]) b_heun_explicit = np.array([0.5,0.5]) c_heun_explicit = np.array([0,1]) self.heun_explicit = (A_heun_explicit,b_heun_explicit,c_heun_explicit) A_rk_explicit = np.array([[0,0,0,0],[0.5,0,0,0],[0,0.5,0,0],[0,0,1,0]]) b_rk_explicit = np.array([1/6,2/6,2/6,1/6]) c_rk_explicit = np.array([0,0.5,0.5,1]) self.rk_explicit = (A_rk_explicit,b_rk_explicit,c_rk_explicit) A_midpoint_implicit = np.array([[0.5]]) b_midpoint_implicit = np.array([1]) c_midpoint_implicit = np.array([0.5]) self.midpoint_implicit = (A_midpoint_implicit,b_midpoint_implicit,c_midpoint_implicit) A_heun_implicit = np.array([[0,0],[0.5,0.5]]) b_heun_implicit = np.array([0.5,0.5]) c_heun_implicit = np.array([0,1]) self.heun_implicit = (A_heun_implicit,b_heun_implicit,c_heun_implicit) self.methods = {} self.methods[self.solvers[0]] = self.euler_explicit self.methods[self.solvers[1]] = self.heun_explicit self.methods[self.solvers[2]] = self.rk_explicit self.methods[self.solvers[3]] = self.midpoint_implicit self.methods[self.solvers[4]] = self.heun_implicit def on_plot_clicked(self,plot): function_name = self.function_entry.get_text() starting_point = self.x0_entry.get_text() x0 = np.array([float(s) for s in starting_point.split(",")]) t0 = float(self.t0_entry.get_text()) T = float(self.T_entry.get_text()) N = int(self.N_entry.get_text()) eps = float(self.eps_entry.get_text()) meth = self.combo_solver.get_active_text() mat = self.methods[meth] func = getattr(functions, function_name) if meth == self.solvers[3] or meth == self.solvers[4]: solution = ODESolver.RungeKuttaImplizit(func,(x0,t0),T,N,mat[0],mat[1],mat[2],eps) else: solution = ODESolver.RungeKutta(func,(x0,t0),T,N,mat[0],mat[1],mat[2]) for i in range(x0.size): self.ax.plot(solution[1],solution[0][i,:]) self.fig.canvas.draw() def reset(self,plot): self.ax.clear() self.ax.plot() self.fig.canvas.draw()
def show_mesh(self, widget, profile): _ = self.lang.gettext bm = self._printer.get_config_section("bed_mesh %s" % profile) if bm == False: logging.info("Unable to load profile: %s" % profile) return if profile == self.active_mesh: abm = self._printer.get_stat("bed_mesh") if abm == None: logging.info("Unable to load active mesh: %s" % profile) return x_range = [int(abm['mesh_min'][0]), int(abm['mesh_max'][0])] y_range = [int(abm['mesh_min'][1]), int(abm['mesh_max'][1])] z_range = [ min(min(abm['mesh_matrix'])), max(max(abm['mesh_matrix'])) ] counts = [len(abm['mesh_matrix'][0]), len(abm['mesh_matrix'])] deltas = [(x_range[1] - x_range[0]) / (counts[0] - 1), (y_range[1] - y_range[0]) / (counts[1] - 1)] x = [(i * deltas[0]) + x_range[0] for i in range(counts[0])] y = [(i * deltas[0]) + y_range[0] for i in range(counts[1])] x, y = np.meshgrid(x, y) z = np.asarray(abm['mesh_matrix']) else: x_range = [int(bm['min_x']), int(bm['max_x'])] y_range = [int(bm['min_y']), int(bm['max_y'])] z_range = [min(min(bm['points'])), max(max(bm['points']))] deltas = [(x_range[1] - x_range[0]) / (int(bm['x_count']) - 1), (y_range[1] - y_range[0]) / (int(bm['y_count']) - 1)] x = [(i * deltas[0]) + x_range[0] for i in range(bm['x_count'])] y = [(i * deltas[0]) + y_range[0] for i in range(bm['y_count'])] x, y = np.meshgrid(x, y) z = np.asarray(bm['points']) rc('axes', edgecolor="#fff", labelcolor="#fff") rc(('xtick', 'ytick'), color="#fff") fig = plt.figure() fig.patch.set_facecolor("black") ax = Axes3D(fig, auto_add_to_figure=False) ax.set_facecolor("black") ax.set(title=profile, xlabel="X", ylabel="Y") ax.spines['bottom'].set_color("#fff") fig.add_axes(ax) surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.coolwarm) ax.set_zlim(z_range[0], z_range[1]) ax.zaxis.set_major_locator(LinearLocator(10)) # A StrMethodFormatter is used automatically ax.zaxis.set_major_formatter('{x:.02f}') fig.colorbar(surf, shrink=0.5, aspect=5) box = Gtk.VBox() box.set_hexpand(True) box.set_vexpand(True) title = Gtk.Label() title.set_markup("<b>%s</b>" % profile) title.set_hexpand(True) title.set_halign(Gtk.Align.CENTER) canvas_box = Gtk.Box() canvas_box.set_hexpand(True) canvas_box.set_vexpand(True) box.add(title) box.add(canvas_box) buttons = [{"name": _("Close"), "response": Gtk.ResponseType.CANCEL}] dialog = self._gtk.Dialog(self._screen, buttons, box, self._close_dialog) alloc = canvas_box.get_allocation() canvas = FigureCanvas(fig) canvas.set_size_request(alloc.width, self._screen.height / 3 * 2) canvas_box.add(canvas) canvas_box.show_all()
class MonitorWindow(Gtk.Window): def __init__(self, pid): Gtk.Window.__init__(self, title="Monitor") self.pid = pid self.restart = False main_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) f = matplotlib.figure.Figure() self.axes = f.add_subplot(111) self.axes.set_xlabel('Time (sec.)') self.axes.set_ylabel('Temperature (C)') self.axes.autoscale() self.out_axes = self.axes.twinx() self.out_axes.set_ylabel('OUT (%)') self.out_axes.autoscale() self.axes.grid() self.pv_x = [] self.pv_y = [] self.sv_x = [] self.sv_y = [] self.out_x = [] self.out_y = [] self.pv_plot, = self.axes.plot(self.pv_x, self.pv_y, 'b--') #b self.sv_plot, = self.axes.plot(self.sv_x, self.sv_y, 'k-') #k self.out_plot, = self.out_axes.plot(self.out_x, self.out_y, 'r:') #r self.canvas = FigureCanvas(f) self.canvas.set_size_request(800,600) vbox.add(self.canvas) hbox = Gtk.Box() # Start/restart program button = Gtk.Button('First Step') button.connect('clicked', self.on_restart) hbox.pack_start(button, False, False, 0) button = Gtk.Button('Continue') button.connect('clicked', lambda x: self.pid.coil('next')) hbox.pack_start(button, False, False, 0) button = Gtk.Button('Pause') button.connect('clicked', lambda x: self.pid.coil('pause')) hbox.pack_start(button, False, False, 0) button = Gtk.Button('Last Step') button.connect('clicked', lambda x: self.pid.coil('end')) hbox.pack_start(button, False, False, 0) hbox.set_sensitive(False) vbox.add(hbox) main_hbox.add(vbox) # Extra information required # Manual/automatic # Program step # Program status (running/pause) # Time/time remaining in step # PV/SV/dSV display? # AL1/AL2 self.add(main_hbox) table = Gtk.Table() row = 0 combo = widgets.PIDComboBoxText(pid, 'ModL') pid.connect('changed', lambda pid, n, val, mult, w=combo: w.set_sensitive(not val['A/M']) if n == 'flags' else None) label = Gtk.Label('Mode') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) table.attach(combo, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) row += 1 # Allow changing SV in manual mode # FIXME: disable if not SV? spin = widgets.PIDSpinButton(pid, 'SV') spin.set_sensitive(False) #combo.connect('changed', lambda combo, s=spin, c=combo: s.set_sensitive(c.get_active_text() == 'SV')) pid.connect('changed', lambda pid, n, val, mult, w=spin, c=combo: w.set_sensitive(not val['A/M'] and c.get_active_text() == 'SV') if n == 'flags' else None) pid.connect('changed', lambda pid, n, val, mult, w=spin: w.set_sensitive(val == 'SV') if n == 'ModL' else None) pid.connect('changed', lambda pid, n, val, mult, w=hbox: w.set_sensitive(val != 'SV') if n == 'ModL' else None) label = Gtk.Label('Set value') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) table.attach(spin, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) row += 1 label = Gtk.Label('Dynamic SV') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) pid.connect('changed', lambda pid, n, val, mult, w=label: w.set_text('%0.1f'%val if mult == .1 else '%d'%val) if n == 'dSV' else None) row += 1 label = Gtk.Label('PV') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) pid.connect('changed', lambda pid, n, val, mult, w=label: w.set_text('%0.1f'%val if mult == .1 else '%d'%val) if n == 'PV' else None) row += 1 check = widgets.ActionCheckButton(lambda val: pid.coil('manual' if val else 'auto', val), read=lambda p=pid: p.flag('A/M')) pid.connect('changed', lambda pid, n, val, mult, w=check: w.set_active(val['A/M'], user=False) if n == 'flags' else None) label = Gtk.Label('Manual mode') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) table.attach(check, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) row += 1 reg = pld.registers['OUT'] spin = widgets.PIDSpinButton(pid, 'OUT') spin.set_sensitive(False) pid.connect('changed', lambda pid, n, val, mult, w=spin: w.set_sensitive(val['A/M']) if n == 'flags' else None) label = Gtk.Label('Output level') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) table.attach(spin, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) row += 1 label = Gtk.Label('Alarm 1') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) pid.connect('changed', lambda pid, n, val, mult, w=label: w.set_text('On' if val['AL1'] else 'Off') if n == 'flags' else None) row += 1 label = Gtk.Label('Alarm 2') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) pid.connect('changed', lambda pid, n, val, mult, w=label: w.set_text('On' if val['AL2'] else 'Off') if n == 'flags' else None) row += 1 label = Gtk.Label('Current Step') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) self.current_step = label row += 1 label = Gtk.Label('Time elapsed/total') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) self.step_time = label row += 1 label = Gtk.Label('Step action') label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) label = Gtk.Label() label.set_alignment(0, 0.5) table.attach(label, 1, 2, row, row+1, yoptions=Gtk.AttachOptions.SHRINK) self.status = label row += 1 main_hbox.add(table) self.run = True self.d = self.loop() self.d.addErrback(lambda x: None) self.connect('delete-event', self.on_delete) def on_restart(self, widget): self.restart = True def on_delete(self, widget, event): self.run = False @twisted.internet.defer.inlineCallbacks def loop(self): start = time.time() while self.run: if self.restart: start = time.time() self.pv_x = [] self.pv_y = [] self.sv_x = [] self.sv_y = [] self.out_x = [] self.out_y = [] self.axes.relim() self.axes.autoscale() self.canvas.draw() self.restart = False yield self.pid.coil('start') yield self.pid.coil('auto') try: val, mult = yield self.pid.holding_read('Pr+t') step, step_t = val val, mult = yield self.pid.holding_read('t-' + ('%02d' % step)) step_total = 0 if type(val) is tuple: val, idx = val if val == 'Run': step_total = idx elif val == 'Jump': val += ' to ' + str(abs(idx)) self.current_step.set_text(str(step)) self.step_time.set_text(str(step_t) + '/' + str(step_total) if val == 'Run' else 'NA') self.status.set_text(val) pv, mult = yield self.pid.holding_read('PV') now = time.time() - start if len(self.pv_y) > 1 and self.pv_y[-2] == self.pv_y[-1] == pv: self.pv_x[-1] = now else: self.pv_x.append(now) self.pv_y.append(pv) self.pv_plot.set_data(self.pv_x, self.pv_y) self.axes.relim() self.axes.autoscale() self.canvas.draw() sv, mult = yield self.pid.holding_read('dSV') now = time.time() - start if len(self.sv_y) > 1 and self.sv_y[-2] == self.sv_y[-1] == sv: self.sv_x[-1] = now else: self.sv_x.append(now) self.sv_y.append(sv) self.sv_plot.set_data(self.sv_x, self.sv_y) self.axes.relim() self.axes.autoscale() self.canvas.draw() out, mult = yield self.pid.holding_read('OUT') now = time.time() - start if len(self.out_y) > 1 and self.out_y[-2] == self.out_y[-1] == out: self.out_x[-1] = now else: self.out_x.append(now) self.out_y.append(out) self.out_plot.set_data(self.out_x, self.out_y) self.out_axes.relim() self.out_axes.autoscale() self.canvas.draw() except Exception, e: print 'monitor error', e traceback.print_exc(file=sys.stdout) d = twisted.internet.defer.Deferred() twisted.internet.reactor.callLater(0.300 , d.callback, None) yield d
class Plot: # TODO scaling of size when resizing # TODO tighter fit of plot # TODO BUG: weird redrawing issue on changing panes, probably should not redraw graph on changing panes # Plot object used GUI def __init__(self, builder, GPU, maxpoints, precision, linux_kernelmain, linux_kernelsub): # Can used for kernel specific workarounds self.linux_kernelmain = linux_kernelmain self.linux_kernelsub = linux_kernelsub self.precision = precision self.builder = builder self.GPU = GPU self.maxpoints = maxpoints self.fig = Figure(figsize=(1000, 150), dpi=100) self.fig.set_tight_layout(True) self.ax = self.fig.add_subplot(111) # enable, name, unit, mean, max, current self.signalstore = Gtk.ListStore(bool, str, str, str, str, str) self.Plotsignals = self.init_signals(self.GPU) self.init_treeview() self.update_signals() self.canvas = FigureCanvas(self.fig) self.canvas.set_size_request(1000, 150) self.object = self.builder.get_object("matplot") self.object.add(self.canvas) self.object.show_all() def init_signals(self, GPU): Plotsignals = [] # Define signals with: names units min max path plotenable plotcolor parser and outputargument used from parser Plotsignals.append( Plotsignal("GPU Clock", "[MHz]", GPU.pstate_clock[-1], GPU.pstate_clock[0], "/pp_dpm_sclk", True, "#1f77b4", GPU.get_current_clock, 0)) Plotsignals.append( Plotsignal("GPU State", "[-]", 0, len(GPU.pstate_clock), "/pp_dpm_sclk", True, "#ff7f0e", GPU.get_current_clock, 1)) Plotsignals.append( Plotsignal("MEM Clock", "[MHz]", GPU.pmem_clock[-1], GPU.pmem_clock[0], "/pp_dpm_mclk", True, "#d62728", GPU.get_current_clock, 0)) Plotsignals.append( Plotsignal("MEM State", "[-]", 0, len(GPU.pmem_clock), "/pp_dpm_mclk", True, "#9467bd", GPU.get_current_clock, 1)) Plotsignals.append( Plotsignal("FAN Speed", "[RPM]", 0, 255, "/hwmon/hwmon0/subsystem/hwmon0/fan1_input", True, "#8c564b", GPU.read_sensor)) Plotsignals.append( Plotsignal( "TEMP 1", "[m°C]", 0, GPU.read_sensor("/hwmon/hwmon0/subsystem/hwmon0/temp1_crit"), "/hwmon/hwmon0/subsystem/hwmon0/temp1_input", True, "#e377c2", GPU.read_sensor)) Plotsignals.append( Plotsignal("POWER", "[µW]", 0, GPU.read_sensor("/hwmon/hwmon0/power1_cap_max"), "/hwmon/hwmon0/power1_average", True, "#7f7f7f", GPU.read_sensor)) # GPU busy percent only properly available in linux version 4.19+ if (self.linux_kernelmain == 4 and self.linux_kernelsub > 18) or (self.linux_kernelmain >= 5): Plotsignals.append( Plotsignal("GPU Usage", "[-]", 1, 0, "/gpu_busy_percent", True, "#2ca02c", parser=GPU.read_sensor)) return Plotsignals def init_treeview(self): textrenderer = Gtk.CellRendererText() boolrenderer = Gtk.CellRendererToggle() boolrenderer.connect("toggled", self.on_cell_toggled) self.tree = self.builder.get_object("Signal Selection") self.tree.append_column( Gtk.TreeViewColumn("Plot", boolrenderer, active=0)) columnnames = ["Name", "Unit", "mean", "max", "current"] for i, column in enumerate(columnnames): tcolumn = Gtk.TreeViewColumn(column, textrenderer, text=i + 1) self.tree.append_column(tcolumn) #if i == 0: # tcolumn.set_sort_column_id(i+1) for plotsignal in self.Plotsignals: self.signalstore.append([ plotsignal.plotenable, plotsignal.name, convert_to_si(plotsignal.unit)[0], '0', '0', '0' ]) self.tree.set_model(self.signalstore) def update_signals(self): # Retrieve signal and set appropriate values in signalstore to update left pane in GUI for i, Plotsignal in enumerate(self.Plotsignals): Plotsignal.retrieve_data(self.maxpoints) self.signalstore[i][3] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_mean())[1], self.precision)) self.signalstore[i][4] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_max())[1], self.precision)) self.signalstore[i][5] = str( np.around( convert_to_si(Plotsignal.unit, Plotsignal.get_last_value())[1], self.precision)) def on_cell_toggled(self, widget, path): self.signalstore[path][0] = not self.signalstore[path][0] self.Plotsignals[int( path)].plotenable = not self.Plotsignals[int(path)].plotenable self.update_plot() def update_plot(self): self.ax.clear() for Plotsignal in self.Plotsignals: if Plotsignal.plotenable: self.ax.plot(convert_to_si(Plotsignal.unit, Plotsignal.get_values())[1], color=Plotsignal.plotcolor) #self.plots = [self.ax.plot(values, color=plotcolor) for values, plotcolor in zip(self.y.T, self.signalcolors)] self.ax.get_yaxis().set_visible(True) self.ax.get_xaxis().set_visible(True) self.canvas.draw() self.canvas.flush_events() def refresh(self): # This is run in thread self.update_signals() self.update_plot()
def __init__(self, parent): super(Home_Page, self).__init__() self.gtkWindow = parent self.controller = Home_Page_Controller(self) self.set_border_width(10) # dates row box = Gtk.HBox() dates_grid = Gtk.Grid() box.set_center_widget(dates_grid) start_date_label = Gtk.Label("Start Date") end_date_label = Gtk.Label("End Date") end_date_button = Gtk.Button(self.controller.end_date.strftime('%d-%m-%Y')) start_date_button = Gtk.Button(self.controller.start_date.strftime('%d-%m-%Y')) start_date_button.connect("clicked",self.controller.clicked_start_date_button) end_date_button.connect("clicked",self.controller.clicked_end_date_button) dates_grid.add(start_date_label) dates_grid.attach_next_to(start_date_button,start_date_label, Gtk.PositionType.BOTTOM, 1,2) dates_grid.attach_next_to(end_date_label,start_date_label, Gtk.PositionType.RIGHT, 1,1) dates_grid.attach_next_to(end_date_button,end_date_label, Gtk.PositionType.BOTTOM, 2,2) self.pack_start(box,True,True,10) self.controller.update_loms() self.fig = Figure(figsize=(5,5), dpi=100) #fig.legend() self.ax = self.fig.add_subplot(111) canvas = FigureCanvas(self.fig) canvas.set_size_request(400,400) self.pack_start(canvas, True, True, 10) self.controller.update_plot() #list pane scrolled_window = Gtk.ScrolledWindow() scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.tree = Gtk.TreeView(self.controller.lists_store) render_toggle = Gtk.CellRendererToggle() render_toggle.connect("toggled",self.controller.toggle_selected_list) self.tree.append_column(Gtk.TreeViewColumn("sel",render_toggle, \ active=0)) self.tree.append_column ( Gtk.TreeViewColumn("id",Gtk.CellRendererText(), text=1) ) self.tree.append_column ( Gtk.TreeViewColumn("name",Gtk.CellRendererText(), text=2) ) render_toggle = Gtk.CellRendererToggle() render_toggle.connect("toggled",self.controller.toggle_visible_list) self.tree.append_column(Gtk.TreeViewColumn("visible",render_toggle,\ active=3)) self.tree.append_column ( Gtk.TreeViewColumn("color",Gtk.CellRendererText(), text=4) ) scrolled_window.add(self.tree) self.pack_start(scrolled_window,True,True,10) button_box = Home_Page_Toolbar(self) self.pack_start(button_box,False,False,10)
class Handler: def __init__(self): global ppp self.window1 = builder.get_object("window1") self.window1.set_title("SPCinspector - No file loaded") self.vbox1 = builder.get_object("vbox1") self.label0 = builder.get_object("label0") self.label1 = builder.get_object("label1") self.label2 = builder.get_object("label2") self.label3 = builder.get_object("label3") self.label4 = builder.get_object("label4") self.label5 = builder.get_object("label5") self.label6 = builder.get_object("label6") self.label7 = builder.get_object("label7") self.label8 = builder.get_object("label8") # self.label9 = builder.get_object("label9") # self.label10 = builder.get_object("label10") # self.label11 = builder.get_object("label11") self.label12 = builder.get_object("label12") self.label13 = builder.get_object("label13") self.label14 = builder.get_object("label14") self.label15 = builder.get_object("label15") self.label16 = builder.get_object("label16") self.label17 = builder.get_object("label17") self.label18 = builder.get_object("label18") self.label19 = builder.get_object("label19") self.label20 = builder.get_object("label20") self.label21 = builder.get_object("label21") self.label22 = builder.get_object("label22") self.label23 = builder.get_object("label23") self.label24 = builder.get_object("label24") self.label25 = builder.get_object("label25") self.label26 = builder.get_object("label26") self.spin1 = builder.get_object("spin1") # depth self.spin2 = builder.get_object("spin2") # species self.spin3 = builder.get_object("spin3") # E-bins self.spin1.set_sensitive(False) self.spin2.set_sensitive(False) self.spin3.set_sensitive(False) self.button1 = builder.get_object("button1") self.button2 = builder.get_object("button2") self.button1.set_sensitive(False) self.cur_depth = 0 self.cur_species = 0 self.cur_ebin = 0 self.spc = [] self.path = "" fig = Figure(figsize=(5,5), dpi=100) #ax = fig.add_subplot(111, projection='polar') self.ax = fig.add_subplot(111) #x = [1, 2, 3, 4, 5] #y = [1, 4, 9, 16, 25] #self.ax.plot(x,y) self.ax.set_xlabel('Energy [MeV/u]') self.ax.set_ylabel('Histories') #sw = Gtk.ScrolledWindow() #myfirstwindow.add(sw) self.canvas = FigureCanvas(fig) self.canvas.set_size_request(600,600) self.vbox1.pack_end(self.canvas,True,True,True) self.zlut = { 1:'H',2:'He', 3:'Li',4:'Be',5:'B',6:'C',7:'N', 8:'O',9:'F',10:'Ne', 11:'Na',12:'Mg',13:'Al',14:'Si',15:'P',16:'S',17:'Cl',18:'Ar', 19:'K',20:'Ca' } print(ppp) if os.path.isfile(ppp): self.load_spc(ppp) def update_plot(self): d = self.spc.data[self.cur_depth] ds = d.species[self.cur_species] dse = ds.ebindata dsh = ds.histdata dsc = ds.rcumdata #print("NB:",len(dse),len(dsh),len(dsc)) self.ax.cla() self.ax.set_xlabel('Energy [MeV/u]') self.ax.set_ylabel('Histories') # plot legent in upper right corner text = r'$\mathregular{^{'+str(ds.la)+'}}$'+self.zlut.get(ds.lz,'?') self.ax.text(0.90, 0.94, text, fontsize=15,transform=self.ax.transAxes) #self.ax.plot(dse[1:],dsc[1:]) # cumulative sum self.ax.bar(dse[1:],dsh) self.canvas.draw() self.canvas.show() def onDeleteWindow(self, *args): Gtk.main_quit(*args) def onButtonPressed(self, button1): print("Hello World!") def main_quit(self, *args): print("Call Gtk.main_quit") Gtk.main_quit(*args) def on_spin1_value_changed(self,*args): self.cur_depth = self.spin1.get_value_as_int()-1 self.set_labels(self.spc) self.update_plot() def on_spin2_value_changed(self,*args): self.cur_species = self.spin2.get_value_as_int()-1 self.set_labels(self.spc) self.update_plot() def on_spin3_value_changed(self,*args): self.cur_ebin = self.spin3.get_value_as_int()-1 self.set_labels(self.spc) #self.update_plot() # no need to, as the energy marker is missing. def on_menuopen_activate(self,*args): dialog = Gtk.FileChooserDialog("Please choose a file", None, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) #self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: print("Open clicked") print("File selected: " + dialog.get_filename()) path = dialog.get_filename() dialog.destroy() self.load_spc(path) elif response == Gtk.ResponseType.CANCEL: print("Cancel clicked") dialog.destroy() def load_spc(self,path): spc = SPC(path) spc.read_spc() self.filename = os.path.split(path)[1] self.window1.set_title("SPCinspector - "+ self.filename) self.spin1.set_range(1,spc.ndsteps) self.spin2.set_range(1,spc.data[self.cur_depth].nparts) self.spin3.set_range(1,spc.data[self.cur_depth].species[self.cur_species].ne) self.spin1.set_sensitive(True) self.spin2.set_sensitive(True) self.spin3.set_sensitive(True) self.button1.set_sensitive(False) # Todo: currently disabled self.set_labels(spc) self.spc = spc self.update_plot() def set_labels(self,spc): self.label0.set_text(self.filename) self.label1.set_text(spc.filetype) self.label2.set_text(spc.fileversion) self.label3.set_text(spc.filedate) self.label4.set_text(spc.targname) self.label5.set_text(spc.projname) self.label6.set_text('{:f}'.format(spc.energy)) self.label7.set_text('{:f}'.format(spc.peakpos)) self.label8.set_text('{:f}'.format(spc.norm)) # - depth self.label12.set_text('{:d}'.format(spc.ndsteps)) d = spc.data[self.cur_depth] self.label13.set_text('{:f}'.format(d.depth)) self.label14.set_text('{:f}'.format(d.dsnorm)) # - species self.label15.set_text('{:d}'.format(d.nparts)) ds = d.species[self.cur_species] self.label16.set_text('{:f} {:f}'.format(ds.z,ds.a)) self.label17.set_text('{:d} {:d}'.format(ds.lz,ds.la)) self.label18.set_text('{:f}'.format(ds.dscum)) # running cum.sum over species self.label19.set_text('{:d}'.format(ds.nc)) # - energy self.label20.set_text('{:d}'.format(ds.ne)) dse = ds.ebindata[self.cur_ebin] if self.cur_ebin == 0: dsel = dse else: dsel = ds.ebindata[self.cur_ebin-1] dsh = ds.histdata[self.cur_ebin] dsc = ds.rcumdata[self.cur_ebin] self.label21.set_text('{:.4f} {:.4f} {:.4f}'.format(dsel,(dsel+dse)*0.5,dse)) self.label22.set_text('{:f}'.format(dse - dsel)) self.label23.set_text('{:f}'.format(dsh)) self.label24.set_text('{:f}'.format(dsh*(dse-dsel))) self.label25.set_text('{:f}'.format(dsc)) #cummulative sum self.label26.set_text('{:.2f} {:.2f}'.format(ds.ebindata.min(),ds.ebindata.max())) def _do_expose(self, widget, event): print("_do_expose") self.canvas.draw() self.canvas.show()
class MyWindow(Gtk.Window): def __init__(self): #Janela Gtk.Window.__init__(self, title="IEM-WBB") self.set_resizable(False) self.set_size_request(600, 600) self.set_position(Gtk.WindowPosition.CENTER) self.set_border_width(10) principal = Gtk.Box(spacing=10) principal.set_homogeneous(False) vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox_left.set_homogeneous(False) vbox_right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox_right.set_homogeneous(False) ### Boxes que ficarão dentro da vbox_left ### hbox_MDIST = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_MDIST.set_homogeneous(False) hbox_labels = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_labels.set_homogeneous(False) hbox_RDIST = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_RDIST.set_homogeneous(True) hbox_TOTEX = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_TOTEX.set_homogeneous(True) hbox_MVELO = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_MVELO.set_homogeneous(True) #criando os elementos das boxes Mdist, Labels, Rdist, TOTEX, Mvelo ##MDIST## label_Mdist = Gtk.Label('MDIST') self.entry_Mdist = Gtk.Entry() self.entry_Mdist.set_editable(False) self.entry_Mdist.set_max_length(max=8) ##LABELS## label_vazia = Gtk.Label(' ') label_AP = Gtk.Label('AP') label_ML = Gtk.Label('ML') label_TOTAL = Gtk.Label('TOTAL') ##RDIST## label_Rdist = Gtk.Label('RDIST') self.entry_Rdist_AP = Gtk.Entry() self.entry_Rdist_AP.set_editable(False) self.entry_Rdist_AP.set_max_length(max=8) self.entry_Rdist_ML = Gtk.Entry() self.entry_Rdist_ML.set_editable(False) self.entry_Rdist_ML.set_max_length(max=8) self.entry_Rdist_TOTAL = Gtk.Entry() self.entry_Rdist_TOTAL.set_editable(False) self.entry_Rdist_TOTAL.set_max_length(max=8) ##TOTEX## label_TOTEX = Gtk.Label('TOTEX') self.entry_TOTEX_AP = Gtk.Entry() self.entry_TOTEX_AP.set_editable(False) self.entry_TOTEX_AP.set_max_length(max=8) self.entry_TOTEX_ML = Gtk.Entry() self.entry_TOTEX_ML.set_editable(False) self.entry_TOTEX_ML.set_max_length(max=8) self.entry_TOTEX_TOTAL = Gtk.Entry() self.entry_TOTEX_TOTAL.set_editable(False) self.entry_TOTEX_TOTAL.set_max_length(max=8) ##MVELO## label_MVELO = Gtk.Label('MVELO') self.entry_MVELO_AP = Gtk.Entry() self.entry_MVELO_AP.set_editable(False) self.entry_MVELO_AP.set_max_length(max=8) self.entry_MVELO_ML = Gtk.Entry() self.entry_MVELO_ML.set_editable(False) self.entry_MVELO_ML.set_max_length(max=8) self.entry_MVELO_TOTAL = Gtk.Entry() self.entry_MVELO_TOTAL.set_editable(False) self.entry_MVELO_TOTAL.set_max_length(max=8) #colocando cada elemento dentro da sua box hbox_MDIST.pack_start(label_Mdist, True, True, 0) hbox_MDIST.pack_start(self.entry_Mdist, True, True, 0) hbox_labels.pack_start(label_vazia, True, True, 0) hbox_labels.pack_start(label_AP, True, True, 0) hbox_labels.pack_start(label_ML, True, True, 0) hbox_labels.pack_start(label_TOTAL, True, True, 0) hbox_RDIST.pack_start(label_Rdist, True, True, 0) hbox_RDIST.pack_start(self.entry_Rdist_AP, True, True, 0) hbox_RDIST.pack_start(self.entry_Rdist_ML, True, True, 0) hbox_RDIST.pack_start(self.entry_Rdist_TOTAL, True, True, 0) hbox_TOTEX.pack_start(label_TOTEX, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_AP, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_ML, True, True, 0) hbox_TOTEX.pack_start(self.entry_TOTEX_TOTAL, True, True, 0) hbox_MVELO.pack_start(label_MVELO, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_AP, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_ML, True, True, 0) hbox_MVELO.pack_start(self.entry_MVELO_TOTAL, True, True, 0) #colocando as boxes pequenas dentro das box vbox_left vbox_left.pack_start(hbox_MDIST, True, True, 0) vbox_left.pack_start(hbox_labels, True, True, 0) vbox_left.pack_start(hbox_RDIST, True, True, 0) vbox_left.pack_start(hbox_TOTEX, True, True, 0) vbox_left.pack_start(hbox_MVELO, True, True, 0) #elementos da vbox_right) #Notebook self.notebook = Gtk.Notebook() self.fig = plt.figure() self.axis = self.fig.add_subplot(111) self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.canvas = FigureCanvas(self.fig) self.canvas.set_size_request(500, 500) self.page1 = Gtk.Box() self.page1.set_border_width(10) self.page1.add(self.canvas) self.notebook.append_page(self.page1, Gtk.Label('Gráfico do CoP')) ##aqui fica a segunda janela do notebook self.fig2 = plt.figure() self.axis2 = self.fig2.add_subplot(111) self.axis2.set_ylabel('ML') self.axis2.set_xlabel('AP') self.canvas2 = FigureCanvas(self.fig2) self.canvas2.set_size_request(500, 500) self.page2 = Gtk.Box() self.page2.set_border_width(10) self.page2.add(self.canvas2) self.notebook.append_page(self.page2, Gtk.Label('Gráfico na frequência')) #criando os botoes hbox_botoes = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) hbox_botoes.set_homogeneous(True) self.button1 = Gtk.Button(label="Capturar") self.button1.connect("clicked", self.on_button1_clicked) self.button2 = Gtk.Button(label="Processar") self.button2.connect("clicked", self.on_button2_clicked) #colocando os botoes nas boxes hbox_botoes.pack_start(self.button1, True, True, 0) hbox_botoes.pack_start(self.button2, True, True, 0) vbox_right.pack_start(self.notebook, True, True, 0) vbox_right.pack_start(hbox_botoes, True, True, 0) # colocando as boxes verticais dentro da box principal principal.pack_start(vbox_left, True, True, 0) principal.pack_start(vbox_right, True, True, 0) #Adicionano os elementos na box exterior self.add(principal) def on_button1_clicked(self, widget): global APs, MLs balance = calc.readWBB() for (x, y) in balance: APs.append(x) MLs.append(y) max_absoluto_AP = calc.valorAbsoluto(min(APs), max(APs)) max_absoluto_ML = calc.valorAbsoluto(min(MLs), max(MLs)) print('max_absoluto_AP:', max_absoluto_AP, 'max_absoluto_ML:', max_absoluto_ML) self.axis.clear() self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.axis.set_xlim(-max_absoluto_AP, max_absoluto_AP) self.axis.set_ylim(-max_absoluto_ML, max_absoluto_ML) self.axis.plot(APs, MLs, '-', color='r') self.canvas.draw() def on_button2_clicked(self, widget): global APs, MLs APs, MLs = calc.geraAP_ML(APs, MLs) dis_resultante_total = calc.distanciaResultante(APs, MLs) dis_resultante_AP = calc.distanciaResultanteParcial(APs) dis_resultante_ML = calc.distanciaResultanteParcial(MLs) dis_media = calc.distanciaMedia(dis_resultante_total) dis_rms_total = calc.dist_RMS(dis_resultante_total) dis_rms_AP = calc.dist_RMS(dis_resultante_AP) dis_rms_ML = calc.dist_RMS(dis_resultante_ML) totex_total = calc.totex(APs, MLs) totex_AP = calc.totexParcial(APs) totex_ML = calc.totexParcial(MLs) mvelo_total = calc.mVelo(totex_total, 20) mvelo_AP = calc.mVelo(totex_AP, 20) mvelo_ML = calc.mVelo(totex_ML, 20) self.entry_Mdist.set_text(str(dis_media)) self.entry_Rdist_TOTAL.set_text(str(dis_rms_total)) self.entry_Rdist_AP.set_text(str(dis_rms_AP)) self.entry_Rdist_ML.set_text(str(dis_rms_ML)) self.entry_TOTEX_TOTAL.set_text(str(totex_total)) self.entry_TOTEX_AP.set_text(str(totex_AP)) self.entry_TOTEX_ML.set_text(str(totex_ML)) self.entry_MVELO_TOTAL.set_text(str(mvelo_total)) self.entry_MVELO_AP.set_text(str(mvelo_AP)) self.entry_MVELO_ML.set_text(str(mvelo_ML)) max_absoluto_AP = calc.valorAbsoluto(min(APs), max(APs)) max_absoluto_ML = calc.valorAbsoluto(min(MLs), max(MLs)) max_absoluto_AP *= 1.25 max_absoluto_ML *= 1.25 print('max_absoluto_AP:', max_absoluto_AP, 'max_absoluto_ML:', max_absoluto_ML) self.axis.clear() self.axis.set_xlim(-max_absoluto_AP, max_absoluto_AP) self.axis.set_ylim(-max_absoluto_ML, max_absoluto_ML) self.axis.plot(APs, MLs, '-', color='g') self.axis.set_ylabel('ML') self.axis.set_xlabel('AP') self.canvas.draw()
class CampaignGraph(object): """ A basic graph provider for using :py:mod:`matplotlib` to create graph representations of campaign data. This class is meant to be subclassed by real providers. """ name = 'Unknown' """The name of the graph provider.""" name_human = 'Unknown' """The human readable name of the graph provider used for UI identification.""" graph_title = 'Unknown' """The title that will be given to the graph.""" table_subscriptions = [] """A list of tables from which information is needed to produce the graph.""" is_available = True def __init__(self, config, parent, size_request=None): """ :param dict config: The King Phisher client configuration. :param parent: The parent window for this object. :type parent: :py:class:`Gtk.Window` :param tuple size_request: The size to set for the canvas. """ self.config = config """A reference to the King Phisher client configuration.""" self.parent = parent """The parent :py:class:`Gtk.Window` instance.""" self.figure, _ = pyplot.subplots() self.axes = self.figure.get_axes() self.canvas = FigureCanvas(self.figure) self.manager = None if size_request: self.canvas.set_size_request(*size_request) self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed) self.canvas.show() self.navigation_toolbar = NavigationToolbar(self.canvas, self.parent) self.popup_menu = Gtk.Menu.new() menu_item = Gtk.MenuItem.new_with_label('Export') menu_item.connect('activate', self.signal_activate_popup_menu_export) self.popup_menu.append(menu_item) menu_item = Gtk.MenuItem.new_with_label('Refresh') menu_item.connect('activate', lambda action: self.refresh()) self.popup_menu.append(menu_item) menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar') menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar) self._menu_item_show_toolbar = menu_item self.popup_menu.append(menu_item) self.popup_menu.show_all() self.navigation_toolbar.hide() def _load_graph(self, info_cache): raise NotImplementedError() def _graph_bar_set_yparams(self, top_lim): min_value = top_lim + (top_lim * 0.075) if min_value <= 25: scale = 5 else: scale = scale = 10 ** (len(str(int(min_value))) - 1) inc_scale = scale while scale <= min_value: scale += inc_scale top_lim = scale ax = self.axes[0] yticks = set((round(top_lim * 0.5), top_lim)) ax.set_yticks(tuple(yticks)) ax.set_ylim(top=top_lim) return def _graph_null_pie(self, title): ax = self.axes[0] ax.pie((100,), labels=(title,), colors=(MPL_COLOR_NULL,), autopct='%1.0f%%', shadow=True, startangle=90) ax.axis('equal') return def add_legend_patch(self, legend_rows, fontsize=None): handles = [] if not fontsize: scale = self.markersize_scale if scale < 5: fontsize = 'xx-small' elif scale < 7: fontsize = 'x-small' elif scale < 9: fontsize = 'small' else: fontsize = 'medium' for row in legend_rows: handles.append(patches.Patch(color=row[0], label=row[1])) self.axes[0].legend(handles=handles, fontsize=fontsize, loc='lower right') def graph_bar(self, bars, color=None, xticklabels=None, ylabel=None): """ Create a standard bar graph with better defaults for the standard use cases. :param list bars: The values of the bars to graph. :param color: The color of the bars on the graph. :type color: list, str :param list xticklabels: The labels to use on the x-axis. :param str ylabel: The label to give to the y-axis. :return: The bars created using :py:mod:`matplotlib` :rtype: `matplotlib.container.BarContainer` """ color = color or MPL_COLOR_NULL width = 0.25 ax = self.axes[0] self._graph_bar_set_yparams(max(bars) if bars else 0) bars = ax.bar(range(len(bars)), bars, width, color=color) ax.set_xticks([float(x) + (width / 2) for x in range(len(bars))]) if xticklabels: ax.set_xticklabels(xticklabels, rotation=30) for col in bars: height = col.get_height() ax.text(col.get_x() + col.get_width() / 2.0, height, "{0:,}".format(height), ha='center', va='bottom') if ylabel: ax.set_ylabel(ylabel) self.figure.subplots_adjust(bottom=0.25) return bars def make_window(self): """ Create a window from the figure manager. :return: The graph in a new, dedicated window. :rtype: :py:class:`Gtk.Window` """ if self.manager == None: self.manager = FigureManager(self.canvas, 0) self.navigation_toolbar.destroy() self.navigation_toolbar = self.manager.toolbar self._menu_item_show_toolbar.set_active(True) window = self.manager.window window.set_transient_for(self.parent) window.set_title(self.graph_title) return window @property def markersize_scale(self): bbox = self.axes[0].get_window_extent().transformed(self.figure.dpi_scale_trans.inverted()) return max(bbox.width, bbox.width) * self.figure.dpi * 0.01 def mpl_signal_canvas_button_pressed(self, event): if event.button != 3: return self.popup_menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time()) return True def signal_activate_popup_menu_export(self, action): dialog = gui_utilities.FileChooser('Export Graph', self.parent) file_name = self.config['campaign_name'] + '.png' response = dialog.run_quick_save(file_name) dialog.destroy() if not response: return destination_file = response['target_path'] self.figure.savefig(destination_file, format='png') def signal_toggled_popup_menu_show_toolbar(self, widget): if widget.get_property('active'): self.navigation_toolbar.show() else: self.navigation_toolbar.hide() def load_graph(self): """Load the graph information via :py:meth:`.refresh`.""" self.refresh() def refresh(self, info_cache=None, stop_event=None): """ Refresh the graph data by retrieving the information from the remote server. :param dict info_cache: An optional cache of data tables. :param stop_event: An optional object indicating that the operation should stop. :type stop_event: :py:class:`threading.Event` :return: A dictionary of cached tables from the server. :rtype: dict """ info_cache = (info_cache or {}) if not self.parent.rpc: return info_cache for table in self.table_subscriptions: if stop_event and stop_event.is_set(): return info_cache if not table in info_cache: info_cache[table] = tuple(self.parent.rpc.remote_table('campaign/' + table, self.config['campaign_id'])) for ax in self.axes: ax.clear() self._load_graph(info_cache) self.axes[0].set_title(self.graph_title, y=1.03) self.canvas.draw() return info_cache
def creaGraficoGtk(self, figure): # a partir de fig, creamos un elem canvas con el tam espeficicado x, y = self.window.get_size() canvas = FigureCanvas(figure) canvas.set_size_request(450, 300) return canvas
def mostrar_grafico(event): from matplotlib.figure import Figure from numpy import sin, cos, pi, linspace from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar #Inicializar valores beneficios = list() win = Gtk.Window() win.set_default_size(900,500) win.set_title("Grafico de beneficios") figura = Figure(figsize=(0.5,0.5), dpi=100) grafica = figura.add_subplot(111) meses = ("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre") meses = (1,2,3,4,5,6,7,8,9,10,11,12) conexion = DB(CONFIG["HOST"], CONFIG["USER"], CONFIG["PASSWORD"], CONFIG["DATABASE"]).conexion tabla = Tabla(conexion, "pedido") for mes in range(1,13): if len(str(mes)) == 1: fecha = CONFIG["GRAFICO_YEAR"]+"/"+"0" + str(mes)+"/01 00:00:00" if mes % 2 == 0: fecha_last = CONFIG["GRAFICO_YEAR"]+"/"+"0" + str(mes)+"/30 23:59:59" else: fecha_last = CONFIG["GRAFICO_YEAR"]+"/"+"0" + str(mes)+"/31 23:59:59" else: fecha = CONFIG["GRAFICO_YEAR"]+"/"+str(mes)+"/01 00:00:00" if mes % 2 == 0: fecha_last = CONFIG["GRAFICO_YEAR"]+"/"+ str(mes)+"/30 23:59:59" else: fecha_last = CONFIG["GRAFICO_YEAR"]+"/"+ str(mes)+"/31 23:59:59" fecha = "'"+fecha+"'" fecha_last = "'"+fecha_last+"'" select = list() tables = list() where = list() select.append("total") tables.append("pedido") where = {} where["fecha"] = { "operator" : ">=", "value" : fecha } where["fecha_2"] = { "operator" : "<=", "value" : fecha_last, "campo" : "fecha" } totales = tabla.advancedSQL(select, tables, where) total = 0 for total_pedido in totales: total = total + total_pedido[0] beneficios.append(total) coswave = grafica.plot(meses, beneficios, color='green', label='beneficios', linestyle='-') #grafica.set_xlim(-pi,pi) #grafica.set_ylim(-1.2,1.2) #grafica.fill_between(fechas, 0, total, (total - 1) > -1, color='blue', alpha=.3) #grafica.fill_between(fechas, 0, total, (total - 1) < -1, color='red', alpha=.3) #figura.xlabel("Meses "+CONFIG["GRAFICO_YEAR"]) #figura.ylabel("Beneficios €") sw = Gtk.ScrolledWindow() win.add (sw) # A scrolled window border goes outside the scrollbars and viewport sw.set_border_width (10) canvas = FigureCanvas(figura) # a Gtk.DrawingArea canvas.set_size_request(200,200) sw.add_with_viewport (canvas) win.show_all()