def displayGraph(self, xaxis, yaxis, hist): if (hist == None): return try: dialog = gtk.Window() figure = Figure(figsize=(6, 4), dpi=72) axis = figure.add_subplot(111) canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea canvas.show() dialog.add(canvas) # empty axis if neccesary, and reset title and stuff axis.clear() axis.set_xlabel(xaxis) axis.set_ylabel(yaxis) if len(hist) > 1: axis.plot(hist[0], 'r') axis.plot(hist[1], 'g') axis.plot(hist[2], 'b') else: axis.plot(hist[0], 'r') dialog.show() except ValueError: sys.exit(1)
def __init__(self, owner): label = "Grayscale analysis" gtk.Frame.__init__(self, label) self.owner = owner self.DMS = self.owner.DMS self.grayscale_fig = plt.Figure(figsize=(50,40), dpi=100) self.grayscale_fig.subplots_adjust(left=0.02, right=0.98, wspace=0.3) self.grayscale_plot_img = self.grayscale_fig.add_subplot(121) self.grayscale_plot_img.get_xaxis().set_visible(False) self.grayscale_plot_img.get_yaxis().set_visible(False) self.grayscale_plot_img_ax = None self.grayscale_plot_img_ax2 = None self.grayscale_plot = self.grayscale_fig.add_subplot(122) self.grayscale_plot.axis("tight") self.grayscale_plot.get_xaxis().set_visible(False) grayscale_canvas = FigureCanvas(self.grayscale_fig) grayscale_canvas.show() grayscale_canvas.set_size_request(400,150) self.add(grayscale_canvas) self.show()
def displayGraph(self, xaxis, yaxis, hist): if(hist == None): return try: dialog = gtk.Window() figure = Figure(figsize=(6,4), dpi=72) axis = figure.add_subplot(111) canvas = FigureCanvasGTK(figure) # a gtk.DrawingArea canvas.show() dialog.add(canvas) # empty axis if neccesary, and reset title and stuff axis.clear() axis.set_xlabel(xaxis) axis.set_ylabel(yaxis) if len(hist) > 1: axis.plot(hist[0], 'r') axis.plot(hist[1], 'g') axis.plot(hist[2], 'b') else: axis.plot(hist[0], 'r') dialog.show() except ValueError: sys.exit(1)
class WidgetsWrapper: def __init__(self): self.widgets = gtk.glade.XML('mpl_with_glade.glade') self.widgets.signal_autoconnect(GladeHandlers.__dict__) self.figure = Figure(figsize=(8,6), dpi=72) self.axis = self.figure.add_subplot(111) t = arange(0.0,3.0,0.01) s = sin(2*pi*t) self.axis.plot(t,s) self.axis.set_xlabel('time (s)') self.axis.set_ylabel('voltage') self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self['vboxMain'].pack_start(self.canvas, gtk.TRUE, gtk.TRUE) self['vboxMain'].show() # below is optional if you want the navigation toolbar self.navToolbar = NavigationToolbar(self.canvas, self['windowMain']) self.navToolbar.lastDir = '/var/tmp/' self['vboxMain'].pack_start(self.navToolbar) self.navToolbar.show() sep = gtk.HSeparator() sep.show() self['vboxMain'].pack_start(sep, gtk.TRUE, gtk.TRUE) self['vboxMain'].reorder_child(self['buttonClickMe'],-1) def __getitem__(self, key): return self.widgets.get_widget(key)
class WidgetsWrapper: def __init__(self): self.widgets = gtk.glade.XML('mpl_with_glade.glade') self.widgets.signal_autoconnect(GladeHandlers.__dict__) self.figure = Figure(figsize=(8, 6), dpi=72) self.axis = self.figure.add_subplot(111) t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * t) self.axis.plot(t, s) self.axis.set_xlabel('time (s)') self.axis.set_ylabel('voltage') self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self['vboxMain'].pack_start(self.canvas, gtk.TRUE, gtk.TRUE) self['vboxMain'].show() # below is optional if you want the navigation toolbar self.navToolbar = NavigationToolbar(self.canvas, self['windowMain']) self.navToolbar.lastDir = '/var/tmp/' self['vboxMain'].pack_start(self.navToolbar) self.navToolbar.show() sep = gtk.HSeparator() sep.show() self['vboxMain'].pack_start(sep, gtk.TRUE, gtk.TRUE) self['vboxMain'].reorder_child(self['buttonClickMe'], -1) def __getitem__(self, key): return self.widgets.get_widget(key)
class Onus: def __init__(self): #self.gladefile = "onus.glade" self.gladefile = "../onus.glade" self.wTree = gtk.glade.XML(self.gladefile, "mainWindow") FILES = [ "../../0_10_0.TXT" ] t = 0 time = [] heart_rate = [] step_count = [] activity = [] # Get the Data for file in FILES: infile = open(file,"r") data_section = 0 while 1: line = infile.readline() if not line: break moment = line.split(",") time.append( t ) t += 1 step_count.append( moment[0] ) heart_rate.append( moment[1] ) activity.append( moment[2] ) self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Time (minutes)') self.axis.set_ylabel('Heart Rate (bpm)') self.axis.set_title('Activity') self.axis.grid(True) self.axis.plot(time, heart_rate, time, step_count, time, activity) self.axis.legend(["Heart Rate", "Step Count", "Activity"]) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphview = self.wTree.get_widget("vbox2") self.graphview.pack_start(self.canvas, True, True) #Create our dictionay and connect it dic = { "on_mainWindow_destroy" : gtk.main_quit, "on_connect" : self.on_connect, "on_import" : self.on_import } self.wTree.signal_autoconnect(dic) def on_connect(self, widget): #dan = Fetch() #.start() self.statusbar1 = self.wTree.get_widget("statusbar1") self.statusbar1.push(0, "Connected") def on_import(self, widget): self.statusbar1 = self.wTree.get_widget("statusbar1") self.statusbar1.push(0, "Importing")
class AppGui(object): def __init__(self): gladefile = "pygtk-matplotlib.glade" self.windowname = "main_window" self.wTree = gtk.glade.XML(gladefile, self.windowname) dic = { "on_main_window_destroy" : gtk.main_quit, "on_button1_clicked" : self.render_graph, #"on_button3_clicked" : self.fillTree, #"on_notebook1_switch_page" : self.selectNotebookPage, #"on_treeview1_button_press_event" : self.clickTree, #"on_button2_clicked" : self.createProjectGraph, } self.wTree.signal_autoconnect(dic) # setup matplotlib stuff on first notebook page (empty graph) self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(1,1,1) self.axis.set_xlabel('Yepper') self.axis.set_ylabel('Flabber') self.axis.set_title('An Empty Graph') self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() # Adding matplotlib canvas to our window self.graphview = self.wTree.get_widget("main_vbox") self.graphview.pack_start(self.canvas, True, True) #self.listview = self.wTree.get_widget("treeview1") #self.listmodel = gtk.ListStore(str, int, int, str, str) #self.listview.set_model(self.listmodel) #renderer = gtk.CellRendererText() #column = gtk.TreeViewColumn("Name",renderer, text=0) #column.set_clickable(True) #column.set_sort_column_id(0) #column.connect("clicked", self.createDBGraph) #column.set_resizable(True) #self.listview.append_column(column) self.wTree.get_widget(self.windowname).show() def render_graph(self, widget): print "render_graph()" self.axis.clear() self.axis.set_xlabel('Samples (n)') self.axis.set_ylabel('Value (-)') self.axis.set_title('Another Graph (click on the columnheader to sort)') self.axis.grid(True)
class MainWin: def __init__(self): # Le decimos a nuestro programa el nombre del archivo glade self.widgets = gtk.glade.XML("interface.glade") # Creamos un pequeño diccionario que contiene las señales definidas en # glade y su respectivo método (o llamada) signals = { "on_buttonIniciar_clicked" : self.on_buttonIniciar_clicked, "on_about_dialog_clicked" : self.on_about_dialog_clicked, "on_exit_clicked" : gtk.main_quit, # al presionar el boton salir, sale de la aplicacion "gtk_main_quit" : gtk.main_quit } # # Luego se auto-conectan las señales. self.widgets.signal_autoconnect(signals) # Nota: Otra forma de hacerlo es No crear el diccionario signals y # solo usar "self.widgets.signal_autoconnect(self)" -->Ojo con el self # Ahora obtenemos del archivo glade los widgets que vamos a utilizar self.labelTiempo = self.widgets.get_widget("labelTiempo") #label de tiempo self.buttonIniciar = self.widgets.get_widget("buttonIniciar") #boton iniciar self.aboutDialog = self.widgets.get_widget("aboutDialog") #dialogo acerca de #Definición del widget que manejará la gráfica self.figure = Figure(figsize=(6,4), dpi=60) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('X') self.axis.set_ylabel('Y') self.axis.set_title('Graph') self.axis.grid(True) #Agregar la gráfica a la caja vertical self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.graphview = self.widgets.get_widget("matplot") self.graphview.pack_start(self.canvas, True, True) # Se definen los métodos, en este caso señales como "destroy" ya fueron # definidas en el .glade, asà solo se necesita definir "on_button1_clicked" def on_about_dialog_clicked(self, widget): #self.labelTiempo.set_text("Hola !") self.aboutDialog.show() def on_buttonIniciar_clicked(self, widget): self.labelTiempo.set_text("Hola !")
class appGui: def __init__(self): gladefile = "project2.glade" self.windowname = "gtkbench" self.wTree = gtk.glade.XML(gladefile, self.windowname) self.win = self.wTree.get_widget("gtkbench") self.win.maximize() dic = {"on_window1_destroy" : gtk.main_quit, "on_button1_clicked" : self.submitDB, "on_button3_clicked" : self.fillTree, "on_notebook1_switch_page" : self.selectNotebookPage, "on_treeview1_button_press_event" : self.clickTree, "on_button2_clicked" : self.createProjectGraph } self.wTree.signal_autoconnect(dic) # start with database selection self.wDialog = gtk.glade.XML("project2.glade", "dbSelector") # setup matplotlib stuff on first notebook page (empty graph) self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Yepper') self.axis.set_ylabel('Flabber') self.axis.set_title('An Empty Graph') self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphview = self.wTree.get_widget("vbox1") self.graphview.pack_start(self.canvas, True, True) # setup listview for database self.listview = self.wTree.get_widget("treeview1") self.listmodel = gtk.ListStore(str, int, int, str, str) self.listview.set_model(self.listmodel) renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Name",renderer, text=0) column.set_clickable(True) column.set_sort_column_id(0) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Age",renderer, text=1) column.set_clickable(True) column.set_sort_column_id(1) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() column = gtk.TreeViewColumn("Shoesize",renderer, text=2) column.set_clickable(True) column.set_sort_column_id(2) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() column = gtk.TreeViewColumn("Created",renderer, text=3) column.set_clickable(True) column.set_sort_column_id(3) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() #renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Updated",renderer, text=4) column.set_clickable(True) column.set_sort_column_id(4) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) return # callbacks. def submitDB(self, widget): while True: try: name = self.wTree.get_widget("entry1").get_text() age = self.wTree.get_widget("entry2").get_text() size = self.wTree.get_widget("entry3").get_text() assert name != "" assert age != "" assert size != "" dataUsr = name, age, size sd = DBStuff.Eb_db(host, user, passwd, db) sd.subMit(dataUsr) break except AssertionError: self.wDialog = gtk.glade.XML("project2.glade", "dbWarningEmpty") close = self.wDialog.get_widget("dbWarningEmpty") response = close.run() if response == gtk.RESPONSE_CLOSE: close.destroy() break except DBStuff.MySQLdb.IntegrityError: def callback(): self.wDialog = gtk.glade.XML("project2.glade", "dbWarningOverwrite") close = self.wDialog.get_widget("dbWarningOverwrite") response = close.run() if response == gtk.RESPONSE_CANCEL: close.destroy() if response == gtk.RESPONSE_OK: sd.delRow(name) wd = DBStuff.Eb_db(host, user, passwd, db) wd.subMit(dataUsr) close.destroy() callback() break def fillTree(self, widget): model = self.listmodel self.listmodel.clear() fg = DBStuff.Eb_db(host, user, passwd, db) fg.getData("Age") for i in range(len(fg.data)): # note: all data from table "bench" is appended, but that is something you don't want # possible solution: create a seperate table for the listbox (eg. ommit Timestamp, keep it in another table) self.listmodel.append(fg.data[i]) self.createDBGraph(self) def selectNotebookPage(self, widget, notebookpage, page_number): # if database page is selected (nr. 1 for now!), retrieve data if page_number == 1: self.fillTree(self) if page_number == 0: print "clicked first tab" def clickTree(self, treeview, event): if event.button == 3: x = int(event.x) y = int(event.y) time = event.time pthinfo = treeview.get_path_at_pos(x, y) if pthinfo != None: path, col, cellx, celly = pthinfo treeview.grab_focus() treeview.set_cursor( path, col, 0) self.wDialog = gtk.glade.XML("project2.glade", "treeRightClick") close = self.wDialog.get_widget("treeRightClick") response = close.run() if response == gtk.RESPONSE_OK: close.destroy() print x print y print pthinfo #self.popup.popup( None, None, None, event.button, time) return 1 def createProjectGraph(self, widget): while True: try: # empty axis if neccesary, and reset title and stuff self.axis.clear() self.axis.set_xlabel('Yepper') self.axis.set_ylabel('Flabber') self.axis.set_title('A Graph') self.axis.grid(True) # get data age = self.wTree.get_widget("entry2").get_text() size = self.wTree.get_widget("entry3").get_text() age != "" size != "" N = 1 ind = arange(N) # the x locations for the groups width = 0.35 # the width of the bars p1 = self.axis.bar(ind, int(age), width, color='r') p2 = self.axis.bar(ind+width, int(size), width, color='y') self.axis.legend((p1[0], p2[0]), ("Age", "Size"), shadow = True) #self.axis.set_xticks(ind+width, ('G1') ) self.axis.set_xlim(-width,len(ind)) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.grahview = self.wTree.get_widget("vbox1") self.grahview.pack_start(self.canvas, True, True) break except ValueError: self.wDialog = gtk.glade.XML("project2.glade", "cannotCreateProjGraph") close = self.wDialog.get_widget("cannotCreateProjGraph") response = close.run() if response == gtk.RESPONSE_OK: close.destroy() break def createDBGraph(self, widget): self.axis.clear() self.axis.set_xlabel('Samples (n)') self.axis.set_ylabel('Value (-)') self.axis.set_title('Another Graph (click on the columnheader to sort)') self.axis.grid(True) # get columns from listmodel age = [] for row in self.listmodel: age.append(row[1]) size = [] for row in self.listmodel: size.append(row[2]) # get number of rows N = len(age) ind = arange(N) # the x locations for the groups width = 0.35 # the width of the bars p1 = self.axis.bar(ind, age, width, color='b') p2 = self.axis.bar(ind+width, size, width, color='r') # destroy graph if it already exists while True: try: self.canvas2.destroy() break except: print "nothing to destroy" break self.canvas2 = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas2.show() self.grahview = self.wTree.get_widget("vbox2") self.grahview.pack_start(self.canvas2, True, True)
class BrachGUI: def __init__(self): self.lastUpdate = datetime.now() self.thread = None self.lastBest = None self.builder = gtk.Builder() self.builder.add_from_file(GUI_FILENAME) # init default values (due to Glade 3.7 bug) self.builder.get_object("input_Ax").set_value(config.A[0]) self.builder.get_object("input_Ay").set_value(config.A[1]) self.builder.get_object("input_Bx").set_value(config.B[0]) self.builder.get_object("input_By").set_value(config.B[1]) self.builder.get_object("input_population_size").set_value(config.POPULATION_SIZE) self.builder.get_object("input_elitism").set_value(config.ELITISM * 100) self.builder.get_object("input_points").set_value(config.POINTS_INIT) self.builder.get_object("input_crossover").set_value(config.CROSSOVER_PROB * 100) self.builder.get_object("input_crossover_points").set_value(config.CROSSOVER_POINTS) self.builder.get_object("input_mutation").set_value(config.MUTATION_PROB * 100) self.builder.get_object("input_mutation_burst").set_value(config.MUTATION_BURST * 100) self.builder.get_object("button_save").set_sensitive(False) self.running = False # init the input_selection_type selection_model = gtk.ListStore(str) selection_model.append(["Tournament"]) selection_model.append(["Roulette"]) selection_model.append(["Rafael-Ribeiro"]) selection_box = self.builder.get_object("input_selection_type") selection_box.set_model(selection_model) cell = gtk.CellRendererText() selection_box.pack_start(cell) selection_box.add_attribute(cell, "text", 0) selection_box.set_active(0) # init the input_representation representation_model = gtk.ListStore(str) representation_model.append(["Even spacing"]) representation_model.append(["Dynamic spacing"]) representation_box = self.builder.get_object("input_representation") representation_box.set_model(representation_model) cell = gtk.CellRendererText() representation_box.pack_start(cell) representation_box.add_attribute(cell, "text", 0) representation_box.set_active(0) # init graphs self.fig_best = Figure(figsize=(400, 400)) self.fig_hist = Figure(figsize=(400, 200)) self.canvas_best = FigureCanvasGTK(self.fig_best) self.canvas_hist = FigureCanvasGTK(self.fig_hist) self.canvas_best.show() self.canvas_hist.show() self.hbox_best = self.builder.get_object("hbox_graph_best") self.hbox_hist = self.builder.get_object("hbox_graph_hist") self.hbox_best.pack_start(self.canvas_best, True, True) self.hbox_hist.pack_start(self.canvas_hist, True, True) # show window self.builder.connect_signals(self) window = self.builder.get_object("window_main") window.set_title("Brachistochrone curve") window.show() def on_adjust_Ax_value_changed(self, widget, data=None): config.A[0] = widget.get_value() self.on_update_points() return True def on_adjust_Ay_value_changed(self, widget, data=None): config.A[1] = widget.get_value() self.on_update_points() return True def on_adjust_Bx_value_changed(self, widget, data=None): config.B[0] = widget.get_value() self.on_update_points() return True def on_adjust_By_value_changed(self, widget, data=None): config.B[1] = widget.get_value() self.on_update_points() return True def on_input_population_size_value_changed(self, widget, data=None): config.POPULATION_SIZE = widget.get_value_as_int() return True def on_input_elitism_value_changed(self, widget, data=None): config.ELITISM = widget.get_value() / 100 return True def on_input_selection_type_changed(self, widget, data=None): config.SELECTION_TYPE = widget.get_active_text() return True def on_input_representation_changed(self, widget, data=None): config.REPRESENTATION = widget.get_active_text() return True def on_input_points_value_changed(self, widget, data=None): config.POINTS_INIT = widget.get_value_as_int() return True def on_input_crossover_value_changed(self, widget, data=None): config.CROSSOVER_PROB = widget.get_value() / 100 return True def on_input_crossover_points_value_changed(self, widget, data=None): config.CROSSOVER_POINTS = widget.get_value() return True def on_input_mutation_value_changed(self, widget, data=None): config.MUTATION_PROB = widget.get_value() / 100.0 burst = self.builder.get_object("input_mutation_burst") m = 100 - config.MUTATION_PROB * 100 if burst.get_value() > m: burst.set_value(m) burst.get_adjustment().set_upper(m) return True def on_input_mutation_burst_value_changed(self, widget, data=None): config.MUTATION_BURST = widget.get_value() / 100 return True def on_button_save_clicked(self, widget, data=None): dialog = gtk.FileChooserDialog( "Choose a folder...", None, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK), ) dialog.set_default_response(gtk.RESPONSE_OK) response = dialog.run() if response == gtk.RESPONSE_OK: points = self.best.getPoints() f = open(dialog.get_filename() + "/data", "w") f.write(str(self.iteration_list[-1]) + "\n") f.write(str(self.best_list) + "\n") f.write(str(self.avg_list) + "\n") f.write(str(self.worst_list) + "\n") f.write(str(self.stddev_list) + "\n") f.write(str(points) + "\n") f.write(str(time.time() - self.start) + "\n") f.close() figureBest = figure(figsize=(4.0, 4.0), dpi=72) graphBest = figureBest.add_subplot(111) graphBest.plot(points[0], points[1], "r-*") figureBest.savefig(dialog.get_filename() + "/best.png", format="png", transparent=True) figureHist = figure(figsize=(10.0, 4.0), dpi=72) graphHist = figureHist.add_subplot(111) graphHist.plot( self.iteration_list, self.best_list, "b", self.iteration_list, self.avg_list, "g", self.iteration_list, self.worst_list, "r", ) figureHist.savefig(dialog.get_filename() + "/hist.png", format="png", transparent=True) dialog.destroy() return True def on_button_start_stop_clicked(self, widget, data=None): if not self.running and (config.A[1] <= config.B[1] or config.B[0] <= config.A[0]): md = gtk.MessageDialog( self.builder.get_object("window_main"), gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, "Invalid start/end points!", ) md.run() md.destroy() return True self.running = not self.running if self.running: widget.set_label("STOP") self.best_list = [] self.avg_list = [] self.worst_list = [] self.stddev_list = [] self.iteration_list = [] self.builder.get_object("input_Ax").set_sensitive(False) self.builder.get_object("input_Ay").set_sensitive(False) self.builder.get_object("input_Bx").set_sensitive(False) self.builder.get_object("input_By").set_sensitive(False) self.builder.get_object("input_population_size").set_sensitive(False) self.builder.get_object("input_elitism").set_sensitive(False) self.builder.get_object("input_selection_type").set_sensitive(False) self.builder.get_object("input_representation").set_sensitive(False) self.builder.get_object("input_points").set_sensitive(False) self.builder.get_object("input_crossover").set_sensitive(False) self.builder.get_object("input_crossover_points").set_sensitive(False) self.builder.get_object("input_mutation").set_sensitive(False) self.builder.get_object("input_mutation_burst").set_sensitive(False) self.builder.get_object("button_save").set_sensitive(False) self.population = Population.new(config.POPULATION_SIZE, config.REPRESENTATION) self.start = time.time() self.thread = Thread(target=self.evolve) self.thread.start() else: widget.set_label("START") self.builder.get_object("input_Ax").set_sensitive(True) self.builder.get_object("input_Ay").set_sensitive(True) self.builder.get_object("input_Bx").set_sensitive(True) self.builder.get_object("input_By").set_sensitive(True) self.builder.get_object("input_population_size").set_sensitive(True) self.builder.get_object("input_elitism").set_sensitive(True) self.builder.get_object("input_selection_type").set_sensitive(True) self.builder.get_object("input_representation").set_sensitive(True) self.builder.get_object("input_points").set_sensitive(True) self.builder.get_object("input_crossover").set_sensitive(True) self.builder.get_object("input_crossover_points").set_sensitive(True) self.builder.get_object("input_mutation").set_sensitive(True) self.builder.get_object("input_mutation_burst").set_sensitive(True) self.builder.get_object("button_save").set_sensitive(True) self.lastBest = None return True def on_update_points(self): config.DX = float(config.B[0] - config.A[0]) config.DY = float(config.B[1] - config.A[1]) config.MUTATION_X_STDEV = (config.A[0] - config.B[0]) / 10 # standard deviation config.MUTATION_Y_STDEV = (config.A[1] - config.B[1]) / 10 # standard deviation def on_window_main_destroy(self, widget, data=None): app.running = False if app.thread != None: app.thread.join() sys.exit(0) def evolve(self): i = 0 while self.running: self.population.evolve() stats = self.population.getStatistics() # print "Iteration", i, stats self.best_list.append(stats[0]) self.avg_list.append(stats[1]) self.worst_list.append(stats[2]) self.stddev_list.append(stats[3]) self.iteration_list.append(i) self.best = self.population.getBest() if datetime.now() > self.lastUpdate + timedelta(seconds=2): gobject.idle_add(self.plot) i += 1 def plot(self): self.lastUpdate = datetime.now() points = self.best.getPoints() self.fig_best.clf() self.fig_hist.clf() graph_best = self.fig_best.add_subplot(111) graph_best.plot(points[0], points[1], "r-*") graph_best.axis([0, config.B[0], 0, config.A[1]]) graph_hist = self.fig_hist.add_subplot(111) graph_hist.plot( self.iteration_list[-100:], self.best_list[-100:], "b", self.iteration_list[-100:], self.avg_list[-100:], "g", self.iteration_list[-100:], self.worst_list[-100:], "r", ) graph_hist.axis([max(0, self.iteration_list[-1] - 100), self.iteration_list[-1], 0, 4.0]) self.fig_best.canvas.draw() self.fig_hist.canvas.draw()
import gtk win = gtk.Window() win.set_name("Embedding in GTK") win.connect("destroy", gtk.mainquit) win.set_border_width(5) vbox = gtk.VBox(spacing=3) win.add(vbox) vbox.show() f = Figure(figsize=(5,4), dpi=100) a = Subplot(f, 111) t = arange(0.0,3.0,0.01) s = sin(2*pi*t) a.plot(t,s) f.add_axis(a) canvas = FigureCanvasGTK(f) # a gtk.DrawingArea canvas.show() vbox.pack_start(canvas) button = gtk.Button('Quit') button.connect('clicked', lambda b: gtk.mainquit()) button.show() vbox.pack_start(button) win.show() gtk.mainloop()
class GuiSessionViewer: def __init__(self, config, querylist, mainwin, owner, debug=True): self.debug = debug self.conf = config self.sql = querylist self.window = mainwin self.owner = owner self.liststore = None self.MYSQL_INNODB = 2 self.PGSQL = 3 self.SQLITE = 4 self.fig = None self.canvas = None self.ax = None self.graphBox = None # create new db connection to avoid conflicts with other threads self.db = Database.Database(self.conf, sql=self.sql) self.cursor = self.db.cursor settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) settings.update(self.conf.get_default_paths()) # text used on screen stored here so that it can be configured self.filterText = {'handhead':_('Hand Breakdown for all levels listed above')} filters_display = { "Heroes" : True, "Sites" : True, "Games" : True, "Currencies": True, "Limits" : True, "LimitSep" : True, "LimitType" : True, "Type" : False, "Seats" : True, "SeatSep" : False, "Dates" : True, "Groups" : False, "GroupsAll" : False, "Button1" : True, "Button2" : False } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name("_Refresh") self.filters.registerButton1Callback(self.refreshStats) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting self.columns = [ (1.0, "SID" ) , (1.0, "Hands" ) , (0.5, "Start" ) , (0.5, "End" ) , (1.0, "Rate" ) , (1.0, "Open" ) , (1.0, "Close" ) , (1.0, "Low" ) , (1.0, "High" ) , (1.0, "Range" ) , (1.0, "Profit") ] self.detailFilters = [] # the data used to enhance the sql select self.main_hbox = gtk.HPaned() self.stats_frame = gtk.Frame() self.stats_frame.show() main_vbox = gtk.VPaned() main_vbox.show() self.graphBox = gtk.VBox(False, 0) self.graphBox.set_size_request(400,400) self.graphBox.show() self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.main_hbox.pack1(self.filters.get_vbox()) self.main_hbox.pack2(main_vbox) main_vbox.pack1(self.graphBox) main_vbox.pack2(self.stats_frame) self.main_hbox.show() # make sure Hand column is not displayed #[x for x in self.columns if x[0] == 'hand'][0][1] = False # if DEBUG == False: # warning_string = _("Session Viewer is proof of concept code only, and contains many bugs.\n") # warning_string += _("Feel free to use the viewer, but there is no guarantee that the data is accurate.\n") # warning_string += _("If you are interested in developing the code further please contact us via the usual channels.\n") # warning_string += _("Thank you") # self.warning_box(warning_string) def warning_box(self, str, diatitle=_("FPDB WARNING")): diaWarning = gtk.Dialog(title=diatitle, parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) label = gtk.Label(str) diaWarning.vbox.add(label) label.show() response = diaWarning.run() diaWarning.destroy() return response def get_vbox(self): """returns the vbox of this thread""" return self.main_hbox def refreshStats(self, widget, data): try: self.stats_vbox.destroy() except AttributeError: pass self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) def fillStatsFrame(self, vbox): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() games = self.filters.getGames() currencies = self.filters.getCurrencies() limits = self.filters.getLimits() seats = self.filters.getSeats() sitenos = [] playerids = [] for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(result) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not games: print _("No games found") return if not currencies: print _("No currencies found") return if not playerids: print _("No player ids found") return if not limits: print _("No limits found") return self.createStatsPane(vbox, playerids, sitenos, games, currencies, limits, seats) def createStatsPane(self, vbox, playerids, sitenos, games, currencies, limits, seats): starttime = time() (results, quotes) = self.generateDatasets(playerids, sitenos, games, currencies, limits, seats) if DEBUG: for x in quotes: print "start %s\tend %s \thigh %s\tlow %s" % (x[1], x[2], x[3], x[4]) self.generateGraph(quotes) heading = gtk.Label(self.filterText['handhead']) heading.show() vbox.pack_start(heading, expand=False, padding=3) # Scrolled window for detailed table (display by hand) swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.show() vbox.pack_start(swin, expand=True, padding=3) vbox1 = gtk.VBox(False, 0) vbox1.show() swin.add_with_viewport(vbox1) self.addTable(vbox1, results) self.db.rollback() print _("Stats page displayed in %4.2f seconds") % (time() - starttime) #end def fillStatsFrame(self, vbox): def generateDatasets(self, playerids, sitenos, games, currencies, limits, seats): if (DEBUG): print "DEBUG: Starting generateDatasets" THRESHOLD = 1800 # Min # of secs between consecutive hands before being considered a new session PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc # Get a list of timestamps and profits q = self.sql.query['sessionStats'] start_date, end_date = self.filters.getDates() q = q.replace("<datestest>", " BETWEEN '" + start_date + "' AND '" + end_date + "'") l = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: l.append(n) if len(l) > 0: gametest = str(tuple(l)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)",")") gametest = gametest.replace("u'","'") gametest = "AND gt.category in %s" % gametest else: gametest = "AND gt.category IS NULL" q = q.replace("<game_test>", gametest) limittest = self.filters.get_limits_where_clause(limits) q = q.replace("<limit_test>", limittest) l = [] for n in currencies: if currencies[n]: l.append(n) currencytest = str(tuple(l)) currencytest = currencytest.replace(",)",")") currencytest = currencytest.replace("u'","'") currencytest = "AND gt.currency in %s" % currencytest q = q.replace("<currency_test>", currencytest) if seats: q = q.replace('<seats_test>', 'AND h.seats BETWEEN ' + str(seats['from']) + ' AND ' + str(seats['to'])) else: q = q.replace('<seats_test>', 'AND h.seats BETWEEN 0 AND 100') nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)",")") q = q.replace("<player_test>", nametest) q = q.replace("<ampersand_s>", "%s") if DEBUG: hands = [ ( u'10000', 10), ( u'10000', 20), ( u'10000', 30), ( u'20000', -10), ( u'20000', -20), ( u'20000', -30), ( u'30000', 40), ( u'40000', 0), ( u'50000', -40), ( u'60000', 10), ( u'60000', 30), ( u'60000', -20), ( u'70000', -20), ( u'70000', 10), ( u'70000', 30), ( u'80000', -10), ( u'80000', -30), ( u'80000', 20), ( u'90000', 20), ( u'90000', -10), ( u'90000', -30), (u'100000', 30), (u'100000', -50), (u'100000', 30), (u'110000', -20), (u'110000', 50), (u'110000', -20), (u'120000', -30), (u'120000', 50), (u'120000', -30), (u'130000', 20), (u'130000', -50), (u'130000', 20), (u'140000', 40), (u'140000', -40), (u'150000', -40), (u'150000', 40), (u'160000', -40), (u'160000', 80), (u'160000', -40), ] else: self.db.cursor.execute(q) hands = self.db.cursor.fetchall() #fixme - nasty hack to ensure that the hands.insert() works # for mysql data. mysql returns tuples which can't be inserted # into so convert explicity to list. hands = list(hands) if (not hands): return ([], []) hands.insert(0, (hands[0][0], 0)) # Take that list and create an array of the time between hands times = map(lambda x:long(x[0]), hands) profits = map(lambda x:float(x[1]), hands) #print "DEBUG: times : %s" % times #print "DEBUG: profits: %s" % profits #print "DEBUG: len(times) %s" %(len(times)) diffs = diff(times) # This array is the difference in starttime between consecutive hands diffs2 = append(diffs,THRESHOLD + 1) # Append an additional session to the end of the diffs, so the next line # includes an index into the last 'session' index = nonzero(diffs2 > THRESHOLD) # This array represents the indexes into 'times' for start/end times of sessions # times[index[0][0]] is the end of the first session, #print "DEBUG: len(index[0]) %s" %(len(index[0])) if len(index[0]) > 0: #print "DEBUG: index[0][0] %s" %(index[0][0]) #print "DEBUG: index %s" %(index) pass else: index = [[0]] #print "DEBUG: index %s" %(index) #print "DEBUG: index[0][0] %s" %(index[0][0]) pass first_idx = 1 quotes = [] results = [] cum_sum = cumsum(profits) / 100 sid = 1 total_hands = 0 total_time = 0 global_open = None global_lwm = None global_hwm = None self.times = [] # Take all results and format them into a list for feeding into gui model. #print "DEBUG: range(len(index[0]): %s" % range(len(index[0])) for i in range(len(index[0])): last_idx = index[0][i] hds = last_idx - first_idx + 1 # Number of hands in session if hds > 0: stime = strftime("%d/%m/%Y %H:%M", localtime(times[first_idx])) # Formatted start time etime = strftime("%d/%m/%Y %H:%M", localtime(times[last_idx])) # Formatted end time self.times.append((times[first_idx], times[last_idx])) minutesplayed = (times[last_idx] - times[first_idx])/60 minutesplayed = minutesplayed + PADDING if minutesplayed == 0: minutesplayed = 1 hph = hds*60/minutesplayed # Hands per hour end_idx = last_idx+1 won = sum(profits[first_idx:end_idx])/100.0 #print "DEBUG: profits[%s:%s]: %s" % (first_idx, end_idx, profits[first_idx:end_idx]) hwm = max(cum_sum[first_idx-1:end_idx]) # include the opening balance, lwm = min(cum_sum[first_idx-1:end_idx]) # before we win/lose first hand open = (sum(profits[:first_idx]))/100 close = (sum(profits[:end_idx]))/100 #print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, end_idx, lwm, hwm, open, close) total_hands = total_hands + hds total_time = total_time + minutesplayed if (global_lwm == None or global_lwm > lwm): global_lwm = lwm if (global_hwm == None or global_hwm < hwm): global_hwm = hwm if (global_open == None): global_open = open global_stime = stime results.append([sid, hds, stime, etime, hph, "%.2f" % open, "%.2f" % close, "%.2f" % lwm, "%.2f" % hwm, "%.2f" % (hwm - lwm), "%.2f" % won]) quotes.append((sid, open, close, hwm, lwm)) #print "DEBUG: Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won) first_idx = end_idx sid = sid+1 else: print "hds <= 0" global_close = close global_etime = etime results.append([''] * 11) results.append([_("all"), total_hands, global_stime, global_etime, total_hands * 60 / total_time, "%.2f" % global_open, "%.2f" % global_close, "%.2f" % global_lwm, "%.2f" % global_hwm, "%.2f" % (global_hwm - global_lwm), "%.2f" % (global_close - global_open)]) return (results, quotes) def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig is not None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("Error:")+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) raise def generateGraph(self, quotes): self.clearGraphData() #print "DEBUG:" #print "\tquotes = %s" % quotes #for i in range(len(highs)): # print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i]) # print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i]) self.ax = self.fig.add_subplot(111) self.ax.set_title(_("Session candlestick graph")) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Sessions"), fontsize = 12) self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) candlestick(self.ax, quotes, width=0.50, colordown='r', colorup='g', alpha=1.00) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() def addTable(self, vbox, results): row = 0 sqlrow = 0 colxalign,colheading = range(2) self.liststore = gtk.ListStore(*([str] * len(self.columns))) for row in results: iter = self.liststore.append(row) view = gtk.TreeView(model=self.liststore) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) vbox.add(view) print view.connect("row-activated", self.row_activated) cell05 = gtk.CellRendererText() cell05.set_property('xalign', 0.5) cell10 = gtk.CellRendererText() cell10.set_property('xalign', 1.0) listcols = [] # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(self.columns): treeviewcolumn = gtk.TreeViewColumn(column[colheading]) listcols.append(treeviewcolumn) treeviewcolumn.set_alignment(column[colxalign]) view.append_column(listcols[col]) if (column[colxalign] == 0.5): cell = cell05 else: cell = cell10 listcols[col].pack_start(cell, expand=True) listcols[col].add_attribute(cell, 'text', col) listcols[col].set_expand(True) vbox.show_all() def row_activated(self, view, path, column): if path[0] < len(self.times): replayer = None for tabobject in self.owner.threads: if isinstance(tabobject, GuiHandViewer.GuiHandViewer): replayer = tabobject self.owner.tab_hand_viewer(None) break if replayer is None: self.owner.tab_hand_viewer(None) for tabobject in self.owner.threads: if isinstance(tabobject, GuiHandViewer.GuiHandViewer): replayer = tabobject break # added the timezone offset ('+00:00') to make the db query work. Otherwise the hands # at the edges of the date range are not included. A better solution may be possible. # Optionally the end date in the call below, which is a Long gets a '+1'. reformat = lambda t: strftime("%Y-%m-%d %H:%M:%S+00:00", gmtime(t)) handids = replayer.get_hand_ids_from_date_range(reformat(self.times[path[0]][0]), reformat(self.times[path[0]][1]), save_date = True) replayer.reload_hands(handids)
class GuiApp(object): def __init__(self): global unit self.filename=None self.gladefile="/usr/share/freeceilo-%s/ceilo.glade" % VERSION self.wTree=gtk.glade.XML(self.gladefile) self.window=self.wTree.get_widget("FreeCeilo") self.window.maximize() self.threadvar=0 #--------buttons---------# self.Open=self.wTree.get_widget("Open") #-----cloud detection plotting button------# self.first_cld_plot_button=self.wTree.get_widget("first_cld_plot_button") self.second_cld_plot_button=self.wTree.get_widget("second_cld_plot_button") self.third_cld_plot_button=self.wTree.get_widget("third_cld_plot_button") self.cld_det_clear_button=self.wTree.get_widget("cld_det_clear_button") self.cld_det_save_button=self.wTree.get_widget("cld_det_save_button") #------------ gnuplot buttons -------------# self.gnu_plot_button=self.wTree.get_widget("gnu_plot_button") self.gnuplot_zoom_in_button=self.wTree.get_widget("gnuplot_zoom_in_button") self.gnuplot_zoom_normal_button=self.wTree.get_widget("gnuplot_zoom_normal_button") self.gnuplot_zoom_out_button=self.wTree.get_widget("gnuplot_zoom_out_button") self.gnuplot_save_button=self.wTree.get_widget("gnuplot_save_button") #--------buttons ends---------# #------progressbars------# self.progressbar1=self.wTree.get_widget("progressbar1") self.progressbar2=self.wTree.get_widget("progressbar2") self.progressbar1.set_fraction(0.0) self.datpbar=0 self.progressbar2.set_fraction(0.0) self.gnupbar=0 self.timer = gobject.timeout_add (100, progress_timeout, self) #------gnu plot image normal size ----# self.imagex= 810 self.imagey=540 self.gnuplot_image=self.wTree.get_widget("gnuplot_image") self.x=0 #--------Handles events dic={"on_FreeCeilo_destroy":self.quitprogram,"on_Open_activate":self.openfile, "on_first_cld_plot_button_clicked":self.firstcloudshow,"on_second_cld_plot_button_clicked" :self.secondcloudshow,"on_third_cld_plot_button_clicked":self.thirdcloudshow, "on_zoom_in_x_activate":self.clouddetectzoominx,"on_zoom_out_x_activate": self.clouddetectzoomoutx,"on_zoom_in_y_activate":self.clouddetectzoominy, "on_zoom_out_y_activate":self.clouddetectzoomouty,"on_cld_det_save_button_clicked" :self.clouddetectsave,"on_cld_det_clear_button_clicked":self.clouddetectgraphclear, "on_gnu_plot_button_clicked":self.gnuplotshow,"on_gnuplot_zoom_in_button_clicked": self.gnuplotzoomin,"on_gnuplot_zoom_normal_button_clicked":self.gnuplotzoomnormal, "on_gnuplot_zoom_out_button_clicked":self.gnuplotzoomout,"on_gnuplot_save_button_clicked" :self.gnuplotsave} self.wTree.signal_autoconnect(dic) #-----plotting area for graphs self.graphview = self.wTree.get_widget("hbox7") #-----plotting area for cloud detection graph self.figure1 = Figure(figsize=(12,6),facecolor='y',dpi=55,edgecolor='black',linewidth=5.0) self.axis1 = self.figure1.add_subplot(111) self.axis1.grid(True) self.canvas1 = FigureCanvasGTK(self.figure1) self.graphview.pack_start(self.canvas1,True,True) self.canvas1.show() self.axis1.set_autoscale_on(True) #-----plotting area for back scatterprofile self.figure2 = Figure(figsize=(12,6),facecolor='y', dpi=55,edgecolor='black',linewidth=4.0) self.axis2 = self.figure2.add_subplot(111) self.axis2.grid(True) self.canvas2 = FigureCanvasGTK(self.figure2) self.graphview.pack_end(self.canvas2,True,True) self.canvas2.show() ################################# File Openning and dataprocessing ####################### def openfile(self,obj): self.filename=None if(self.threadvar==1): os.system("killall -9 gnuplot > /dev/zero") self.datpbar=0 self.gnupbar=0 self.datadecode_thread_obj.stop() dialog = gtk.FileChooserDialog("Open..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("DATA FILES") filter.add_pattern("*.dat") dialog.add_filter(filter) response=dialog.run() if response == gtk.RESPONSE_OK: self.filename=dialog.get_filename() self.window.set_title("Free Ceilo 0.1 ( "+self.filename+")") self.datpbar=1 self.gnupbar=1 #---- Threads for datadecoding ,gnuplot ---# cond=Condition() self.datadecode_thread_obj=datadecodethreadlib.DataDecodeThread(cond,self.filename) self.datadecode_thread_obj.start() self.threadvar=1 #---- Threads ends ------# elif response == gtk.RESPONSE_CANCEL: print 'Closed, no files selected' dialog.destroy() ###############################Cloud Detection Graph Plotting ####################### ##### Show the first cloud ###### def firstcloudshow(self,obj): self.x= getstatusobj.getdataobj() self.axis1.set_xlabel('Time') self.axis1.set_ylabel('Altitude'+","+unit) self.axis1.set_title('Cloud Detection Graph') self.axis1.grid(True) self.axis1.plot_date(self.x.lwst_time_index,self.x.lwst_cldbse_hgt,'b.',label=" First") self.axis1.xaxis.set_major_locator(MaxNLocator(6)) ####-------for rotating the xticks------------------########### #labels = self.axis1.get_xticklabels() #setp(labels, rotation=90, fontsize=10) self.axis1.legend() self.canvas1.draw() ##### Show the second cloud ###### def secondcloudshow(self,obj): self.x= getstatusobj.getdataobj() self.axis1.set_xlabel('Time') self.axis1.set_ylabel('Altitude'+","+unit) self.axis1.set_title('Cloud Detection Graph') self.axis1.grid(True) self.axis1.plot_date(self.x.sec_time_index,self.x.sec_lwst_cldbse_hgt,'g.',label="Second") self.axis1.xaxis.set_major_locator(MaxNLocator(6)) self.axis1.legend() self.canvas1.draw() ##### Show the third cloud ###### def thirdcloudshow(self,obj): self.x= getstatusobj.getdataobj() self.axis1.set_xlabel('Time') self.axis1.set_ylabel('Altitude'+","+unit) self.axis1.set_title('Cloud Detection Graph') self.axis1.grid(True) self.axis1.plot_date(self.x.higst_time_index,self.x.higst_cldbse_hgt,'r.',label="Third") self.axis1.xaxis.set_major_locator(MaxNLocator(6)) self.axis1.legend() self.canvas1.draw() ####---------Zooming the figure--------######## def clouddetectzoominx(self,obj): self.axis1.zoomx(2) self.canvas1.draw() def clouddetectzoomoutx(self,obj): self.axis1.zoomx(-2) self.canvas1.draw() def clouddetectzoominy(self,obj): self.axis1.zoomy(2) self.canvas1.draw() def clouddetectzoomouty(self,obj): self.axis1.zoomy(-2) self.canvas1.draw() def clouddetectgraphclear(self,obj): self.axis1.clear() self.axis1.set_xlabel('Time') self.axis1.set_ylabel('Altitude'+","+unit) self.axis1.set_title('Cloud Detection Graph') self.axis1.grid(True) self.canvas1.draw() #############SAVE CLD DETECT######### def clouddetectsave(self,obj): dialog= gtk.FileChooserDialog("Save Cloud Detection Graph ", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) dialog.set_current_folder(os.curdir) dialog.set_do_overwrite_confirmation(True) filter = gtk.FileFilter() filter.set_name("image(png) file") filter.add_pattern("*.png") dialog.add_filter(filter) response=dialog.run() if response == gtk.RESPONSE_OK: plotimagefile=dialog.get_filename() dialog.destroy() #self.canvas1.print_figure1(plotimagefile, 72,'w', 'w','portrait') self.figure1.savefig(plotimagefile) self.canvas1.destroy() self.canvas1 = FigureCanvasGTK(self.figure1) self.graphview.pack_start(self.canvas1, True,True) self.canvas1.show() elif response == gtk.RESPONSE_CANCEL: print "no file is selected" dialog.destroy() self.canvas1.show() ##########################################GNUPLOT#################################### #--------- The Functions to display Gnuplot image and zoom the images and save------# def gnuplotshow(self,obj): self.gnuplot_image.set_from_file("/tmp/FreeCeilo/.gnu.png") #----Functions to zoom the images----# def gnuplotzoomin(self,obj): self.imagex+=30 self.imagey+=20 self.gnuplotzoom() def gnuplotzoomout(self,obj): self.imagex-=30 self.imagey-=20 self.gnuplotzoom() def gnuplotzoomnormal(self,obj): self.imagex=810 self.imagey=540 self.gnuplotzoom() def gnuplotzoom(self): self.gnuplot_image.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file("/tmp/FreeCeilo/.gnu.png").scale_simple(self.imagex,self.imagey,gtk.gdk.INTERP_BILINEAR)) #---Function to save the gnuplot image in another location using save as option---# def gnuplotsave(self,obj): dialog= gtk.FileChooserDialog("Save as..", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) dialog.set_do_overwrite_confirmation(True) filter = gtk.FileFilter() filter.set_name("image(png) file") filter.add_pattern("*.png") dialog.add_filter(filter) response=dialog.run() if response == gtk.RESPONSE_OK: plotimagefile=dialog.get_filename() if not plotimagefile.endswith(".png"): k=plotimagefile.find(".") plotimagefile=plotimagefile[0:k] plotimagefile=plotimagefile.__add__(".png") shutil.copyfile("/tmp/FreeCeilo/.gnu.png",plotimagefile) elif response == gtk.RESPONSE_CANCEL: print "no file is selected" dialog.destroy() ################################# Quit the Program ######################### def quitprogram(self,obj): self.id1=os.getpid() gobject.source_remove(self.timer) self.timer = 0 gtk.main_quit() os.system("killall -9 gnuplot > /dev/zero") os.popen("kill -9 "+str(self.id1)) sys.exit(0)
class mainGUI: #==================== #constructor #==================== def __init__(self): # Create main window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("Dan's crazy gene regulation simulator") self.window.set_border_width(2) self.window.connect("delete_event",self.close) #window size values self.x_size = 640 self.y_size = 480 self.design_Window_Fraction_x = 1.0 self.design_Window_Fraction_y = 0.5 self.button_Window_Fraction_x = 0.1 self.button_Window_Fraction_y = 0.5 self.plot_Window_Fraction_x = 0.9 self.plot_Window_Fraction_y = 0.5 #divide up the window self.main_Box = gtk.VBox(False,0) self.window.add(self.main_Box) #Setup circuit design area self.setup_Design_Area(self.main_Box) self.sub_Box = gtk.HBox(False,0) self.main_Box.pack_start(self.sub_Box,True,True,0) #Setup buttons self.setup_Buttons(self.sub_Box) self.setup_Plots(self.sub_Box) self.sub_Box.show_all() self.main_Box.show_all() self.window.show_all() #==================== #Init helpers #==================== def setup_Design_Area(self,box): self.design_Area = gtk.Fixed() self.design_Area.set_size_request(int(self.design_Window_Fraction_x*self.x_size), int(self.design_Window_Fraction_y*self.y_size)) self.design_Area.set_has_window(True) box.pack_start(self.design_Area,True,True,0) self.design_Area.show() self.gene_Collection = Gene_Collection(self.design_Area) self.design_Area.connect("button-press-event",self.create_Object,"") def setup_Buttons(self,box): self.button_Box = gtk.VBox(False,0) self.button_Clear = gtk.Button("Clear") self.button_Clear.connect("clicked",self.clear,"") self.button_Clear.show() self.button_Box.pack_start(self.button_Clear,True,True,0) self.button_Go = gtk.Button("Go") self.button_Go.connect("clicked",self.runSim,"") self.button_Box.pack_start(self.button_Go,True,True,0) self.button_Go.show() self.button_Quit = gtk.Button("Quit") self.button_Quit.connect("clicked",self.close,"") self.button_Box.pack_start(self.button_Quit,True,True,0) self.button_Quit.show() self.button_Box.show() box.add(self.button_Box) def setup_Plots(self,box): self.plot_Figure = Figure(figsize=(5,4), dpi=72) self.plot = self.plot_Figure.add_subplot(111) self.plot.plot(0,0,'-') self.plot_Canvas = FigureCanvas(self.plot_Figure) self.plot_Canvas.set_size_request(int(self.plot_Window_Fraction_x*self.x_size), int(self.plot_Window_Fraction_y*self.y_size)) self.plot_Canvas.show() box.add(self.plot_Canvas) #==================== #Call backs #==================== def close(self, widget, event, data=None): gtk.main_quit() return False def clear(self, widget, event, data=None): print "clear" def runSim(self, widget, event, data=None): print "sim" if(self.gene_Collection.Build_Simulation()): self.gene_Collection.Run_Simulation() else: print "error building simulation" def create_Object(self, widget, event, data=None): if(event.button == 1): if(event.type == gtk.gdk._2BUTTON_PRESS): self.gene_Collection.Add_New(event)
win.connect("destroy", gtk.mainquit) win.set_border_width(5) vbox = gtk.VBox(spacing=3) vbox.show() win.add(vbox) fig = Figure(figsize=(5, 4), dpi=100) ax = fig.add_subplot(111) t = arange(0.0, 3.0, 0.01) s = sin(2 * pi * t) ax.plot(t, s) canvas = FigureCanvas(fig) # a gtk.DrawingArea canvas.show() vbox.pack_start(canvas) toolbar = NavigationToolbar(canvas) toolbar.show() vbox.pack_start(toolbar, gtk.FALSE, gtk.FALSE) #buttonQuit = gtk.Button('Quit') #buttonQuit.connect('clicked', gtk.mainquit) #buttonQuit.show() #vbox.pack_start(buttonQuit) if __name__ == '__main__': win.show() # gtk.mainloop() gtk.main()
class GuiGraphViewer(threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent # print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes": True, "Sites": True, "Games": True, "Currencies": True, "Limits": True, "LimitSep": True, "LimitType": True, "Type": False, "UseType": "ring", "Seats": False, "SeatSep": False, "Dates": True, "GraphOps": True, "Groups": False, "Button1": True, "Button2": True, } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None # self.exportButton.set_sensitive(False) self.canvas = None self.exportFile = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox # end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() games = self.filters.getGames() currencies = self.filters.getCurrencies() graphops = self.filters.getGraphOps() names = "" for i in ("show", "none"): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) names = names + "\n" + _hname + " on " + site if not sitenos: # Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return if not limits: print _("No limits found") self.db.rollback() return # Set graph properties self.ax = self.fig.add_subplot(111) # Get graph data from DB starttime = time() (green, blue, red, orange) = self.getRingProfitGraph( playerids, sitenos, limits, games, currencies, graphops["dspin"] ) print _("Graph generated in: %s") % (time() - starttime) # Set axis labels and grid overlay properites self.ax.set_xlabel(_("Hands")) # SET LABEL FOR X AXIS self.ax.set_ylabel(graphops["dspin"]) self.ax.grid(color="g", linestyle=":", linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = [ 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 500.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 875.0, 750.0, 625.0, 500.0, 375.0, 250.0, 125.0, 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 500.0, 1000.0, 1000.0, ] red = [ 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 125.0, 250.0, 375.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 375.0, 250.0, 125.0, 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 500.0, 1000.0, 1000.0, ] blue = [ 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 125.0, 250.0, 375.0, 500.0, 625.0, 750.0, 875.0, 1000.0, 875.0, 750.0, 625.0, 500.0, 375.0, 250.0, 125.0, 0.0, 0.0, 0.0, 0.0, 500.0, 1000.0, 900.0, 800.0, 700.0, 600.0, 500.0, 400.0, 300.0, 200.0, 100.0, 0.0, 500.0, 1000.0, 1000.0, ] self.ax.plot( green, color="green", label=_("Hands") + ": %d\n" % len(green) + _("Profit") + ": %.2f" % green[-1] ) self.ax.plot(blue, color="blue", label=_("Showdown") + ": $%.2f" % (blue[-1])) self.ax.plot(red, color="red", label=_("Non-showdown") + ": $%.2f" % (red[-1])) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() else: self.ax.set_title((_("Profit graph for ring games") + names)) # Draw plot if graphops["showdown"] == "ON": self.ax.plot(blue, color="blue", label=_("Showdown") + " (%s): %.2f" % (graphops["dspin"], blue[-1])) if graphops["nonshowdown"] == "ON": self.ax.plot(red, color="red", label=_("Non-showdown") + " (%s): %.2f" % (graphops["dspin"], red[-1])) if graphops["ev"] == "ON": self.ax.plot( orange, color="orange", label=_("All-in EV") + " (%s): %.2f" % (graphops["dspin"], orange[-1]) ) self.ax.plot( green, color="green", label=_("Hands") + ": %d\n" % len(green) + _("Profit") + ": (%s): %.2f" % (graphops["dspin"], green[-1]), ) # order legend, greenline on top handles, labels = self.ax.get_legend_handles_labels() handles = handles[-1:] + handles[:-1] labels = labels[-1:] + labels[:-1] legend = self.ax.legend( handles, labels, loc="upper left", fancybox=True, shadow=True, prop=FontProperties(size="smaller") ) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() # self.exportButton.set_sensitive(True) # end of def showClicked def getRingProfitGraph(self, names, sites, limits, games, currencies, units): # tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" if units == "$": tmp = self.sql.query["getRingProfitAllHandsPlayerIdSiteInDollars"] elif units == "BB": tmp = self.sql.query["getRingProfitAllHandsPlayerIdSiteInBB"] start_date, end_date = self.filters.getDates() # Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) # nametest = nametest.replace("L", "") q = [] for m in self.filters.display.items(): if m[0] == "Games" and m[1]: for n in games: if games[n]: q.append(n) if len(q) > 0: gametest = str(tuple(q)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)", ")") gametest = gametest.replace("u'", "'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" tmp = tmp.replace("<game_test>", gametest) limittest = self.filters.get_limits_where_clause(limits) q = [] for n in currencies: if currencies[n]: q.append(n) currencytest = str(tuple(q)) currencytest = currencytest.replace(",)", ")") currencytest = currencytest.replace("u'", "'") currencytest = "AND gt.currency in %s" % currencytest if type == "ring": limittest = limittest + " and gt.type = 'ring' " elif type == "tour": limittest = limittest + " and gt.type = 'tour' " # Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace("<limit_test>", limittest) tmp = tmp.replace("<currency_test>", currencytest) tmp = tmp.replace(",)", ")") # print "DEBUG: sql query:" # print tmp self.db.cursor.execute(tmp) # returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None, None) green = map(lambda x: float(x[1]), winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) orange = map(lambda x: float(x[3]), winnings) greenline = cumsum(green) blueline = cumsum(blue) redline = cumsum(red) orangeline = cumsum(orange) return (greenline / 100, blueline / 100, redline / 100, orangeline / 100) # end of def getRingProfitGraph def exportGraph(self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. png_filter = gtk.FileFilter() png_filter.add_pattern("*.png") dia_chooser = gtk.FileChooserDialog( title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK), ) dia_chooser.set_filter(png_filter) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) if self.exportFile is not None: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default else: dia_chooser.set_current_name("fpdbgraph.png") response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _("Closed, no graph exported") dia_chooser.destroy() return self.exportFile = dia_chooser.get_filename() dia_chooser.destroy() self.fig.savefig(self.exportFile, format="png") # Display info box to confirm graph created. diainfo = gtk.MessageDialog( parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created"), ) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class GuiGraphViewer (threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes" : True, "Sites" : True, "Games" : True, "Limits" : True, "LimitSep" : True, "LimitType" : True, "Type" : False, "UseType" : 'ring', "Seats" : False, "SeatSep" : False, "Dates" : True, "GraphOps" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("Error:")+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) raise def generateGraph(self, widget, data): try: self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() games = self.filters.getGames() graphops = self.filters.getGraphOps() names = "" for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) names = names + "\n"+_hname + " on "+site if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return if not limits: print _("No limits found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, blue, red) = self.getRingProfitGraph(playerids, sitenos, limits, games, graphops['dspin']) print _("Graph generated in: %s") %(time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Hands"), fontsize = 12) # SET LABEL FOR X AXIS self.ax.set_ylabel(graphops['dspin'], fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label=_('Hands: %d\nProfit: (%s): %.2f') %(len(green), green[-1])) self.ax.plot(blue, color='blue', label=_('Showdown') + ': $%.2f' %(blue[-1])) self.ax.plot(red, color='red', label=_('Non-showdown') + ': $%.2f' %(red[-1])) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user #print "No hands returned by graph query" else: self.ax.set_title((_("Profit graph for ring games")+names),fontsize=12) #Draw plot self.ax.plot(green, color='green', label=_('Hands: %d\nProfit: (%s): %.2f') %(len(green),graphops['dspin'], green[-1])) if graphops['showdown'] == 'ON': self.ax.plot(blue, color='blue', label=_('Showdown') + ' (%s): %.2f' %(graphops['dspin'], blue[-1])) if graphops['nonshowdown'] == 'ON': self.ax.plot(red, color='red', label=_('Non-showdown') + ' (%s): %.2f' %(graphops['dspin'], red[-1])) if sys.version[0:3] == '2.5': self.ax.legend(loc='upper left', shadow=True, prop=FontProperties(size='smaller')) else: self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("Error:")+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) #end of def showClicked def getRingProfitGraph(self, names, sites, limits, games, units): # tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" if units == '$': tmp = self.sql.query['getRingProfitAllHandsPlayerIdSiteInDollars'] elif units == 'BB': tmp = self.sql.query['getRingProfitAllHandsPlayerIdSiteInBB'] start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #nametest = nametest.replace("L", "") q = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: q.append(n) if len(q) > 0: gametest = str(tuple(q)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)",")") gametest = gametest.replace("u'","'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" tmp = tmp.replace("<game_test>", gametest) lims = [int(x) for x in limits if x.isdigit()] potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl'] nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl'] capnolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'cn'] limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in " # and ( (limit and bb in()) or (nolimit and bb in ()) ) if lims: blindtest = str(tuple(lims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'pl' and gt.bigBlind in " if potlims: blindtest = str(tuple(potlims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in " if nolims: blindtest = str(tuple(nolims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'cn' and gt.bigBlind in " if capnolims: blindtest = str(tuple(capnolims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) )' else: limittest = limittest + '(-1) ) )' if type == 'ring': limittest = limittest + " and gt.type = 'ring' " elif type == 'tour': limittest = limittest + " and gt.type = 'tour' " #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace("<limit_test>", limittest) tmp = tmp.replace(",)", ")") #print "DEBUG: sql query:" #print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None, None) green = map(lambda x:float(x[1]), winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) blueline = cumsum(blue) redline = cumsum(red) return (greenline/100, blueline/100, redline/100) #end of def getRingProfitGraph def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename() + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class GuiTourneyGraphViewer(threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes": True, "Sites": True, "Games": False, "Limits": False, "LimitSep": False, "LimitType": False, "Type": False, "UseType": 'tour', "Seats": False, "SeatSep": False, "Dates": True, "Groups": False, "Button1": True, "Button2": True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() green = self.getData(playerids, sitenos) print _("Graph generated in: %s") % (time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Tournaments"), fontsize=12) self.ax.set_ylabel("$", fontsize=12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + ': $%.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Tournament Results")) #Draw plot self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + ': $%.2f' % green[-1]) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) #end of def showClicked def getData(self, names, sites): tmp = self.sql.query['tourneyResults'] print "DEBUG: getData" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") print "DEBUG: sql query:" print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return None green = map(lambda x: float(x[1]), winnings) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) return (greenline / 100) def exportGraph(self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog( title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename( self.exportFile ) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename( ) + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
def get_analysis(self, center=None, radius=None): if radius is None: self.selection_circ.set_radius(0) #EMPTYING self.plots_vbox #for child in self.plots_vbox2.get_children(): # self.plots_vbox2.remove(child) img_transf = self.get_kodak_image() if img_transf is None: return None x_factor = img_transf.shape[0] / 200 y_factor = img_transf.shape[1] / 200 if x_factor > y_factor: scale_factor = x_factor else: scale_factor = y_factor if scale_factor == 0: scale_factor = 1 # # BLOB SELECTION CANVAS # image_size = (img_transf.shape[1]/scale_factor, img_transf.shape[0]/scale_factor) # # RETRIEVING ANALYSIS # self._cell = colonies.get_grid_cell_from_array(img_transf, center=center, radius = radius) self._cell.kodak_data_source = None self._cell.original_data_source = img_transf.copy() features = self.get_features() self.set_features_in_gui(features) self.DMS("ANALYSE ONE", 'Features: {0}'.format(features), "L", debug_level="debug") # # UPDATE IMAGE SECTION USING CURRENT VALUE SPACE REPRESENTATION # if center is None and radius is None: self.blob_fig_ax.set_data(self._cell.data_source.T) self.blob_fig_ax.set_clim(vmin = 0, vmax=(100,3500)[self.last_value_space]) self.blob_fig.gca().add_patch(self.selection_circ) self.blob_fig.canvas.draw() # # GETTING BLOB AND BACKGROUND # blob = self._cell.get_item('blob') self.blob_filter = blob.filter_array self.blob_image = blob.grid_array background = self._cell.get_item('background') # # CALCULATING CCE IF POLY-COEFFS EXISTS # if self._cce_poly_coeffs is not None: cce_vector = self.get_cce_data_vector(img_section=img_transf) cce_vector = self.get_expanded_vector(cce_vector) cce_calculated = self.get_vector_polynomial_sum_single(cce_vector, self._cce_poly_coeffs) self.cce_calculated.set_text(str(cce_calculated) + " cells in blob") # # BLOB vs BACKGROUND CANVAS # blob_filter_view = self.blob_filter#.astype(float) * 256 + img_transf #blob_filter_view = blob_filter_view * ( 256/ float(np.max(blob_filter_view)) ) self.blob_bool_fig_ax.set_data(blob_filter_view.T) self.blob_bool_fig.canvas.draw() self.bg_bool_fig_ax.set_data(background.filter_array.T) self.bg_bool_fig.canvas.draw() # # HISTOGRAM # blob_hist = blob.histogram if blob_hist.labels != None: bincenters = 0.5*(blob_hist.labels[1:]+blob_hist.labels[:-1]) if self._blobs_have_been_loaded == False: label = gtk.Label("Histogram (Kodak Space):") label.show() self.plots_vbox2.pack_start(label, False, False, 2) self.blob_hist = plt.Figure(figsize=image_size, dpi=150) self.blob_hist.add_axes() image_canvas = FigureCanvas(self.blob_hist) image_plot = self.blob_hist.gca() image_canvas.set_size_request(300,400) image_canvas.show() self.plots_vbox2.pack_start(image_canvas, False, False, 2) #self.blob_hist.subplots_adjust(top=2, bottom=2) label = gtk.Label("Threshold (red), Background Mean(green)") label.show() self.plots_vbox2.pack_start(label, False, False, 2) else: image_plot = self.blob_hist.gca() image_plot.cla() #image_plot.bar(blob_hist.labels, blob_hist.counts, linewidth=0, color='k') image_plot.hist(img_transf.ravel(), bins=150, color='k', alpha=0.6, lw=1) #image_plot.hist(img_transf[np.where(background.filter_array)].ravel(), bins=150, color='k', alpha=0.6, lw=1) x_labels = [t.get_text() for t in image_plot.get_axes().get_xticklabels()] self.DMS('ANALYSE ONE', 'Debugging niceness of plot {0}'.format(\ [str(t) for t in image_plot.get_axes().get_xticklabels()]), "L", debug_level='debug') image_plot.get_axes().set_xticklabels(x_labels, fontsize='xx-small') #if blob_hist.labels != None: image_plot.axvline(np.mean(img_transf[np.where(\ background.filter_array)]), c='g') #x_ticks = range(0,256,20) #image_plot.set_xticks(x_ticks) #image_plot.set_xticklabels(map(str,x_ticks), fontsize='xx-small') image_plot.axvline(blob.threshold, c='r') #image_plot.set_xlim(xmin=0, xmax=100) self.blob_hist.canvas.draw() if self._blobs_have_been_loaded == False: self.plots_vbox2.show_all() self._blobs_have_been_loaded = True
class GuiSessionViewer(threading.Thread): def __init__(self, config, querylist, mainwin, debug=True): self.debug = debug self.conf = config self.sql = querylist self.liststore = None self.MYSQL_INNODB = 2 self.PGSQL = 3 self.SQLITE = 4 self.fig = None self.canvas = None self.ax = None self.graphBox = None # create new db connection to avoid conflicts with other threads self.db = Database.Database(self.conf, sql=self.sql) self.cursor = self.db.cursor settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) settings.update(self.conf.get_default_paths()) # text used on screen stored here so that it can be configured self.filterText = { 'handhead': _('Hand Breakdown for all levels listed above') } filters_display = { "Heroes": True, "Sites": True, "Games": False, "Limits": False, "LimitSep": False, "LimitType": False, "Type": True, "Seats": False, "SeatSep": False, "Dates": True, "Groups": False, "GroupsAll": False, "Button1": True, "Button2": False } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name("_Refresh") self.filters.registerButton1Callback(self.refreshStats) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting self.columns = [ ("sid", True, "SID", 0.0, "%s"), ("hand", False, "Hand", 0.0, "%s" ) # true not allowed for this line , ("n", True, "Hds", 1.0, "%d"), ("start", True, "Start", 1.0, "%d"), ("end", True, "End", 1.0, "%d"), ("hph", True, "Hands/h", 1.0, "%d"), ("profit", True, "Profit", 1.0, "%s") #, ("avgseats", True, "Seats", 1.0, "%3.1f") #, ("vpip", True, "VPIP", 1.0, "%3.1f") #, ("pfr", True, "PFR", 1.0, "%3.1f") #, ("pf3", True, "PF3", 1.0, "%3.1f") #, ("steals", True, "Steals", 1.0, "%3.1f") #, ("saw_f", True, "Saw_F", 1.0, "%3.1f") #, ("sawsd", True, "SawSD", 1.0, "%3.1f") #, ("wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f") #, ("wmsd", True, "W$SD", 1.0, "%3.1f") #, ("flafq", True, "FlAFq", 1.0, "%3.1f") #, ("tuafq", True, "TuAFq", 1.0, "%3.1f") #, ("rvafq", True, "RvAFq", 1.0, "%3.1f") #, ("pofafq", False, "PoFAFq", 1.0, "%3.1f") #, ("net", True, "Net($)", 1.0, "%6.2f") #, ("bbper100", True, "BB/100", 1.0, "%4.2f") #, ("rake", True, "Rake($)", 1.0, "%6.2f") #, ("variance", True, "Variance", 1.0, "%5.2f") ] self.stats_frame = None self.stats_vbox = None self.detailFilters = [] # the data used to enhance the sql select #self.main_hbox = gtk.HBox(False, 0) #self.main_hbox.show() self.main_hbox = gtk.HPaned() self.stats_frame = gtk.Frame() self.stats_frame.show() self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) # self.fillStatsFrame(self.stats_vbox) #self.main_hbox.pack_start(self.filters.get_vbox()) #self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) self.main_hbox.pack1(self.filters.get_vbox()) self.main_hbox.pack2(self.stats_frame) self.main_hbox.show() # make sure Hand column is not displayed #[x for x in self.columns if x[0] == 'hand'][0][1] = False def get_vbox(self): """returns the vbox of this thread""" return self.main_hbox def refreshStats(self, widget, data): try: self.stats_vbox.destroy() except AttributeError: pass self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) def fillStatsFrame(self, vbox): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() seats = self.filters.getSeats() sitenos = [] playerids = [] # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _q = self.sql.query['getPlayerId'] _name = Charset.to_utf8(heroes[site]) #print 'DEBUG(_name) :: %s' % _name self.cursor.execute(_q, (_name, )) # arg = tuple result = self.db.cursor.fetchall() if len(result) == 1: playerids.append(result[0][0]) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not playerids: print _("No player ids found") return if not limits: print _("No limits found") return self.createStatsPane(vbox, playerids, sitenos, limits, seats) def createStatsPane(self, vbox, playerids, sitenos, limits, seats): starttime = time() (results, opens, closes, highs, lows) = self.generateDatasets(playerids, sitenos, limits, seats) self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.generateGraph(opens, closes, highs, lows) vbox.pack_start(self.graphBox) # Separator sep = gtk.HSeparator() vbox.pack_start(sep, expand=False, padding=3) sep.show_now() vbox.show_now() heading = gtk.Label(self.filterText['handhead']) heading.show() vbox.pack_start(heading, expand=False, padding=3) # Scrolled window for detailed table (display by hand) swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.show() vbox.pack_start(swin, expand=True, padding=3) vbox1 = gtk.VBox(False, 0) vbox1.show() swin.add_with_viewport(vbox1) self.addTable(vbox1, results) self.db.rollback() print _("Stats page displayed in %4.2f seconds") % (time() - starttime) #end def fillStatsFrame(self, vbox): def generateDatasets(self, playerids, sitenos, limits, seats): THRESHOLD = 1800 # Minimum number of seconds between consecutive hands before being considered a new session PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc (FiXME: user configurable) # Get a list of all handids and their timestampts #FIXME: Query still need to filter on blind levels q = self.sql.query['sessionStats'] start_date, end_date = self.filters.getDates() q = q.replace("<datestest>", " between '" + start_date + "' and '" + end_date + "'") nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)", ")") q = q.replace("<player_test>", nametest) q = q.replace("<ampersand_s>", "%s") self.db.cursor.execute(q) hands = self.db.cursor.fetchall() # Take that list and create an array of the time between hands times = map(lambda x: long(x[0]), hands) handids = map(lambda x: int(x[1]), hands) winnings = map(lambda x: float(x[4]), hands) #print "DEBUG: len(times) %s" %(len(times)) diffs = diff( times ) # This array is the difference in starttime between consecutive hands diffs2 = append( diffs, THRESHOLD + 1 ) # Append an additional session to the end of the diffs, so the next line # includes an index into the last 'session' index = nonzero( diffs2 > THRESHOLD ) # This array represents the indexes into 'times' for start/end times of sessions # times[index[0][0]] is the end of the first session, #print "DEBUG: len(index[0]) %s" %(len(index[0])) if len(index[0]) > 0: #print "DEBUG: index[0][0] %s" %(index[0][0]) #print "DEBUG: index %s" %(index) pass else: index = [[0]] #print "DEBUG: index %s" %(index) #print "DEBUG: index[0][0] %s" %(index[0][0]) pass total = 0 first_idx = 0 lowidx = 0 uppidx = 0 opens = [] closes = [] highs = [] lows = [] results = [] cum_sum = cumsum(winnings) cum_sum = cum_sum / 100 sid = 1 # Take all results and format them into a list for feeding into gui model. for i in range(len(index[0])): hds = index[0][i] - first_idx + 1 # Number of hands in session if hds > 0: stime = strftime("%d/%m/%Y %H:%M", localtime( times[first_idx])) # Formatted start time etime = strftime("%d/%m/%Y %H:%M", localtime( times[index[0][i]])) # Formatted end time minutesplayed = (times[index[0][i]] - times[first_idx]) / 60 if minutesplayed == 0: minutesplayed = 1 minutesplayed = minutesplayed + PADDING hph = hds * 60 / minutesplayed # Hands per hour won = sum(winnings[first_idx:index[0][i]]) / 100.0 hwm = max(cum_sum[first_idx:index[0][i]]) lwm = min(cum_sum[first_idx:index[0][i]]) open = (sum(winnings[:first_idx])) / 100 close = (sum(winnings[:index[0][i]])) / 100 #print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, index[0][i], lwm, hwm, open, close) results.append([sid, hds, stime, etime, hph, won]) opens.append(open) closes.append(close) highs.append(hwm) lows.append(lwm) #print "DEBUG: Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won) total = total + (index[0][i] - first_idx) first_idx = index[0][i] + 1 sid = sid + 1 else: print "hds <= 0" return (results, opens, closes, highs, lows) def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig is not None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("***Error: ") + err[2] + "(" + str(err[1]) + "): " + str( sys.exc_info()[1]) raise def generateGraph(self, opens, closes, highs, lows): self.clearGraphData() # print "DEBUG:" # print "highs = %s" % highs # print "lows = %s" % lows # print "opens = %s" % opens # print "closes = %s" % closes # print "len(highs): %s == len(lows): %s" %(len(highs), len(lows)) # print "len(opens): %s == len(closes): %s" %(len(opens), len(closes)) # # for i in range(len(highs)): # print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i]) # print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i]) self.ax = self.fig.add_subplot(111) self.ax.set_title(_("Session candlestick graph")) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Sessions"), fontsize=12) self.ax.set_ylabel("$", fontsize=12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) candlestick2(self.ax, opens, closes, highs, lows, width=0.50, colordown='r', colorup='g', alpha=1.00) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() def addTable(self, vbox, results): row = 0 sqlrow = 0 colalias, colshow, colheading, colxalign, colformat = 0, 1, 2, 3, 4 # pre-fetch some constant values: cols_to_show = [x for x in self.columns if x[colshow]] self.liststore = gtk.ListStore(*([str] * len(cols_to_show))) for row in results: iter = self.liststore.append(row) view = gtk.TreeView(model=self.liststore) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) vbox.add(view) textcell = gtk.CellRendererText() textcell50 = gtk.CellRendererText() textcell50.set_property('xalign', 0.5) numcell = gtk.CellRendererText() numcell.set_property('xalign', 1.0) listcols = [] # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(cols_to_show): s = column[colheading] listcols.append(gtk.TreeViewColumn(s)) view.append_column(listcols[col]) if column[colformat] == '%s': if column[colxalign] == 0.0: listcols[col].pack_start(textcell, expand=True) listcols[col].add_attribute(textcell, 'text', col) else: listcols[col].pack_start(textcell50, expand=True) listcols[col].add_attribute(textcell50, 'text', col) listcols[col].set_expand(True) else: listcols[col].pack_start(numcell, expand=True) listcols[col].add_attribute(numcell, 'text', col) listcols[col].set_expand(True) vbox.show_all()
class appgui: def __init__(self): self.gladefile = "attenuation_calc.glade" windowname = "MainWindow" self.wTree=gtk.glade.XML(self.gladefile, windowname) dic = { "on_GetDataButton_clicked" : self.button1_clicked, "on_SaveImageMenuItem_activate" : self.save_image, "on_ExportMenuItem_activate" : self.save_data, "on_MainWindow_destroy" : (gtk.main_quit) , "on_QuitMenuItem_activate" : (gtk.main_quit), "on_about_menuitem_activate" : self.about } self.wTree.signal_autoconnect(dic) self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Energies') self.axis.set_ylabel('Attenuation Length (microns)') self.axis.set_title('Attenuation Lengths vs Energy') self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.graphview = self.wTree.get_widget("vbox1") self.graphview.pack_start(self.canvas,True,True) #self.graphview.pack_start(self.canvas,True,True) self.wTree.get_widget(windowname).maximize() self.E = {} self.attlen = {} return def about(self,widget): print 'Hello World' t = gtk.glade.XML(self.gladefile, "aboutdialog1") about = t.get_widget("aboutdialog1") about.run() about.hide() return def button1_clicked(self,widget): self.graphview.remove(self.canvas) # important else they just get inserted again each time (not replaced) self.axis.cla() eltext = self.wTree.get_widget("ElementText").get_text() if eltext.find(',') == -1: el = self.wTree.get_widget("ElementText").get_text().split() else: el = self.wTree.get_widget("ElementText").get_text().split(',') [self.E,self.attlen] = nx.calclengths(el) for e in self.attlen.keys(): self.axis.loglog(self.E[e],self.attlen[e],label=e); self.axis.set_xlabel('Energy (MeV)') self.axis.set_ylabel('Attenuation Length (cm)') self.axis.set_title('Attenuation Lengths vs Energy') self.axis.legend(loc='lower right') self.axis.grid(True) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.graphview = self.wTree.get_widget("vbox1") self.graphview.pack_end(self.canvas, True, True) #self.graphview.pack_start(self.canvas, True, True) #print dir(self.canvas) def save_image(self,widget): chooser = gtk.FileChooserDialog(title='Save File',action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_OK) response = chooser.run() if response == gtk.RESPONSE_OK: print chooser.get_filename() self.figure.savefig(chooser.get_filename()) else: print 'No files selected' chooser.destroy() def save_data(self,widget): chooser = gtk.FileChooserDialog(title='Save File',action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_OK) response = chooser.run() if response == gtk.RESPONSE_OK: print chooser.get_filename() filename = chooser.get_filename() Eint = [] # ==Interpolate data== # Find unique energies for e in self.E.keys(): Eint = Eint + self.E[e] # Uniquify list Eint = list(set(Eint)) Eint.sort() att_ints = [] # Interpolate the data for e in self.attlen.keys(): buff = interpolate.interp1d(self.E[e], self.attlen[e], kind='linear', bounds_error=False) att_ints.append(buff(Eint)) print 'Writing data to file:',filename fout = open(filename,'w') fout.write('# Data output from attenuation calculator\n') fout.write('Energy,'+ ','.join(self.E.keys())+'\n') print len(Eint), len(self.attlen.keys()) for i in range(len(Eint)): fout.write(str(Eint[i])) for j in range(len(self.attlen.keys())): fout.write(',' + str(att_ints[j][i])) fout.write('\n') #fout.write(str(energy)+','+','.join([i(energy) for i in att_ints])+'\n') print 'Done' else: print 'No files selected' chooser.destroy()
class GuiGraphViewer (threading.Thread): def __init__(self, querylist, config, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes" : True, "Sites" : True, "Games" : True, "Limits" : True, "LimitSep" : True, "LimitType" : True, "Type" : False, "UseType" : 'ring', "Seats" : False, "SeatSep" : False, "Dates" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name("Refresh _Graph") self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name("_Export to File") self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) raise def generateGraph(self, widget, data): try: self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() games = self.filters.getGames() for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print "No sites selected - defaulting to PokerStars" self.db.rollback() return if not playerids: print "No player ids found" self.db.rollback() return if not limits: print "No limits found" self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, blue, red) = self.getRingProfitGraph(playerids, sitenos, limits, games) print "Graph generated in: %s" %(time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel("Hands", fontsize = 12) self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title("No Data for Player(s) Found") green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label='Hands: %d\nProfit: $%.2f' %(len(green), green[-1])) self.ax.plot(blue, color='blue', label='Showdown: $%.2f' %(blue[-1])) self.ax.plot(red, color='red', label='Non-showdown: $%.2f' %(red[-1])) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user #print "No hands returned by graph query" else: self.ax.set_title("Profit graph for ring games") #text = "Profit: $%.2f\nTotal Hands: %d" %(green[-1], len(green)) #self.ax.annotate(text, # xy=(10, -10), # xycoords='axes points', # horizontalalignment='left', verticalalignment='top', # fontsize=10) #Draw plot self.ax.plot(green, color='green', label='Hands: %d\nProfit: $%.2f' %(len(green), green[-1])) self.ax.plot(blue, color='blue', label='Showdown: $%.2f' %(blue[-1])) self.ax.plot(red, color='red', label='Non-showdown: $%.2f' %(red[-1])) if sys.version[0:3] == '2.5': self.ax.legend(loc='best', shadow=True, prop=FontProperties(size='smaller')) else: self.ax.legend(loc='best', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) #end of def showClicked def getRingProfitGraph(self, names, sites, limits, games): tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #nametest = nametest.replace("L", "") q = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: q.append(n) if len(q) > 0: gametest = str(tuple(q)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)",")") gametest = gametest.replace("u'","'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" tmp = tmp.replace("<game_test>", gametest) lims = [int(x) for x in limits if x.isdigit()] potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl'] nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl'] limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in " # and ( (limit and bb in()) or (nolimit and bb in ()) ) if lims: blindtest = str(tuple(lims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'pl' and gt.bigBlind in " if potlims: blindtest = str(tuple(potlims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in " if nolims: blindtest = str(tuple(nolims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) )' else: limittest = limittest + '(-1) ) )' if type == 'ring': limittest = limittest + " and gt.type = 'ring' " elif type == 'tour': limittest = limittest + " and gt.type = 'tour' " #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace("<limit_test>", limittest) tmp = tmp.replace(",)", ")") #print "DEBUG: sql query:" #print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None, None) green = map(lambda x:float(x[1]), winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) blueline = cumsum(blue) redline = cumsum(red) return (greenline/100, blueline/100, redline/100) #end of def getRingProfitGraph def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title="Please choose the directory you wish to export to:", action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) #TODO: Suggest path and filename to start with response = dia_chooser.run() if response == gtk.RESPONSE_OK: self.exportDir = dia_chooser.get_filename() print "DEBUG: self.exportDir = %s" %(self.exportDir) elif response == gtk.RESPONSE_CANCEL: print 'Closed, no graph exported' dia_chooser.destroy() #TODO: Check to see if file exists #NOTE: Dangerous - will happily overwrite any file we have write access too #TODO: This asks for a directory but will take a filename and overwrite it. self.fig.savefig(self.exportDir, format="png")
class GuiBankrollGraphViewer(threading.Thread): def __init__(self, settings, db, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.settings = settings self.db = db self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) view = None filters_display = { "Heroes": True, "Sites": True, "Games": False, "Limits": False, "LimitSep": False, "LimitType": False, "Type": False, "UseType": 'tour', "Seats": False, "SeatSep": False, "Dates": True, "Groups": False, "Button1": True, "Button2": True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) numeric_const_pattern = r""" [-+]? # optional sign (?: (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc | (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc ) # followed by optional exponent part if desired (?: [Ee] [+-]? \d+ ) ? """ self.rx = re.compile(numeric_const_pattern, re.VERBOSE) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() #add a button to modify transferts ButtonTransfert = gtk.Button(_("ButtonTransfert")) ButtonTransfert.set_label(_("_Modify Transferts")) ButtonTransfert.connect("clicked", self.transfertsWindow, "clicked") ButtonTransfert.set_sensitive(True) self.filters.mainVBox.pack_start(ButtonTransfert, False) ButtonTransfert.show() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None #update the graph at entry (simulate a «Refresh Graph» click) gobject.GObject.emit(self.filters.Button1, "clicked") self.db.rollback() #endinit def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, dates, transfersAmount, transfersDate, transferType) = self.getData(playerids, sitenos) print _("Graph generated in: %s") % (time() - starttime) #Set axis labels and grid overlay properites self.ax.set_ylabel("$", fontsize=12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) self.ax.plot(green, color='green', label=_('Bankroll') + _('Profit') + ': $%.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Bankroll Results")) useDates = True #nothing to draw if (len(green) == 0): return #Get the dates of the action (transfert / cg hand / tourney) #if it has no date, get the most ancient date and assume it's its one if dates[0] is None: i = 1 while i < len(dates) and type(dates[i]) is None: i = i + 1 if i == len(dates): print "Wow wow wow : no dates in your whole database" useDates = False else: dates[0] = dates[i] #now, convert date to dateTime format if useDates: for i in range(0, len(dates)): if dates[i] is None: dates[i] = dates[i - 1] #~else: #~dates[i] = datetime.datetime.strptime(dates[i], "%Y-%m-%d %H:%M:%S") for i in range(0, len(green) - 1): beneficeSinceStart = green[i + 1] - self.totalTransfer( dates[i + 1], transfersAmount, transfersDate) mycolor = self.color(transferType[i + 1], beneficeSinceStart) self.ax.plot([i, i + 1], [green[i], green[i + 1]], color=mycolor) #show date and gain only 5 times on X axis if (i % (len(green) / 5) == 1): #the gain since start at this time if (mycolor == 'cyan'): mycolor = 'green' self.ax.annotate('%.2f' % beneficeSinceStart, xy=(i, 0), color=mycolor, xycoords=('data', 'axes fraction'), xytext=(0, 18), textcoords='offset points', va='top', ha='left') #and show the date too if enabled if useDates: dateMMDD = datetime.datetime.strptime( dates[i], "%Y-%m-%d %H:%M:%S").strftime('%d/%m') self.ax.annotate(dateMMDD, xy=(i, 0), xycoords=('data', 'axes fraction'), xytext=(0, -18), textcoords='offset points', va='top', ha='left') #plot the last one and show the top corner legend i = len(green) - 1 bankroll = float(green[i]) profit = bankroll if len(transfersAmount) > 0: profit -= transfersAmount[len(transfersAmount) - 1] self.ax.plot([i, i + 1], [green[i], green[i]], color=self.color(transferType[i], beneficeSinceStart), label=_('Bankroll') + ': \$%.2f' % bankroll + '\n' + _('Profit') + ': \$%.2f' % profit) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #end of def showClicked #return total cash from transfer until «date» def totalTransfer(self, date, amounts, transfersDate): #~print transferts if len(amounts) == 0 or (date < transfersDate[0]): return 0 i = 0 while (i < len(amounts) - 1 and date > transfersDate[i]): i = i + 1 return amounts[i] def color(self, typ, gain): # 0:play, 1:transfert if typ == 1: return 'cyan' elif gain < 0: return 'red' else: return 'green' def getData(self, names, sites): print "DEBUG: args are :" print names print sites tmp = self.rightRequest('getAllPrintIdSite', names, sites) tmp2 = self.rightRequest('getAllTransfer', names, sites) print "DEBUG: sql query:" print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.cursor.execute(tmp2) transfers = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return None green = map(lambda x: float(x[0]), winnings) dates = map(lambda x: x[1], winnings) typeOf = map(lambda x: x[2], winnings) transferAmounts = map(lambda x: x[0], transfers) transferDates = map(lambda x: x[1], transfers) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) transferAmounts = cumsum(transferAmounts) return (greenline / 100., dates, transferAmounts, transferDates, typeOf) def exportGraph(self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog( title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename( self.exportFile ) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename( ) + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy() #end of def exportGraph def transfertsWindow(self, widget, data): #if the window is already launched, put it in front if not self.settings['global_lock'].acquire( wait=False, source="GuiBankrollGraphViewer"): return #create the window … #first, check if there is at least one player on database, else quit if (len(self.filters.getHeroes()) == 0): print "No site/hero found, abort" return self.transferWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) self.transferWindow.set_title("Transferts Management") self.transferWindow.set_position(gtk.WIN_POS_CENTER) self.transferWindow.set_transient_for(self.parent) self.transferWindow.connect("destroy", self.release) vbox = gtk.VBox(False, 0) self.transferWindow.add(vbox) ##### ##### #«new transfert» part hboxAdd = gtk.HBox(True, 0) vbox.pack_start(hboxAdd) #calendar cal = gtk.Calendar() vboxSelection = gtk.VBox(False, 0) #hour selection hourLabel = gtk.Label(_('Select hour:')) hourLabel.set_alignment(xalign=0.0, yalign=0.5) hboxHour = gtk.HBox(False, 0) timeHourPicker = gtk.SpinButton(None, 0, 0) timeHourPicker.set_increments(1, 6) timeHourPicker.set_range(0, 23) timeHourPicker.set_value(datetime.datetime.now().hour) # current hour timeMinPicker = gtk.SpinButton(None, 0, 0) timeMinPicker.set_increments(1, 10) timeMinPicker.set_range(0, 59) timeMinPicker.set_value(datetime.datetime.now().minute) # current hour #site/hero selection IDLabel = gtk.Label(_('Site - hero:')) IDLabel.set_alignment(xalign=0.0, yalign=0.5) IDSelection = gtk.combo_box_new_text() for site, hero in self.filters.getHeroes().items(): IDSelection.append_text(site + " - " + hero) IDSelection.set_active(0) #amount of virement amountLabel = gtk.Label(_('Tranfert amount ($):')) amountLabel.set_alignment(xalign=0.0, yalign=0.5) amountEntry = gtk.Entry() amountEntry.set_text('10.00') amountEntry.connect('changed', self.on_changed, 'changed') #button add buttonAdd = gtk.ToolButton(gtk.STOCK_ADD) buttonAdd.connect('clicked', self.newTransfer, 'clicked', cal, timeHourPicker, timeMinPicker, IDSelection, amountEntry) buttonAdd.connect('clicked', self.destroyWindow) hboxAdd.pack_start(cal, 0) hboxAdd.pack_start(vboxSelection, 0) vboxSelection.pack_start(hourLabel, 0) vboxSelection.pack_start(hboxHour, 0) hboxHour.pack_start(timeHourPicker, 0) hboxHour.pack_start(timeMinPicker, 0) vboxSelection.pack_start(IDLabel, 0) vboxSelection.pack_start(IDSelection, 0) vboxSelection.pack_start(amountLabel, 0) vboxSelection.pack_start(amountEntry, 0) vboxSelection.pack_start(buttonAdd, -1) #end of "new transfert" part ##### #### #### #start of "delete transfert" part hboxDelete = gtk.HBox(False, 0) vbox.pack_start(hboxDelete) #tab to create vboxTab = gtk.VBox(False, 0) self.createTab(vboxTab) buttonDelete = gtk.ToolButton(gtk.STOCK_DELETE) buttonDelete.connect('clicked', self.deleteTransfer, 'clicked') hboxDelete.pack_start(vboxTab, 1) hboxDelete.pack_start(buttonDelete, 1) #end of "delete transfert" part #### self.transferWindow.show_all() return #end of def transfertsWindow def release(self, widget, data=None): self.settings['global_lock'].release() self.transferWindow.destroy() return def on_changed(self, widget, data): #~text = widget.get_text().strip() #~widget.set_text(''.join([i for i in text if i in '0123456789'])) entry_text = widget.get_text() newtext = self.rx.findall(entry_text) if len(newtext): widget.set_text(newtext[0]) else: widget.set_text("") def destroyWindow(self, widget): self.transferWindow.destroy() return def newTransfer(self, widget, data, cal, timeHourPicker, timeMinPicker, IDSelection, amountEntry): year, month, day = cal.get_date() month = month + 1 # because gtk gives it between 0 and 11 ?! hour = timeHourPicker.get_value() minute = timeMinPicker.get_value() (site, separator, hero) = IDSelection.get_active_text().partition(' - ') transfer = float(amountEntry.get_text()) now = datetime.datetime(year, month, day, int(hour), int(minute), 0) #get siteID from siteName (table "sites") self.db.cursor.execute('SELECT id from sites where name LIKE "' + site + '"') siteID = self.db.cursor.fetchall()[0][0] self.db.rollback() #get heroID from heroName and siteID (table "players") self.db.cursor.execute('select id from players where name LIKE "' + hero + '" and siteId = ' + str(siteID)) heroID = self.db.cursor.fetchall()[0][0] self.db.rollback() #insert it in the table now query = "INSERT INTO BankrollsManagement(siteId, playerId, transfer, startTime) VALUES (?, ?, ?, ?)" #~print "DEBUG:\n%s" % query self.db.cursor.execute(query, (siteID, heroID, int(transfer * 100), now)) self.db.commit() self.db.rollback() #update the graph gobject.GObject.emit(self.filters.Button1, "clicked") def deleteTransfer(self, widget, data): #get the active line of the array selected = self.view.get_cursor()[0] #if no row selected, abort if selected is None: return #else, retrieve the line ( /!\ rowNumber != Id from the table ), rowNumber = selected[0] line = self.liststore[0][rowNumber] id = line[0] #then delete it from table and refresh graph self.db.cursor.execute('DELETE FROM BankrollsManagement WHERE id=' + str(id)) self.db.commit() self.db.rollback() #destroy the window self.destroyWindow(widget) gobject.GObject.emit(self.filters.Button1, "clicked") def createTab(self, vbox): cols_to_show = [ ["id", False, _("ID"), 0.0, "%s", "str"], ["siteName", True, _("Site"), 0.0, "%s", "str"] # true not allowed for this line (set in code) , ["playerName", True, _("Name"), 0.8, "%s", "str"] # true not allowed for this line (set in code) , ["amount", True, _("Amount"), 0.0, "%0.2f", "str"], ["date", True, _("Date"), 0.0, "%s", "str"] ] self.liststore = [] self.liststore.append(gtk.ListStore(*([str] * len(cols_to_show)))) self.view = gtk.TreeView(model=self.liststore[0]) self.view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) #vbox.pack_start(view, expand=False, padding=3) vbox.add(self.view) textcell = gtk.CellRendererText() textcell50 = gtk.CellRendererText() textcell50.set_property('xalign', 0.5) numcell = gtk.CellRendererText() numcell.set_property('xalign', 1.0) listcols = [] listcols.append([]) # Create header row eg column: ("game", True, "Game", 0.0, "%s") for i, col in enumerate(cols_to_show): listcols[0].append(gtk.TreeViewColumn(col[_COL_HEADING])) self.view.append_column(listcols[0][i]) if col[_COL_FORMAT] == '%s': if col[_COL_XALIGN] == 0.0: listcols[0][i].pack_start(textcell, expand=True) listcols[0][i].add_attribute(textcell, 'text', i) cellrend = textcell else: listcols[0][i].pack_start(textcell50, expand=True) listcols[0][i].add_attribute(textcell50, 'text', i) cellrend = textcell50 listcols[0][i].set_expand(True) else: listcols[0][i].pack_start(numcell, expand=True) listcols[0][i].add_attribute(numcell, 'text', i) listcols[0][i].set_expand(True) cellrend = numcell query = self.sql.query['getAllTransferInformations'] #~print "DEBUG:\n%s" % query self.db.cursor.execute(query) result = self.db.cursor.fetchall() #~print "result of the big query in addGrid:",result colnames = [desc[0] for desc in self.db.cursor.description] #~for i in range(0, len(tab)) rows = len(result) # +1 for title row counter = 0 row = 0 sqlrow = 0 while sqlrow < rows: treerow = [] for col, column in enumerate(cols_to_show): if column[_COL_ALIAS] in colnames: if column[_COL_ALIAS] == 'amount': #convert $ cents to $ value = result[sqlrow][colnames.index( column[_COL_ALIAS])] / 100. else: value = result[sqlrow][colnames.index( column[_COL_ALIAS])] else: value = 111 if value != None and value != -999: treerow.append(column[_COL_FORMAT] % value) else: treerow.append(' ') #print "addGrid, just before end of big for. grid:",grid,"treerow:",treerow iter = self.liststore[0].append(treerow) sqlrow += 1 row += 1 vbox.show_all() def rightRequest(self, request, names, sites): tmp = self.sql.query[request] print "DEBUG: getData. :" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") return tmp
class DataManager(gtk.Window): numRows, numCols = 20,10 data = rand(numRows, numCols) def __init__(self): gtk.Window.__init__(self) self.connect('destroy', lambda win: gtk.main_quit()) self.set_title('GtkListStore demo') self.set_border_width(8) vbox = gtk.VBox(FALSE, 8) self.add(vbox) label = gtk.Label('Double click a row to plot the data') vbox.pack_start(label, FALSE, FALSE) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True, True) model = self.create_model() self.treeview = gtk.TreeView(model) self.treeview.set_rules_hint(TRUE) # matplotlib stuff fig = Figure(figsize=(6,4)) self.canvas = FigureCanvas(fig) # a gtk.DrawingArea self.canvas.show() vbox.pack_start(self.canvas, False, False) ax = fig.add_subplot(111) self.line, = ax.plot(self.data[0,:], 'go') # plot the first row self.treeview.connect('row-activated', self.plot_row) sw.add(self.treeview) self.add_columns() self.set_default_size(600, 600) self.add_events(gdk.BUTTON_PRESS_MASK | gdk.KEY_PRESS_MASK| gdk.KEY_RELEASE_MASK) def plot_row(self, treeview, path, view_column): ind, = path # get the index into data points = self.data[ind,:] self.line.set_ydata(points) self.canvas.draw() def add_columns(self): model = self.treeview.get_model() renderer = gtk.CellRendererText() for i in range(self.numCols): column = gtk.TreeViewColumn('%d'%i, gtk.CellRendererText(), text=i) self.treeview.append_column(column) def create_model(self): types = [gobject.TYPE_DOUBLE]*self.numCols store = gtk.ListStore(*types) for row in self.data: iter = store.append() pairs = [] for i, num in enumerate(row): pairs.extend((i, num)) store.set(iter, *pairs) return store
class myGUI: # ------------------------------ nbv = 100 # number of values to be plotted sig_x = np.empty(0) sig_y = np.empty(0) # instant values read from shared memory sig_f = np.empty(0) sig_a1 = np.empty(0) sig_a2 = np.empty(0) ave_x = np.empty(0) #zeros(nbv) ave_y = np.empty(0) #zeros(nbv) # averaged values ave_f = np.empty(0) ave_a1 = np.empty(0) ave_a2 = np.empty(0) live_plot = False # ------------------------------- def pgquit(self, widget): self.live_plot = False print("The program has ended normally.") mygtk.gui_quit() # ------------------------------- def __init__(self, ): self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.connect("destroy", self.pgquit) self.window.set_title("Plot window") self.window.set_border_width(5) self.window.set_default_size(800, 600) self.table = gtk.Table(10, 4, True) self.window.add(self.table) self.table.show() # ========================================== self.figure = Figure(figsize=(6, 4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('iteration') self.axis.set_ylabel('Astigmatisms moving average (micron)') self.axis.set_ylim([-80.0, 80.0]) self.axis.set_ylim([-0.2, 0.2]) self.axis.grid(True) x = np.arange(100) self.axis.plot(x) self.axis.plot(x) self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.table.attach(self.canvas, 0, 4, 0, 9) # ========================================== butt = gtk.Button("START") butt.connect("clicked", self.b_clicked1) self.table.attach(butt, 0, 1, 9, 10) butt.show() self.butt = gtk.Button("STOP") self.butt.connect("clicked", self.b_clicked2) self.table.attach(self.butt, 1, 2, 9, 10) self.butt.show() self.lbl = gtk.Label("ExpTime:") #self.butt.connect("clicked", self.b_clicked3) self.table.attach(self.lbl, 2, 3, 9, 10) self.lbl.show() self.lbl_tint = gtk.Label("") self.table.attach(self.lbl_tint, 3, 4, 9, 10) self.lbl_tint.show() # ---------------- self.window.show() def b_clicked1(self, widget): self.live_plot = True #plot_loop(self) t = threading.Thread(target=plot_loop, args=(self, )) t.start() def b_clicked2(self, widget): self.live_plot = False
class BrachGUI: def __init__(self): self.lastUpdate = datetime.now() self.thread = None self.lastBest = None self.builder = gtk.Builder() self.builder.add_from_file(GUI_FILENAME) # init default values (due to Glade 3.7 bug) self.builder.get_object("input_Ax").set_value(brach.A[0]) self.builder.get_object("input_Ay").set_value(brach.A[1]) self.builder.get_object("input_Bx").set_value(brach.B[0]) self.builder.get_object("input_By").set_value(brach.B[1]) self.builder.get_object("input_population_size").set_value(brach.POPULATION_MAX) self.builder.get_object("input_elitism").set_value(brach.ELITISM*100) self.builder.get_object("input_points").set_value(brach.POINTS_INIT) self.builder.get_object("input_crossover").set_value(brach.CROSSOVER*100) self.builder.get_object("input_crossover_len").set_value(brach.CROSSOVER_LEN_MAX*100) self.builder.get_object("input_mutation").set_value(brach.MUTATION*100) self.builder.get_object("input_mutation_y").set_value(brach.MUTATION_Y*100) self.builder.get_object("input_mutation_burst").set_value(brach.MUTATION_BURST*100) # init the input_selection_type selection_model = gtk.ListStore(str) selection_model.append(["Tournament"]) selection_model.append(["Roulette"]) selection_box = self.builder.get_object("input_selection_type") selection_box.set_model(selection_model) cell = gtk.CellRendererText() selection_box.pack_start(cell) selection_box.add_attribute(cell,'text',0) selection_box.set_active(0) self.builder.get_object("button_save").set_sensitive(False) self.running = False # init graphs self.fig_best = Figure(figsize=(400, 400)) self.fig_hist = Figure(figsize=(400, 200)) self.canvas_best = FigureCanvasGTK(self.fig_best) self.canvas_hist = FigureCanvasGTK(self.fig_hist) self.canvas_best.show() self.canvas_hist.show() self.hbox_best = self.builder.get_object("hbox_graph_best") self.hbox_hist = self.builder.get_object("hbox_graph_hist") self.hbox_best.pack_start(self.canvas_best, True, True) self.hbox_hist.pack_start(self.canvas_hist, True, True) # show window self.builder.connect_signals(self) window = self.builder.get_object('window_main') window.set_title("Brachistochrone curve") window.show() def on_adjust_Ax_value_changed(self, widget, data=None): brach.A[0] = widget.get_value() if brach.A[0] >= brach.B[0]: widget.set_value(brach.A[0]-0.1) return True def on_adjust_Ay_value_changed(self, widget, data=None): brach.A[1] = widget.get_value() if brach.A[1] < brach.B[1]: widget.set_value(brach.A[1] + 0.1) return True def on_adjust_Bx_value_changed(self, widget, data=None): brach.B[0] = widget.get_value() if brach.B[0] <= brach.A[0]: widget.set_value(brach.B[0] + 0.1) return True def on_adjust_By_value_changed(self, widget, data=None): brach.A[1] = widget.get_value() if brach.B[1] > brach.A[1]: widget.set_value(brach.B[1] - 0.1) return True def on_input_population_size_value_changed(self, widget, data=None): brach.POPULATION_MAX = widget.get_value_as_int() return True def on_input_elitism_value_changed(self, widget, data=None): brach.ELITISM = widget.get_value()/100 return True def on_input_selection_type_changed(self, widget, data=None): brach.SELECTION_TYPE = widget.get_active_text() return True def on_input_points_value_changed(self, widget, data=None): brach.POINTS_INIT = widget.get_value_as_int() return True def on_input_crossover_value_changed(self, widget, data=None): brach.CROSSOVER = widget.get_value()/100 return True def on_input_crossover_len_value_changed(self, widget, data=None): brach.CROSSOVER_LEN_MAX = widget.get_value()/100 return True def on_input_mutation_value_changed(self, widget, data=None): brach.MUTATION = widget.get_value()/100 return True def on_input_mutation_y_value_changed(self, widget, data=None): brach.MUTATION_Y = widget.get_value()/100 return True def on_input_mutation_burst_value_changed(self, widget, data=None): brach.MUTATION_BURST = widget.get_value()/100 return True def on_button_save_clicked(self, widget, data=None): # TODO: http://www.pygtk.org/pygtk2tutorial/sec-FileChoosers.html # chooser.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) dialog = gtk.FileChooserDialog("Choose a folder..", None, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) dialog.set_default_response(gtk.RESPONSE_OK) response = dialog.run() if response == gtk.RESPONSE_OK: points = self.population.getBest().getPlotData() f = open(dialog.get_filename() + '/data', 'w') f.write(str(self.iteration_list[-1])+"\n") f.write(str(self.best_list)+"\n") f.write(str(self.avg_list)+"\n") f.write(str(self.worst_list)+"\n") f.write(str(self.stddev_list)+"\n") f.write(str(points)+"\n") f.close() figureBest = plot.Figure(figsize=(400,400), dpi=72) graphBest = figureBest.add_subplot(111) graphBest.plot(points[0], points[1], 'r-*') graphBest.axis([0, brach.B[0], 0, brach.A[1]]) figureBest.savefig(dialog.get_filename() + '/best.png') dialog.destroy() return True def on_button_start_stop_clicked(self, widget, data=None): self.running = not self.running if self.running: widget.set_label("STOP") self.best_list = [] self.avg_list = [] self.worst_list = [] self.stddev_list = [] self.iteration_list = [] self.builder.get_object("input_Ax").set_sensitive(False) self.builder.get_object("input_Ay").set_sensitive(False) self.builder.get_object("input_Bx").set_sensitive(False) self.builder.get_object("input_By").set_sensitive(False) self.builder.get_object("input_population_size").set_sensitive(False) self.builder.get_object("input_elitism").set_sensitive(False) self.builder.get_object("input_selection_type").set_sensitive(False) self.builder.get_object("input_points").set_sensitive(False) self.builder.get_object("input_crossover").set_sensitive(False) self.builder.get_object("input_crossover_len").set_sensitive(False) self.builder.get_object("input_mutation").set_sensitive(False) self.builder.get_object("input_mutation_y").set_sensitive(False) self.builder.get_object("input_mutation_burst").set_sensitive(False) self.builder.get_object("button_save").set_sensitive(False) self.population = brach.Population.new(brach.POPULATION_MAX) self.thread = Thread(target=self.evolve) self.thread.start() else: widget.set_label("START") self.builder.get_object("input_Ax").set_sensitive(True) self.builder.get_object("input_Ay").set_sensitive(True) self.builder.get_object("input_Bx").set_sensitive(True) self.builder.get_object("input_By").set_sensitive(True) self.builder.get_object("input_population_size").set_sensitive(True) self.builder.get_object("input_elitism").set_sensitive(True) self.builder.get_object("input_selection_type").set_sensitive(True) self.builder.get_object("input_points").set_sensitive(True) self.builder.get_object("input_crossover").set_sensitive(True) self.builder.get_object("input_crossover_len").set_sensitive(True) self.builder.get_object("input_mutation").set_sensitive(True) self.builder.get_object("input_mutation_y").set_sensitive(True) self.builder.get_object("input_mutation_burst").set_sensitive(True) self.builder.get_object("button_save").set_sensitive(True) self.lastBest = None return True def on_window_main_destroy(self, widget, data=None): app.running = False if app.thread != None: app.thread.join() sys.exit(0) def evolve(self): i = 0 while self.running: self.population.evolve() stats = self.population.getStatistics() print "Iteration", i, stats self.best_list.append(stats[0]) self.avg_list.append(stats[1]) self.worst_list.append(stats[2]) self.stddev_list.append(stats[3]) self.iteration_list.append(i) if datetime.now() > self.lastUpdate + timedelta(seconds=1): self.lastUpdate = datetime.now() # best solution points = self.population.getBest().getPlotData() self.fig_best.clf() self.fig_hist.clf() graph_best = self.fig_best.add_subplot(111) graph_best.plot(points[0], points[1], 'r-*') graph_best.axis([0, brach.B[0], 0, brach.A[1]]) graph_hist = self.fig_hist.add_subplot(111) graph_hist.plot(self.iteration_list[-100:], self.best_list[-100:], 'b', self.iteration_list[-100:], self.avg_list[-100:], 'g', self.iteration_list[-100:], self.worst_list[-100:], 'r') self.fig_best.canvas.draw() self.fig_hist.canvas.draw() i += 1
class DataManager(gtk.Window): numRows, numCols = 20, 10 data = rand(numRows, numCols) def __init__(self): gtk.Window.__init__(self) self.connect('destroy', lambda win: gtk.main_quit()) self.set_title('GtkListStore demo') self.set_border_width(8) vbox = gtk.VBox(FALSE, 8) self.add(vbox) label = gtk.Label('Double click a row to plot the data') vbox.pack_start(label, FALSE, FALSE) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True, True) model = self.create_model() self.treeview = gtk.TreeView(model) self.treeview.set_rules_hint(TRUE) # matplotlib stuff fig = Figure(figsize=(6, 4)) self.canvas = FigureCanvas(fig) # a gtk.DrawingArea self.canvas.show() vbox.pack_start(self.canvas, False, False) ax = fig.add_subplot(111) self.line, = ax.plot(self.data[0, :], 'go') # plot the first row self.treeview.connect('row-activated', self.plot_row) sw.add(self.treeview) self.add_columns() self.set_default_size(600, 600) self.add_events(gdk.BUTTON_PRESS_MASK | gdk.KEY_PRESS_MASK | gdk.KEY_RELEASE_MASK) def plot_row(self, treeview, path, view_column): ind, = path # get the index into data points = self.data[ind, :] self.line.set_ydata(points) self.canvas.draw() def add_columns(self): model = self.treeview.get_model() renderer = gtk.CellRendererText() for i in range(self.numCols): column = gtk.TreeViewColumn('%d' % i, gtk.CellRendererText(), text=i) self.treeview.append_column(column) def create_model(self): types = [gobject.TYPE_DOUBLE] * self.numCols store = gtk.ListStore(*types) for row in self.data: iter = store.append() pairs = [] for i, num in enumerate(row): pairs.extend((i, num)) store.set(iter, *pairs) return store
class GuiSessionViewer (threading.Thread): def __init__(self, config, querylist, mainwin, debug=True): self.debug = debug self.conf = config self.sql = querylist self.liststore = None self.MYSQL_INNODB = 2 self.PGSQL = 3 self.SQLITE = 4 self.fig = None self.canvas = None self.ax = None self.graphBox = None # create new db connection to avoid conflicts with other threads self.db = Database.Database(self.conf, sql=self.sql) self.cursor = self.db.cursor settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) settings.update(self.conf.get_default_paths()) # text used on screen stored here so that it can be configured self.filterText = {'handhead':_('Hand Breakdown for all levels listed above')} filters_display = { "Heroes" : True, "Sites" : True, "Games" : False, "Limits" : False, "LimitSep" : False, "LimitType" : False, "Type" : True, "Seats" : False, "SeatSep" : False, "Dates" : True, "Groups" : False, "GroupsAll" : False, "Button1" : True, "Button2" : False } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name("_Refresh") self.filters.registerButton1Callback(self.refreshStats) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting self.columns = [ ("sid", True, "SID", 0.0, "%s") , ("hand", False, "Hand", 0.0, "%s") # true not allowed for this line , ("n", True, "Hds", 1.0, "%d") , ("start", True, "Start", 1.0, "%d") , ("end", True, "End", 1.0, "%d") , ("hph", True, "Hands/h", 1.0, "%d") , ("profit", True, "Profit", 1.0, "%s") #, ("avgseats", True, "Seats", 1.0, "%3.1f") #, ("vpip", True, "VPIP", 1.0, "%3.1f") #, ("pfr", True, "PFR", 1.0, "%3.1f") #, ("pf3", True, "PF3", 1.0, "%3.1f") #, ("steals", True, "Steals", 1.0, "%3.1f") #, ("saw_f", True, "Saw_F", 1.0, "%3.1f") #, ("sawsd", True, "SawSD", 1.0, "%3.1f") #, ("wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f") #, ("wmsd", True, "W$SD", 1.0, "%3.1f") #, ("flafq", True, "FlAFq", 1.0, "%3.1f") #, ("tuafq", True, "TuAFq", 1.0, "%3.1f") #, ("rvafq", True, "RvAFq", 1.0, "%3.1f") #, ("pofafq", False, "PoFAFq", 1.0, "%3.1f") #, ("net", True, "Net($)", 1.0, "%6.2f") #, ("bbper100", True, "BB/100", 1.0, "%4.2f") #, ("rake", True, "Rake($)", 1.0, "%6.2f") #, ("variance", True, "Variance", 1.0, "%5.2f") ] self.stats_frame = None self.stats_vbox = None self.detailFilters = [] # the data used to enhance the sql select #self.main_hbox = gtk.HBox(False, 0) #self.main_hbox.show() self.main_hbox = gtk.HPaned() self.stats_frame = gtk.Frame() self.stats_frame.show() self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) # self.fillStatsFrame(self.stats_vbox) #self.main_hbox.pack_start(self.filters.get_vbox()) #self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) self.main_hbox.pack1(self.filters.get_vbox()) self.main_hbox.pack2(self.stats_frame) self.main_hbox.show() # make sure Hand column is not displayed #[x for x in self.columns if x[0] == 'hand'][0][1] = False def get_vbox(self): """returns the vbox of this thread""" return self.main_hbox def refreshStats(self, widget, data): try: self.stats_vbox.destroy() except AttributeError: pass self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) def fillStatsFrame(self, vbox): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() seats = self.filters.getSeats() sitenos = [] playerids = [] # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _q = self.sql.query['getPlayerId'] _name = Charset.to_utf8(heroes[site]) #print 'DEBUG(_name) :: %s' % _name self.cursor.execute(_q, (_name,)) # arg = tuple result = self.db.cursor.fetchall() if len(result) == 1: playerids.append(result[0][0]) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not playerids: print _("No player ids found") return if not limits: print _("No limits found") return self.createStatsPane(vbox, playerids, sitenos, limits, seats) def createStatsPane(self, vbox, playerids, sitenos, limits, seats): starttime = time() (results, opens, closes, highs, lows) = self.generateDatasets(playerids, sitenos, limits, seats) self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.generateGraph(opens, closes, highs, lows) vbox.pack_start(self.graphBox) # Separator sep = gtk.HSeparator() vbox.pack_start(sep, expand=False, padding=3) sep.show_now() vbox.show_now() heading = gtk.Label(self.filterText['handhead']) heading.show() vbox.pack_start(heading, expand=False, padding=3) # Scrolled window for detailed table (display by hand) swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.show() vbox.pack_start(swin, expand=True, padding=3) vbox1 = gtk.VBox(False, 0) vbox1.show() swin.add_with_viewport(vbox1) self.addTable(vbox1, results) self.db.rollback() print _("Stats page displayed in %4.2f seconds") % (time() - starttime) #end def fillStatsFrame(self, vbox): def generateDatasets(self, playerids, sitenos, limits, seats): THRESHOLD = 1800 # Minimum number of seconds between consecutive hands before being considered a new session PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc (FiXME: user configurable) # Get a list of all handids and their timestampts #FIXME: Query still need to filter on blind levels q = self.sql.query['sessionStats'] start_date, end_date = self.filters.getDates() q = q.replace("<datestest>", " between '" + start_date + "' and '" + end_date + "'") nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)",")") q = q.replace("<player_test>", nametest) q = q.replace("<ampersand_s>", "%s") self.db.cursor.execute(q) hands = self.db.cursor.fetchall() # Take that list and create an array of the time between hands times = map(lambda x:long(x[0]), hands) handids = map(lambda x:int(x[1]), hands) winnings = map(lambda x:float(x[4]), hands) #print "DEBUG: len(times) %s" %(len(times)) diffs = diff(times) # This array is the difference in starttime between consecutive hands diffs2 = append(diffs,THRESHOLD + 1) # Append an additional session to the end of the diffs, so the next line # includes an index into the last 'session' index = nonzero(diffs2 > THRESHOLD) # This array represents the indexes into 'times' for start/end times of sessions # times[index[0][0]] is the end of the first session, #print "DEBUG: len(index[0]) %s" %(len(index[0])) if len(index[0]) > 0: #print "DEBUG: index[0][0] %s" %(index[0][0]) #print "DEBUG: index %s" %(index) pass else: index = [[0]] #print "DEBUG: index %s" %(index) #print "DEBUG: index[0][0] %s" %(index[0][0]) pass total = 0 first_idx = 0 lowidx = 0 uppidx = 0 opens = [] closes = [] highs = [] lows = [] results = [] cum_sum = cumsum(winnings) cum_sum = cum_sum/100 sid = 1 # Take all results and format them into a list for feeding into gui model. for i in range(len(index[0])): hds = index[0][i] - first_idx + 1 # Number of hands in session if hds > 0: stime = strftime("%d/%m/%Y %H:%M", localtime(times[first_idx])) # Formatted start time etime = strftime("%d/%m/%Y %H:%M", localtime(times[index[0][i]])) # Formatted end time minutesplayed = (times[index[0][i]] - times[first_idx])/60 if minutesplayed == 0: minutesplayed = 1 minutesplayed = minutesplayed + PADDING hph = hds*60/minutesplayed # Hands per hour won = sum(winnings[first_idx:index[0][i]])/100.0 hwm = max(cum_sum[first_idx:index[0][i]]) lwm = min(cum_sum[first_idx:index[0][i]]) open = (sum(winnings[:first_idx]))/100 close = (sum(winnings[:index[0][i]]))/100 #print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, index[0][i], lwm, hwm, open, close) results.append([sid, hds, stime, etime, hph, won]) opens.append(open) closes.append(close) highs.append(hwm) lows.append(lwm) #print "DEBUG: Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won) total = total + (index[0][i] - first_idx) first_idx = index[0][i] + 1 sid = sid+1 else: print "hds <= 0" return (results, opens, closes, highs, lows) def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig is not None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("***Error: ")+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) raise def generateGraph(self, opens, closes, highs, lows): self.clearGraphData() # print "DEBUG:" # print "highs = %s" % highs # print "lows = %s" % lows # print "opens = %s" % opens # print "closes = %s" % closes # print "len(highs): %s == len(lows): %s" %(len(highs), len(lows)) # print "len(opens): %s == len(closes): %s" %(len(opens), len(closes)) # # for i in range(len(highs)): # print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i]) # print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i]) self.ax = self.fig.add_subplot(111) self.ax.set_title(_("Session candlestick graph")) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Sessions"), fontsize = 12) self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) candlestick2(self.ax, opens, closes, highs, lows, width=0.50, colordown='r', colorup='g', alpha=1.00) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() def addTable(self, vbox, results): row = 0 sqlrow = 0 colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4 # pre-fetch some constant values: cols_to_show = [x for x in self.columns if x[colshow]] self.liststore = gtk.ListStore(*([str] * len(cols_to_show))) for row in results: iter = self.liststore.append(row) view = gtk.TreeView(model=self.liststore) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) vbox.add(view) textcell = gtk.CellRendererText() textcell50 = gtk.CellRendererText() textcell50.set_property('xalign', 0.5) numcell = gtk.CellRendererText() numcell.set_property('xalign', 1.0) listcols = [] # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(cols_to_show): s = column[colheading] listcols.append(gtk.TreeViewColumn(s)) view.append_column(listcols[col]) if column[colformat] == '%s': if column[colxalign] == 0.0: listcols[col].pack_start(textcell, expand=True) listcols[col].add_attribute(textcell, 'text', col) else: listcols[col].pack_start(textcell50, expand=True) listcols[col].add_attribute(textcell50, 'text', col) listcols[col].set_expand(True) else: listcols[col].pack_start(numcell, expand=True) listcols[col].add_attribute(numcell, 'text', col) listcols[col].set_expand(True) vbox.show_all()
class GuiGraphViewer(threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes": True, "Sites": True, "Games": True, "Currencies": True, "Limits": True, "LimitSep": True, "LimitType": True, "Type": False, "UseType": 'ring', "Seats": False, "SeatSep": False, "Dates": True, "GraphOps": True, "Groups": False, "Button1": True, "Button2": True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.exportFile = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() games = self.filters.getGames() currencies = self.filters.getCurrencies() graphops = self.filters.getGraphOps() names = "" for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) names = names + "\n" + _hname + " on " + site if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return if not limits: print _("No limits found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, blue, red, orange) = self.getRingProfitGraph(playerids, sitenos, limits, games, currencies, graphops['dspin']) print _("Graph generated in: %s") % (time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Hands")) # SET LABEL FOR X AXIS self.ax.set_ylabel(graphops['dspin']) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) self.ax.plot(green, color='green', label=_('Hands') + ': %d\n' % len(green) + _('Profit') + ': %.2f' % green[-1]) self.ax.plot(blue, color='blue', label=_('Showdown') + ': $%.2f' % (blue[-1])) self.ax.plot(red, color='red', label=_('Non-showdown') + ': $%.2f' % (red[-1])) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() else: self.ax.set_title((_("Profit graph for ring games") + names)) #Draw plot self.ax.plot(green, color='green', label=_('Hands') + ': %d\n' % len(green) + _('Profit') + ': (%s): %.2f' % (graphops['dspin'], green[-1])) if graphops['showdown'] == 'ON': self.ax.plot(blue, color='blue', label=_('Showdown') + ' (%s): %.2f' % (graphops['dspin'], blue[-1])) if graphops['nonshowdown'] == 'ON': self.ax.plot(red, color='red', label=_('Non-showdown') + ' (%s): %.2f' % (graphops['dspin'], red[-1])) if graphops['ev'] == 'ON': self.ax.plot(orange, color='orange', label=_('All-in EV') + ' (%s): %.2f' % (graphops['dspin'], orange[-1])) if sys.version[0:3] == '2.5': self.ax.legend(loc='upper left', shadow=True, prop=FontProperties(size='smaller')) else: self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) #end of def showClicked def getRingProfitGraph(self, names, sites, limits, games, currencies, units): # tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" if units == '$': tmp = self.sql.query['getRingProfitAllHandsPlayerIdSiteInDollars'] elif units == 'BB': tmp = self.sql.query['getRingProfitAllHandsPlayerIdSiteInBB'] start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #nametest = nametest.replace("L", "") q = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: q.append(n) if len(q) > 0: gametest = str(tuple(q)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)", ")") gametest = gametest.replace("u'", "'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" tmp = tmp.replace("<game_test>", gametest) limittest = self.filters.get_limits_where_clause(limits) q = [] for n in currencies: if currencies[n]: q.append(n) currencytest = str(tuple(q)) currencytest = currencytest.replace(",)", ")") currencytest = currencytest.replace("u'", "'") currencytest = "AND gt.currency in %s" % currencytest if type == 'ring': limittest = limittest + " and gt.type = 'ring' " elif type == 'tour': limittest = limittest + " and gt.type = 'tour' " #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace("<limit_test>", limittest) tmp = tmp.replace("<currency_test>", currencytest) tmp = tmp.replace(",)", ")") #print "DEBUG: sql query:" #print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None, None) green = map(lambda x: float(x[1]), winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) orange = map(lambda x: float(x[3]), winnings) greenline = cumsum(green) blueline = cumsum(blue) redline = cumsum(red) orangeline = cumsum(orange) return (greenline / 100, blueline / 100, redline / 100, orangeline / 100) #end of def getRingProfitGraph def exportGraph(self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. png_filter = gtk.FileFilter() png_filter.add_pattern('*.png') dia_chooser = gtk.FileChooserDialog( title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dia_chooser.set_filter(png_filter) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) if self.exportFile is not None: dia_chooser.set_filename( self.exportFile ) # use previously chosen export path as default else: dia_chooser.set_current_name('fpdbgraph.png') response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return self.exportFile = dia_chooser.get_filename() dia_chooser.destroy() self.fig.savefig(self.exportFile, format="png") # Display info box to confirm graph created. diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class ShowSpectrumPanel(gtk.VBox): def __init__(self, options=ProcessOptions(), parent=None): gtk.VBox.__init__(self) self.header = None self.channels = None self.ellipticity = None self.xdata = None self.options=options self._create_widgets() def show_spectrum_file(self, input_fn, options=None): results = jwslib.read_file(input_fn) error = True if results[0] == jwslib.JWS_ERROR_SUCCESS: header = results[1] channels = results[2] if len(channels) > 0: error = False if error: return False else: if options is not None: self.options = options self.show_spectrum(header, channels) return True def show_spectrum(self, header, channels, options=None): self.header = header self.channels = channels if options is not None: self.options = options self.xdata = arange(header.x_for_first_point, #start header.x_for_last_point+header.x_increment, #end+incr. header.x_increment) #increment self.ellipticity = array(self.channels[0], float32) self._configure_widgets() self._plot_spectrum() def _smoothing_changed_cb(self, widget, user_data=None): self._refresh_options() if self.options.smoothing and (self.options.smoothing_type == "sg"): self.sp_hbox.show() else: self.sp_hbox.hide() self._plot_spectrum() def _plot_spectrum(self): self.figure.clear() # Construct xdata (an array with x value for each point) m = self.options.m p = self.figure.add_subplot(111) if self.options.smoothing: if (m % 2) == 0: m += 1 if self.options.smoothing_type == "mm": smoothed = pysmoothing.mean_movement(self.ellipticity, m) elif self.options.smoothing_type == "sg": smoothed = pysmoothing.sgolayfilt(self.ellipticity, self.options.p, m) p.plot( self.xdata, self.ellipticity, "b", # a- Original data self.xdata, smoothed, "r") # b- Processed data #p.legend(("Original","Processed")) else: p.plot( self.xdata, self.ellipticity) self.canvas.draw() def _refresh_options(self,widget=None): st = self.smoothing_combo.get_active() if st==2: self.options.smoothing = False else: self.options.smoothing = True if st==1: self.options.smoothing_type = "sg" elif st==0: self.options.smoothing_type = "mm" self.options.m = int(self.m_spinner.get_value()) self.options.set_clamped_p(int(self.p_spinner.get_value())) def _configure_widgets(self): self.m_spinner.set_value(self.options.m) if self.options.smoothing_type == "mm": self.smoothing_combo.set_active(0) elif self.options.smoothing_type == "sg": self.smoothing_combo.set_active(1) else: self.smoothing_combo.set_active(2) self.p_spinner.set_value(self.options.get_clamped_p()) self.smoothing_combo.connect("changed", self._smoothing_changed_cb) self.m_spinner.connect("value-changed", self._smoothing_changed_cb) self.p_spinner.connect("value-changed", self._smoothing_changed_cb) if self.options.smoothing and (self.options.smoothing_type == "sg"): self.sp_hbox.show() else: self.sp_hbox.hide() def _create_widgets(self): def create_label(text): label = gtk.Label(text) label.show() return label self.smoothing_list = gtk.ListStore(str) smoothing_types = ("Mean-movement", "Savitsky-Golay", _("No smoothing")) for smt in smoothing_types: self.smoothing_list.append([smt]) cell = gtk.CellRendererText() self.smoothing_combo = gtk.ComboBox(self.smoothing_list) self.smoothing_combo.pack_start(cell, True) self.smoothing_combo.add_attribute(cell, 'text', 0) self.smoothing_combo.show() self.m_spinner = gtk.SpinButton() self.m_spinner.set_range(5, 25) self.m_spinner.set_increments(1,5) self.m_spinner.show() self.p_spinner = gtk.SpinButton() self.p_spinner.set_range(1,6) self.p_spinner.set_increments(1,1) self.p_spinner.show() sc_hbox = gtk.HBox() sc_hbox.pack_start(create_label(_("Smoothing type:")), False, False, 0) sc_hbox.pack_end(self.smoothing_combo, False, True, 0) sc_hbox.show() sm_hbox = gtk.HBox() sm_hbox.pack_start(create_label(_("Smoothing level (m):")), False, False, 0) sm_hbox.pack_end(self.m_spinner, False, False, 0) sm_hbox.show() sp_hbox = gtk.HBox() sp_hbox.pack_start(create_label(_("S-G filter order (p):")), False, False, 0) sp_hbox.pack_end(self.p_spinner, False, False, 0) sp_hbox.show() self.sp_hbox = sp_hbox self.figure = Figure(figsize=(5,4)) self.canvas = FigureCanvas(self.figure) self.canvas.show() self.pack_start(sc_hbox, False, False, 0) self.pack_start(sm_hbox, False, False, 0) self.pack_start(sp_hbox, False, False, 0) self.pack_start(self.canvas, True, True, 0)
class PPlanGUI: def __init__(self): gladefile = os.path.join(roslib.packages.get_pkg_dir('pplan'), "glade/pplan_gui.glade") self.windowname = "main_window" self.w_tree = gtk.glade.XML(gladefile, self.windowname) dic = {'on_main_window_destroy' : gtk.main_quit, 'on_get_data_button_clicked' : self.get_data, 'on_make_graph_button_clicked' : self.make_graph, 'on_calc_kernel_button_clicked' : self.calc_kernel, 'on_plan_path_button_clicked' : self.plan_path, } self.w_tree.signal_autoconnect(dic) main_window = self.w_tree.get_widget('main_window') # setup matplotlib stuff on first notebook page (empty graph) self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Longitude') self.axis.set_ylabel('Latitude') self.axis.set_title('') self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphview = self.w_tree.get_widget('vbox1') self.graphview.pack_start(self.canvas, True, True) self.nav_bar = NavigationToolbar(self.canvas, main_window) self.graphview.pack_start(self.nav_bar, False, True) run_dir = sys.argv[1] self.settings = pplan.PPlanSettings(run_dir) # initialize the data directory, if not done already self.store = ppas.Store(self.settings.data_dir) self.plot_graph() self.plot_path() def get_data(self, event): ''' Start a new thread to fetch data. ''' progress_bar = self.w_tree.get_widget('get_data_progress_bar') out = pplan.GTKOutputter(progress_bar) s = self.settings rp = s.roi_properties tp = s.training_properties save_dir = os.path.join(s.data_dir, 'training_data') downloader = pplan.ROMSDownloader( out, ppas.Store(save_dir), rp['lat0']-0.03, rp['lat1']+0.03, rp['lon0']-0.03, rp['lon1']+0.03, rp['depth']-10., rp['depth']+10., tp['dates']) downloader.start() def make_graph(self, event): progress_bar = self.w_tree.get_widget('make_graph_progress_bar') out = pplan.GTKOutputter(progress_bar) graph_maker = pplan.GraphMaker( out, ppas.Store(self.settings.data_dir), self.settings.roi_properties, self.settings.graph_properties) graph_maker.start() def calc_kernel(self, event): progress_bar = self.w_tree.get_widget('calc_kernel_progress_bar') out = pplan.GTKOutputter(progress_bar) save_dir = self.settings.data_dir training_data_dir = os.path.join(self.settings.data_dir, 'training_data') points_dir = self.settings.data_dir cov_trainer = pplan.CovarianceTrainer( out, ppas.Store(save_dir), ppas.Store(training_data_dir), ppas.Store(points_dir), self.settings.roi_properties['qoi'], self.settings.roi_properties['starttime']) cov_trainer.start() def plan_path(self, event): progress_bar = self.w_tree.get_widget('plan_path_progress_bar') out = pplan.GTKOutputter(progress_bar) save_dir = self.settings.data_dir graph_dir = self.settings.data_dir path_planner = pplan.PathPlanner( out, ppas.Store(save_dir), ppas.Store(graph_dir), self.settings.planner_properties) path_planner.start() def plot_graph(self): try: G = self.store['G'] graph_plotter = ppas.plot.GraphPlotter(G, 'latlon') graph_plotter.plot(ax=self.axis, nodenames=False) except Exception: pass def plot_path(self): try: G = self.store['G'] P = self.store['P'] graph_plotter = ppas.plot.GraphPlotter(G, 'latlon') graph_plotter.plot_path(P, ax=self.axis, nodenames=False) except Exception: pass def main(self): gtk.main()
class SmoothingSelectionDialog(gtk.Dialog): def __init__(self, header, channels, options, parent=None, title=_("Choose smoothing type"), buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK)): gtk.Dialog.__init__(self, title=title, parent=parent, flags=gtk.DIALOG_MODAL, buttons=buttons) self.header = header self.channels = channels self.options = options self.xdata = arange(header.x_for_first_point, #start header.x_for_last_point+header.x_increment, #end+incr. header.x_increment) #increment self.ellipticity = array(self.channels[0], float32) self._create_widgets() self._configure_widgets() self._plot_spectrum() def _smoothing_changed_cb(self, widget, user_data=None): self._refresh_options() if self.options.smoothing and (self.options.smoothing_type == "sg"): self.sp_hbox.show() else: self.sp_hbox.hide() self._plot_spectrum() def _plot_spectrum(self): self.figure.clear() # Construct xdata (an array with x value for each point) m = self.options.m p = self.figure.add_subplot(111) if self.options.smoothing: if (m % 2) == 0: m += 1 if self.options.smoothing_type == "mm": smoothed = pysmoothing.mean_movement(self.ellipticity, m) elif self.options.smoothing_type == "sg": smoothed = pysmoothing.sgolayfilt(self.ellipticity, self.options.p, m) p.plot( self.xdata, self.ellipticity, "b", # a- Original data self.xdata, smoothed, "r") # b- Processed data #p.legend(("Original","Processed")) else: p.plot( self.xdata, self.ellipticity) self.canvas.draw() def _refresh_options(self,widget=None): st = self.smoothing_combo.get_active() if st==2: self.options.smoothing = False else: self.options.smoothing = True if st==1: self.options.smoothing_type = "sg" elif st==0: self.options.smoothing_type = "mm" self.options.m = int(self.m_spinner.get_value()) self.options.set_clamped_p(int(self.p_spinner.get_value())) def _configure_widgets(self): self.m_spinner.set_value(self.options.m) if self.options.smoothing_type == "mm": self.smoothing_combo.set_active(0) elif self.options.smoothing_type == "sg": self.smoothing_combo.set_active(1) else: self.smoothing_combo.set_active(2) self.p_spinner.set_value(self.options.get_clamped_p()) self.smoothing_combo.connect("changed", self._smoothing_changed_cb) self.m_spinner.connect("value-changed", self._smoothing_changed_cb) self.p_spinner.connect("value-changed", self._smoothing_changed_cb) if self.options.smoothing and (self.options.smoothing_type == "sg"): self.sp_hbox.show() else: self.sp_hbox.hide() def _create_widgets(self): def create_label(text): label = gtk.Label(text) label.show() return label self.smoothing_list = gtk.ListStore(str) smoothing_types = ("Mean-movement", "Savitsky-Golay", _("No smoothing")) for smt in smoothing_types: self.smoothing_list.append([smt]) cell = gtk.CellRendererText() self.smoothing_combo = gtk.ComboBox(self.smoothing_list) self.smoothing_combo.pack_start(cell, True) self.smoothing_combo.add_attribute(cell, 'text', 0) self.smoothing_combo.show() self.m_spinner = gtk.SpinButton() self.m_spinner.set_range(5, 25) self.m_spinner.set_increments(1,5) self.m_spinner.show() self.p_spinner = gtk.SpinButton() self.p_spinner.set_range(1,6) self.p_spinner.set_increments(1,1) self.p_spinner.show() sc_hbox = gtk.HBox() sc_hbox.pack_start(create_label(_("Smoothing type:")), False, False, 0) sc_hbox.pack_end(self.smoothing_combo, False, True, 0) sc_hbox.show() sm_hbox = gtk.HBox() sm_hbox.pack_start(create_label(_("Smoothing level(m):")), False, False, 0) sm_hbox.pack_end(self.m_spinner, False, False, 0) sm_hbox.show() sp_hbox = gtk.HBox() sp_hbox.pack_start(create_label(_("S-G filter order (p):")), False, False, 0) sp_hbox.pack_end(self.p_spinner, False, False, 0) sp_hbox.show() self.sp_hbox = sp_hbox self.figure = Figure(figsize=(5,4)) self.canvas = FigureCanvas(self.figure) self.canvas.show() self.vbox.pack_start(sc_hbox, False, False, 0) self.vbox.pack_start(sm_hbox, False, False, 0) self.vbox.pack_start(sp_hbox, False, False, 0) self.vbox.pack_start(self.canvas, True, True, 0) self.set_default_size(400,400)
class GuiTourneyGraphViewer: def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes": True, "Sites": True, "Games": False, "Currencies": True, "Limits": False, "LimitSep": False, "LimitType": False, "Type": False, "UseType": 'tour', "Seats": False, "SeatSep": False, "Dates": True, "GraphOpsTour": True, "Groups": False, "Button1": True, "Button2": True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() #update the graph at entry (simulate a "Refresh Graph" click) gobject.GObject.emit(self.filters.Button1, "clicked") def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() currencies = self.filters.getCurrencies() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, datesXAbs) = self.getData(playerids, sitenos, currencies) print _("Graph generated in: %s") % (time() - starttime) currencyLabel = ','.join(['%s' % key for key in currencies.keys()]) #Set axis labels and grid overlay properites self.ax.set_ylabel(currencyLabel, fontsize=12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000. ]) self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + '(' + currencyLabel + '): %.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Tournament Results")) useDates = True #nothing to draw if (len(green) == 0): return #Get the dates of tourneys #if first tourney has no date, get the most ancient date and assume it's his one if datesXAbs[0] is None: i = 1 while i < len(datesXAbs) and type(datesXAbs[i]) is None: i = i + 1 if i == len(datesXAbs): print "Wow wow wow : no dates in your whole tourneys" useDates = False else: datesXAbs[0] = datesXAbs[i] #now convert date to dateTime format if useDates: for i in range(0, len(datesXAbs)): if datesXAbs[i] is None: datesXAbs[i] = datesXAbs[i - 1] else: datesXAbs[i] = datetime.datetime.strptime( datesXAbs[i], "%Y-%m-%d %H:%M:%S") datesXAbs[i] = datesXAbs[i].strftime('%d/%m') mycolor = 'red' if green[0] > 0: mycolor = 'green' self.ax.plot([0, 1], [0, green[0]], color=mycolor, label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + '(' + currencyLabel + '): %.2f' % green[-1]) for i in range(1, len(green)): final = green[i] - green[i - 1] mycolor = 'red' if (green[i] > 0): mycolor = 'green' self.ax.plot([i, i + 1], [green[i - 1], green[i]], color=mycolor) if (i % (len(green) / 5) == 0): gain = "" if (green[i] == 0): gain = "=" else: if (green[i] > 0): gain = "+" gain += str(green[i]) self.ax.annotate(gain, xy=(i, 0), color=mycolor, xycoords=('data', 'axes fraction'), xytext=(0, 18), textcoords='offset points', va='top', ha='left') if useDates: self.ax.annotate(datesXAbs[i], xy=(i, 0), xycoords=('data', 'axes fraction'), xytext=(0, -18), textcoords='offset points', va='top', ha='left') #~self.ax.axhline(0, color='black', lw=2) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) #end of def showClicked def getData(self, names, sites, currencies): tmp = self.sql.query['tourneyGraph'] # print "DEBUG: getData. :" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) currencytest = str(tuple()) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) currencytest = str(tuple(currencies)) currencytest = currencytest.replace(",)", ")") currencytest = currencytest.replace("u'", "'") currencytest = "AND tt.currency in %s" % currencytest tmp = tmp.replace("<currency_test>", currencytest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") # print "DEBUG: sql query:", tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None) green = map(lambda x: float(x[1]), winnings) datesXAbs = map(lambda x: x[8], winnings) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) return (greenline / 100, datesXAbs) def exportGraph(self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog( title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename( self.exportFile ) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename( ) + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class Backend( backend.Backend ): def init(self): # line_cache: key = id(Curve), value=mpl line object self.line_cache = dict() self.layer_to_axes = dict() self.axes_to_layer = dict() self.layers_cache = list() # copy of self.plot.layers def connect(self): logger.debug("Opening matplotlib session.") self.figure = Figure(dpi=100, facecolor="white") # figsize=(5,4), dpi=100) self.canvas = FigureCanvas(self.figure) self.canvas.show() self.line_cache.clear() self.layer_to_axes.clear() self.axes_to_layer.clear() backend.Backend.connect(self) logger.debug("Init finished") def disconnect(self): logger.debug("Closing matplotlib session.") if not self.canvas is None: self.canvas.destroy() self.canvas = None if not self.figure is None: self.figure = None backend.Backend.disconnect(self) #---------------------------------------------------------------------- def arrange(self, rows=1, cols=1): layers = self.plot.layers n = len(layers) if n > (rows*cols): rows = int((rows*cols) / n) + 1 cols = rows * n #raise ValueError("Not enough rows and cols for all layers!") self.figure.clear() self.figure.axes = [] self.layer_to_axes.clear() self.axes_to_layer.clear() self.layers_cache = list() j = 1 for layer in layers: print "Setting up layer", layer axes = self.figure.add_subplot("%d%d%d" % (rows,cols,j)) self.layer_to_axes[layer] = axes self.axes_to_layer[axes] = layer self.layers_cache.append(layer) j += 1 def draw_layer(self, layer, group_info): ax = self.layer_to_axes[layer] print "DRAWING AXES ", ax ax.lines = [] line_cache = [] line_count = 0 last_cx = -1 # Default values come in two flavors: # group-wise and single default values group_colors = uwrap.get(layer, 'group_colors') group_styles = uwrap.get(layer, 'group_styles') group_markers = uwrap.get(layer, 'group_markers') #default_color = 'r' default_color = None default_style = 'solid' default_marker = 'None' #:layer.visible if uwrap.get(layer, 'visible') is False: return #:layer.title title = uwrap.get(layer, 'title', None) if title is not None: ax.set_title(title) #:layer.grid grid = uwrap.get(layer, 'grid') ax.grid(grid) #:layer.lines for line in layer.lines: data_to_plot = [] #:line.visible if uwrap.get(line, 'visible') is False: if line in ax.lines: ax.lines.remove(line) continue ds = self.get_line_source(line) table = self.get_table(ds) cx, cy = self.get_column_indices(line) xdata, ydata = self.get_table_data(table, cx, cy) #:line.row_first #:line.row_last def limit_data(data, start, end): try: return data[start:end] except IndexError: backend.BackendError("Index range '%s'out of bounds!" % (start,end) ) start, end = line.row_first, line.row_last xdata = limit_data(xdata, start, end) ydata = limit_data(ydata, start, end) #:line.style global linestyle_mappings default = default_style or group_styles[line_count % len(group_styles)] style = uwrap.get(line, 'style', default) style = linestyle_mappings[style] #:line.marker global linemarker_mappings default = default_marker or group_markers[line_count % len(group_markers)] marker = uwrap.get(line, 'marker', default) marker = linemarker_mappings[marker] #:line.width width = uwrap.get(line, 'width') #:line.color default = default_color or group_colors[line_count % len(group_colors)] color = uwrap.get(line, 'color', default) #--- PLOT LINE --- l, = ax.plot( xdata, ydata, linewidth=width, linestyle=style, marker=marker, color=color) line_cache.append(l) label = self.get_line_label(line, table=table, cy=cy) l.set_label(label) line_count += 1 # # # # additional lines # # # p = len(xdata) # if p > 2: p = p/2 # atpoint = xdata[max(p-1,0)] # print "Printing vertical line at ", atpoint # ax.axvline(atpoint) #:layer.legend legend = uwrap.get(layer, 'legend') if legend is not None and line_count > 0: visible = uwrap.get(legend, 'visible') if visible is True: #:legend.label:TODO label = uwrap.get(legend, 'visible') if label is not None: pass #:legend.border:OK # (see below but keep it here!) border = uwrap.get(legend, 'border') #:legend.position TODO position = uwrap.get(legend, 'position', 'best') if position == 'at position': position = (uwrap.get(legend, 'x'), uwrap.get(legend, 'y')) # create legend entries from line labels labels = [l.get_label() for l in line_cache] legend = ax.legend(line_cache, labels, loc=position) legend.draw_frame(border) else: ax.legend_ = None else: ax.legend_ = None #:layer.axes for (key, axis) in layer.axes.iteritems(): #:axis.label #:axis.scale #:axis.start #:axis.end label = uwrap.get(axis, 'label') scale = uwrap.get(axis, 'scale') start = uwrap.get(axis, 'start') end = uwrap.get(axis, 'end') print "START = %s, END = %s" % (str(start), str(end)) if key == 'x': set_label = ax.set_xlabel set_scale = ax.set_xscale set_start = (lambda l: ax.set_xlim(xmin=l)) set_end = (lambda l: ax.set_xlim(xmax=l)) elif key == 'y': set_label = ax.set_ylabel set_scale = ax.set_yscale set_start = (lambda l: ax.set_ylim(ymin=l)) set_end = (lambda l: ax.set_ylim(ymax=l)) else: raise RuntimeError("Invalid axis key '%s'" % key) if label is not None: set_label(label) if scale is not None: set_scale(scale) if start is not None: set_start(start) if end is not None: set_end(end) def draw(self): logger.debug("Matplotlib: draw()") self.check_connection() # plot all curves together in one plot legend_list = [] # for legend later on curve_count = 0 # if self.plot.layers != self.layers_cache: self.arrange() for layer in self.plot.layers: group_info = {} self.draw_layer(layer, group_info) self.canvas.draw()
class Backend( backend.Plotter ): def init(self): # line_cache: key = id(Curve), value=mpl line object self.line_cache = dict() self.layer_to_axes = dict() self.axes_to_layer = dict() self.layers_cache = list() # copy of self.plot.layers def connect(self): logger.debug("Opening matplotlib session.") self.figure = Figure(dpi=100, facecolor="white") # figsize=(5,4), dpi=100) self.canvas = FigureCanvas(self.figure) self.canvas.show() self.line_cache.clear() self.layer_to_axes.clear() self.axes_to_layer.clear() backend.Plotter.connect(self) logger.debug("Init finished") def disconnect(self): logger.debug("Closing matplotlib session.") if not self.canvas is None: self.canvas.destroy() self.canvas = None if not self.figure is None: self.figure = None backend.Plotter.disconnect(self) #---------------------------------------------------------------------- def arrange(self, rows=1, cols=1): layers = self.plot.layers n = len(layers) if n > (rows*cols): rows = int((rows*cols) / n) + 1 cols = rows * n #raise ValueError("Not enough rows and cols for all layers!") self.figure.clear() self.figure.axes = [] self.layer_to_axes.clear() self.axes_to_layer.clear() self.layers_cache = list() j = 1 for layer in layers: print "Setting up layer", layer axes = self.figure.add_subplot("%d%d%d" % (rows,cols,j)) self.layer_to_axes[layer] = axes self.axes_to_layer[axes] = layer self.layers_cache.append(layer) j += 1 def draw_layer(self, layer, group_info): ax = self.layer_to_axes[layer] print "DRAWING AXES ", ax ax.lines = [] line_cache = [] line_count = 0 last_cx = -1 # Default values come in two flavors: # group-wise and single default values group_colors = uwrap.get(layer, 'group_colors') group_styles = uwrap.get(layer, 'group_styles') group_markers = uwrap.get(layer, 'group_markers') #default_color = 'r' default_color = None default_style = 'solid' default_marker = 'None' #:layer.visible if uwrap.get(layer, 'visible') is False: return #:layer.title title = uwrap.get(layer, 'title', None) if title is not None: ax.set_title(title) #:layer.grid grid = uwrap.get(layer, 'grid') ax.grid(grid) #:layer.lines for line in layer.lines: data_to_plot = [] #:line.visible if uwrap.get(line, 'visible') is False: if line in ax.lines: ax.lines.remove(line) continue #:line.source if line.source is None: logger.warn("No Dataset specified for Line!") continue else: ds = line.source if ds.is_empty() is True: logger.warn("No data for Line!") continue table = ds.get_data() if not isinstance(table, Table): raise TypeError("Matplotlib Backend currently only supports data of type Table, while this is of %s" % type(table)) #:line.cx if line.cx is None or line.cy is None: logger.error("No x or y source given for Line. Line skipped.") continue else: cx, cy = line.cx, line.cy try: xdata = table[cx] except IndexError: logger.error("X-Index out of range (%s). Line skipped." % cx) continue #:line.cy try: ydata = table[cy] except IndexError: logger.error("Y-Index out of range (%s). Line skipped." % cy) continue #:line.style global linestyle_mappings default = default_style or group_styles[line_count % len(group_styles)] style = uwrap.get(line, 'style', default) style = linestyle_mappings[style] #:line.marker global linemarker_mappings default = default_marker or group_markers[line_count % len(group_markers)] marker = uwrap.get(line, 'marker', default) marker = linemarker_mappings[marker] #:line.width width = uwrap.get(line, 'width') #:line.color default = default_color or group_colors[line_count % len(group_colors)] color = uwrap.get(line, 'color', default) #--- PLOT LINE --- l, = ax.plot( xdata, ydata, linewidth=width, linestyle=style, marker=marker, color=color) line_cache.append(l) # TODO: if we set the label afterwards, don't we then have a redraw? #:line.label label = line.label if label is None: column = table.column(cy) label = column.label or column.key or uwrap.get(line, 'label') l.set_label(label) line_count += 1 # # # # additional lines # # # p = len(xdata) # if p > 2: p = p/2 # atpoint = xdata[max(p-1,0)] # print "Printing vertical line at ", atpoint # ax.axvline(atpoint) #:layer.legend legend = uwrap.get(layer, 'legend') if legend is not None and line_count > 0: visible = uwrap.get(legend, 'visible') if visible is True: #:legend.label TODO label = uwrap.get(legend, 'visible') if label is not None: pass #:legend.border TODO border = uwrap.get(legend, 'border') #:legend.position TODO position = uwrap.get(legend, 'position', 'best') if position == 'at position': position = (uwrap.get(legend, 'x'), uwrap.get(legend, 'y')) # create legend entries from line labels labels = [l.get_label() for l in line_cache] ax.legend(line_cache, labels, loc=position) else: ax.legend_ = None else: ax.legend_ = None #:layer.axes for (key, axis) in layer.axes.iteritems(): #:axis.label #:axis.scale #:axis.start #:axis.end label = uwrap.get(axis, 'label') scale = uwrap.get(axis, 'scale') start = uwrap.get(axis, 'start') end = uwrap.get(axis, 'end') print "START = %s, END = %s" % (str(start), str(end)) if key == 'x': set_label = ax.set_xlabel set_scale = ax.set_xscale set_start = (lambda l: ax.set_xlim(xmin=l)) set_end = (lambda l: ax.set_xlim(xmax=l)) elif key == 'y': set_label = ax.set_ylabel set_scale = ax.set_yscale set_start = (lambda l: ax.set_ylim(ymin=l)) set_end = (lambda l: ax.set_ylim(ymax=l)) else: raise RuntimeError("Invalid axis key '%s'" % key) if label is not None: set_label(label) if scale is not None: set_scale(scale) if start is not None: set_start(start) if end is not None: set_end(end) def draw(self): logger.debug("Matplotlib: draw()") self.check_connection() # plot all curves together in one plot legend_list = [] # for legend later on curve_count = 0 # if self.plot.layers != self.layers_cache: self.arrange() for layer in self.plot.layers: group_info = {} self.draw_layer(layer, group_info) self.canvas.draw()
class appGui: def __init__(self): gladefile = "project2.glade" self.windowname = "gtkbench" self.wTree = gtk.glade.XML(gladefile, self.windowname) self.win = self.wTree.get_widget("gtkbench") self.win.maximize() dic = { "on_window1_destroy": gtk.main_quit, "on_button1_clicked": self.submitDB, "on_button3_clicked": self.fillTree, "on_notebook1_switch_page": self.selectNotebookPage, "on_treeview1_button_press_event": self.clickTree, "on_button2_clicked": self.createProjectGraph } self.wTree.signal_autoconnect(dic) # start with database selection self.wDialog = gtk.glade.XML("project2.glade", "dbSelector") # setup matplotlib stuff on first notebook page (empty graph) self.figure = Figure(figsize=(6, 4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Yepper') self.axis.set_ylabel('Flabber') self.axis.set_title('An Empty Graph') self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphview = self.wTree.get_widget("vbox1") self.graphview.pack_start(self.canvas, True, True) # setup listview for database self.listview = self.wTree.get_widget("treeview1") self.listmodel = gtk.ListStore(str, int, int, str, str) self.listview.set_model(self.listmodel) renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Name", renderer, text=0) column.set_clickable(True) column.set_sort_column_id(0) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Age", renderer, text=1) column.set_clickable(True) column.set_sort_column_id(1) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() column = gtk.TreeViewColumn("Shoesize", renderer, text=2) column.set_clickable(True) column.set_sort_column_id(2) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() column = gtk.TreeViewColumn("Created", renderer, text=3) column.set_clickable(True) column.set_sort_column_id(3) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) #self.listview.show() #renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Updated", renderer, text=4) column.set_clickable(True) column.set_sort_column_id(4) column.connect("clicked", self.createDBGraph) column.set_resizable(True) self.listview.append_column(column) return # callbacks. def submitDB(self, widget): while True: try: name = self.wTree.get_widget("entry1").get_text() age = self.wTree.get_widget("entry2").get_text() size = self.wTree.get_widget("entry3").get_text() assert name != "" assert age != "" assert size != "" dataUsr = name, age, size sd = DBStuff.Eb_db(host, user, passwd, db) sd.subMit(dataUsr) break except AssertionError: self.wDialog = gtk.glade.XML("project2.glade", "dbWarningEmpty") close = self.wDialog.get_widget("dbWarningEmpty") response = close.run() if response == gtk.RESPONSE_CLOSE: close.destroy() break except DBStuff.MySQLdb.IntegrityError: def callback(): self.wDialog = gtk.glade.XML("project2.glade", "dbWarningOverwrite") close = self.wDialog.get_widget("dbWarningOverwrite") response = close.run() if response == gtk.RESPONSE_CANCEL: close.destroy() if response == gtk.RESPONSE_OK: sd.delRow(name) wd = DBStuff.Eb_db(host, user, passwd, db) wd.subMit(dataUsr) close.destroy() callback() break def fillTree(self, widget): model = self.listmodel self.listmodel.clear() fg = DBStuff.Eb_db(host, user, passwd, db) fg.getData("Age") for i in range(len(fg.data)): # note: all data from table "bench" is appended, but that is something you don't want # possible solution: create a seperate table for the listbox (eg. ommit Timestamp, keep it in another table) self.listmodel.append(fg.data[i]) self.createDBGraph(self) def selectNotebookPage(self, widget, notebookpage, page_number): # if database page is selected (nr. 1 for now!), retrieve data if page_number == 1: self.fillTree(self) if page_number == 0: print "clicked first tab" def clickTree(self, treeview, event): if event.button == 3: x = int(event.x) y = int(event.y) time = event.time pthinfo = treeview.get_path_at_pos(x, y) if pthinfo != None: path, col, cellx, celly = pthinfo treeview.grab_focus() treeview.set_cursor(path, col, 0) self.wDialog = gtk.glade.XML("project2.glade", "treeRightClick") close = self.wDialog.get_widget("treeRightClick") response = close.run() if response == gtk.RESPONSE_OK: close.destroy() print x print y print pthinfo #self.popup.popup( None, None, None, event.button, time) return 1 def createProjectGraph(self, widget): while True: try: # empty axis if neccesary, and reset title and stuff self.axis.clear() self.axis.set_xlabel('Yepper') self.axis.set_ylabel('Flabber') self.axis.set_title('A Graph') self.axis.grid(True) # get data age = self.wTree.get_widget("entry2").get_text() size = self.wTree.get_widget("entry3").get_text() age != "" size != "" N = 1 ind = arange(N) # the x locations for the groups width = 0.35 # the width of the bars p1 = self.axis.bar(ind, int(age), width, color='r') p2 = self.axis.bar(ind + width, int(size), width, color='y') self.axis.legend((p1[0], p2[0]), ("Age", "Size"), shadow=True) #self.axis.set_xticks(ind+width, ('G1') ) self.axis.set_xlim(-width, len(ind)) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.grahview = self.wTree.get_widget("vbox1") self.grahview.pack_start(self.canvas, True, True) break except ValueError: self.wDialog = gtk.glade.XML("project2.glade", "cannotCreateProjGraph") close = self.wDialog.get_widget("cannotCreateProjGraph") response = close.run() if response == gtk.RESPONSE_OK: close.destroy() break def createDBGraph(self, widget): self.axis.clear() self.axis.set_xlabel('Samples (n)') self.axis.set_ylabel('Value (-)') self.axis.set_title( 'Another Graph (click on the columnheader to sort)') self.axis.grid(True) # get columns from listmodel age = [] for row in self.listmodel: age.append(row[1]) size = [] for row in self.listmodel: size.append(row[2]) # get number of rows N = len(age) ind = arange(N) # the x locations for the groups width = 0.35 # the width of the bars p1 = self.axis.bar(ind, age, width, color='b') p2 = self.axis.bar(ind + width, size, width, color='r') # destroy graph if it already exists while True: try: self.canvas2.destroy() break except: print "nothing to destroy" break self.canvas2 = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas2.show() self.grahview = self.wTree.get_widget("vbox2") self.grahview.pack_start(self.canvas2, True, True)
class JPlot: """Misspecification plot""" def __init__(self, app): #setup matplotlib stuff on first notebook page (empty graph) self.app = app # Plot defaults: self.imp_col = '#dd2244' self.nim_col = '#5533dd' # Create figure self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Modification index') self.axis.set_ylabel('Power') self.axis.set_title('Misspecifications') try: # omit missing observations parameters = [par for par in self.app.get_parameters() if \ par.mi <99.0 and par.power < 1.0 and par.epc < 99.0] self.mis = [par.mi for par in parameters] self.names = [par.name for par in parameters] self.powers = [par.power for par in parameters] self.ids = ["%s in group %s" % (par.name, par.group) for par in parameters] self.axis.scatter( self.mis, self.powers, c = [par.epc > self.app.get_field_value('delta') \ and self.imp_col or self.nim_col for par in parameters], linewidth=0, picker=30.0, vmin=self.imp_col, vmax = self.nim_col, ) self.axis.autoscale_view(True) #tight self.axis.axvline(self.app.get_critical(), color='#444444', linestyle='dashed') self.axis.axhline( y=float(self.app.get_field_value('power')), color='#444444', linestyle='dashed') except AttributeError: pass self.draw() def pick_handler(self, event): '''What happens if the user clicks a point in the plot''' index = event.ind[0] label = self.ids[index] sys.stderr.write('ind is %s'% index) sys.stderr.write('mousover %s\n' % label) x, y = self.mis[index], self.powers[index] self.axis.text(x, y, label) self.draw() def draw(self): 'Draw or re-draw the plot, possibly showing some labels' try: self.graphview.remove(self.canvas) except: pass self.canvas = FigureCanvasGTK(self.figure) self.canvas.mpl_connect('pick_event', self.pick_handler) self.canvas.show() self.graphview = self.app.tree.get_widget("vbox_plot") self.graphview.pack_start(self.canvas, True, True) def reload(self): 'Completely redo the whole plot.' self.graphview.remove(self.canvas) self.__init__(self.app)
class GuiTourneyGraphViewer (threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes" : True, "Sites" : True, "Games" : False, "Limits" : False, "LimitSep" : False, "LimitType" : False, "Type" : False, "UseType" : 'tour', "Seats" : False, "SeatSep" : False, "Dates" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() green = self.getData(playerids, sitenos) print _("Graph generated in: %s") %(time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Tournaments"), fontsize = 12) self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + ': $%.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Tournament Results")) #Draw plot self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + ': $%.2f' % green[-1]) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) #end of def showClicked def getData(self, names, sites): tmp = self.sql.query['tourneyResults'] print "DEBUG: getData" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") print "DEBUG: sql query:" print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return None green = map(lambda x:float(x[1]), winnings) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) return (greenline/100) def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename() + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class App: def __init__(self): self.gladefile = "property_hist.glade" self.widgetsTree = gtk.glade.XML(self.gladefile) dic = { "new_bins_number_selected": self.new_bins_number_selected, "on_range_check_toggled": self.on_range_check_toggled, "on_min_cutoff_box_activate": self.on_min_cutoff_box_activate, "on_max_cutoff_box_activate": self.on_max_cutoff_box_activate, "on_cumulative_check_toggled": self.on_cumulative_check_toggled, "on_normalized_check_toggled": self.on_normalized_check_toggled, "on_log_check_toggled": self.on_log_check_toggled, "on_obj_combo_changed": self.on_obj_combo_changed, "on_save_file_clicked": self.on_save_file_clicked, } self.widgetsTree.signal_autoconnect(dic) self.window = self.widgetsTree.get_widget("property_hist") if (self.window): self.window.connect("destroy", self.close_app) # -- initialization self.bins = 50 self.cumulative = False self.cumulative_check = self.widgetsTree.get_widget("cumulative_check") self.normalized = False self.normalized_check = self.widgetsTree.get_widget("normalized_check") self.log = False self.log_check = self.widgetsTree.get_widget("log_check") self.undefined_value = -99 self.property_names = [ "BIG_SOFT_DATA_CONT", "BIG_SOFT_IND_DATA", "SOME_OTHER_OBJECT" ] # objects initialization self.properties = [] self.properties.append( load_property_python_hpgl(166, 141, 20, "GAUSSIAN_PROP.INC", intype=True)) self.properties.append( load_property_python_hpgl(166, 141, 20, "BIG_SOFT_DATA_160_141_20.INC", intype=True)) #default object is 0 self.property = self.properties[0] self.property_name = self.property_names[0] self.property_defined_only = self.property[ self.property != self.undefined_value] self.bins_editbox = self.widgetsTree.get_widget("bins_editbox") self.bins_editbox.insert_text(str(self.bins), position=0) # objects box cell = [] self.object_box = gtk.ListStore(str) self.cb = self.widgetsTree.get_widget("obj_combo") self.cb.set_model(self.object_box) for k in xrange(len(self.property_names)): self.object_box.append([self.property_names[k]]) cell.append(gtk.CellRendererText()) self.cb.pack_start(cell[k]) self.cb.add_attribute(cell[k], 'text', k) self.cb.set_active(0) # -- histogram drawing self.figure = Figure(figsize=(6, 4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.hist(self.property_defined_only, bins=self.bins, range=self.range, normed=self.normalized, cumulative=self.cumulative, log=self.log) self.axis.set_xlabel('Values') self.axis.set_ylabel('Count') self.axis.set_title(self.property_names[self.cb.get_active()]) self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphview = self.widgetsTree.get_widget("draw_area") self.graphview.pack_start(self.canvas, True, True) # range elements self.max_cutoff = self.widgetsTree.get_widget("max_cutoff_box") self.max_cutoff.hide() self.min_cutoff = self.widgetsTree.get_widget("min_cutoff_box") self.min_cutoff.hide() self.min_cutoff_text = self.widgetsTree.get_widget("min_cutoff_text") self.min_cutoff_text.hide() self.max_cutoff_text = self.widgetsTree.get_widget("max_cutoff_text") self.max_cutoff_text.hide() self.range_check = self.widgetsTree.get_widget("range_check") self.save_file = self.widgetsTree.get_widget("save_file") # statistic calculation self.init() self.window.show() def new_bins_number_selected(self, widget): self.bins = int(self.bins_editbox.get_chars(0, -1)) self.repaint_hist() def repaint_hist(self): self.axis.clear() self.axis.set_xlabel('Values') if self.normalized: self.axis.set_ylabel('Frequency') else: self.axis.set_ylabel('Count') self.axis.hist(self.property_defined_only, bins=self.bins, range=self.range, normed=self.normalized, cumulative=self.cumulative, log=self.log) self.axis.set_title(self.property_name) self.axis.grid(True) self.graphview.hide_all() self.graphview.show_all() def on_range_check_toggled(self, widget): if self.range_check.get_active(): self.max_cutoff.show() self.min_cutoff.show() self.min_cutoff_text.show() self.max_cutoff_text.show() self.repaint_hist() else: self.range_state = False self.max_cutoff.hide() self.min_cutoff.hide() self.min_cutoff_text.hide() self.max_cutoff_text.hide() self.repaint_hist() def on_max_cutoff_box_activate(self, widget): self.range[1] = double(self.max_cutoff.get_text()) self.repaint_hist() def on_min_cutoff_box_activate(self, widget): self.range[0] = double(self.min_cutoff.get_text()) self.repaint_hist() def on_cumulative_check_toggled(self, widget): if self.cumulative_check.get_active(): self.cumulative = True self.repaint_hist() else: self.cumulative = False self.repaint_hist() def on_normalized_check_toggled(self, widget): if self.normalized_check.get_active(): self.normalized = True self.repaint_hist() else: self.normalized = False self.repaint_hist() def on_log_check_toggled(self, widget): if self.log_check.get_active(): self.log = True self.repaint_hist() else: self.log = False self.repaint_hist() def on_obj_combo_changed(self, widget): del (self.property) del (self.property_name) self.property_name = self.property_names[self.cb.get_active()] self.property = self.properties[self.cb.get_active()] self.property_defined_only = self.property[ self.property != self.undefined_value] self.init() self.repaint_hist() # save file def on_save_file_clicked(self, widget): print "saving..." self.save_file_dialog = gtk.FileChooserDialog( parent=self.window, action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) response = self.save_file_dialog.run() filter = gtk.FileFilter() filter.set_name("png image") filter.add_pattern("*." + "png") self.save_file_dialog.add_filter(filter) self.figure.savefig(self.save_file_dialog.get_filename()) self.save_file_dialog.destroy() def init(self): # -- statistics # mean self.mean_editbox = self.widgetsTree.get_widget("mean_box") self.mean_editbox.set_text(str(self.property_defined_only.mean())) # median self.median_editbox = self.widgetsTree.get_widget("median_box") self.median_editbox.set_text(str(median(self.property_defined_only))) # variance self.var_box = self.widgetsTree.get_widget("var_box") self.var_box.set_text(str(self.property_defined_only.var())) # max & min self.max_box = self.widgetsTree.get_widget("max_box") self.max_box.set_text(str(self.property_defined_only.max())) self.min_box = self.widgetsTree.get_widget("min_box") self.min_box.set_text(str(self.property_defined_only.min())) # now we can set ranges :) self.range = [ self.property_defined_only.min(), self.property_defined_only.max() ] # number of all points self.min_box = self.widgetsTree.get_widget("points_num_box") self.min_box.set_text(str(self.property.size)) # number of defined points self.min_box = self.widgetsTree.get_widget("def_points_num_box") self.min_box.set_text(str(self.property_defined_only.size)) self.max_cutoff.set_text(str(self.range[1])) self.min_cutoff.set_text(str(self.range[0])) def close_app(self, widget): gtk.main_quit()
class MasterGui: def __init__(self, filename=None, query=""): builder = gtk.Builder() builder.add_from_file(os.path.join(getdatapath(), "master_gui.ui")) self.root = builder.get_object('mainWin') builder.connect_signals(self) self.tlbStart = builder.get_object('tlbStart') self.tlbPause = builder.get_object('tlbPause') self.tlbStop = builder.get_object('tlbStop') self.statusbar = builder.get_object('statusbar1') self.imgQueryStatus = builder.get_object('imgQueryStatus') self.txtQueryQuery = builder.get_object('txtQueryQuery') self.graphContainer = builder.get_object('graphContainer') if matplotlib: # setup matplotlib stuff on first notebook page (empty graph) #self.figure = Figure(figsize=(6,4), dpi=72) self.figure = Figure() self.axis = self.figure.add_subplot(111) self.axis.set_xlabel('Time (secs.)') self.axis.set_ylabel('Size of waiting list') self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.graphContainer.pack_start(self.canvas, True, True) self.graph_lines = [] self.graph_data = [] for i in range(1, size): self.graph_lines += self.axis.plot([0]) self.graph_data += [[0]] print self.graph_data print self.graph_lines self.axis.set_ylim(0, 100) self.axis.set_xlim(0, 10) self.root.show_all() self.running = False if filename: self.loadFile(filename) if query: self.txtQueryQuery.set_text(query) gobject.idle_add(self.on_start) def on_quit(self, widget=None): for i in range(1, size): comm.send(None, dest=i, tag=messages.ABORT) gtk.main_quit() def on_openfile(self, widget=None): file_open_dialog = gtk.FileChooserDialog( title="Open UPPAAL model", action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) filter = gtk.FileFilter() filter.set_name("UPPAAL models") filter.add_pattern("*.xml") filter.add_mime_type("application/xml") file_open_dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") file_open_dialog.add_filter(filter) if file_open_dialog.run() == gtk.RESPONSE_OK: filename = file_open_dialog.get_filename() self.loadFile(filename) file_open_dialog.destroy() else: file_open_dialog.destroy() def loadFile(self, filename): model_file = open(filename, "r") self.model = pyuppaal.NTA.from_xml(model_file) self.node = MPINode(self.model, self.txtQueryQuery.get_text()) print "Master Broadcasting..." comm.bcast((self.model, self.txtQueryQuery.get_text()), root=0) def on_start(self, widget=None): self.running = True self.tlbStart.set_sensitive(False) self.tlbPause.set_sensitive(True) self.tlbStop.set_sensitive(True) self.start_time = datetime.datetime.now() #Seed the modelchecking with the initial state initstate = self.node.succgen.get_initialstate() self.node.sendtoremote(initstate, self.node.pwlist.homenode(initstate)) self.node.termination_detection.master_start_termination_detection() gobject.timeout_add(100, self.on_process_mpi) gobject.timeout_add(1000, self.on_update_status) def on_pause(self, widget=None): #Broadcast pause #for i in range(1, size): # comm.send(None, dest=i, tag=messages.PAUSE) self.tlbStart.set_sensitive(True) self.tlbPause.set_sensitive(False) self.tlbStop.set_sensitive(True) self.running = False def on_abort(self, widget=None): self.tlbStart.set_sensitive(True) self.tlbPause.set_sensitive(False) self.tlbStop.set_sensitive(False) self.running = False def on_update_status(self): if not self.running: return False statuses = [] elapsed = (datetime.datetime.now() - self.start_time).seconds or 1 totalwaiting = 0 totalpassed = 0 totaltotal = 0 graph_maxy = 0 for i in range(1, size): curstatus = None comm.send(None, dest=i, tag=messages.STATUS) (numwaiting, numpassed, numtotal) = comm.recv(None, source=i, tag=messages.STATUS) if matplotlib: self.graph_data[i - 1] += [numwaiting] self.graph_lines[i - 1].set_ydata(self.graph_data[i - 1]) self.graph_lines[i - 1].set_xdata( range(len(self.graph_data[i - 1]))) totalwaiting += numwaiting totalpassed += numpassed totaltotal += numtotal graph_maxy = max([graph_maxy] + self.graph_data[i - 1]) if matplotlib: self.axis.set_ylim(0, int(graph_maxy * 1.1)) self.axis.set_xlim(0, len(self.graph_data[0])) self.canvas.draw_idle() delta = datetime.datetime.now() - self.start_time msg = str(totalwaiting) + " waiting " + \ str(totalpassed) + " passed " + \ str(int(float(totaltotal) / elapsed)) + \ " states/sec " + \ "Walltime: " + \ str(delta.seconds) + "." + str(delta.microseconds / 1000)+ \ " secs" self.statusbar.pop(0) self.statusbar.push(0, msg) return True def on_process_mpi(self): if not self.running: return False self.node.termination_detection.master_termination_detection() if self.node.termination_detection.terminated: self.on_update_status() self.on_pause(None) if self.node.master_goal_detection(): self.imgQueryStatus.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_BUTTON) return True
class GuiGraphViewer (threading.Thread): def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes" : True, "Sites" : True, "Games" : True, "Limits" : True, "LimitSep" : True, "LimitType" : True, "Type" : False, "UseType" : 'ring', "Seats" : False, "SeatSep" : False, "Dates" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name("Refresh _Graph") self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name("_Export to File") self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("***Error: ")+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) raise def generateGraph(self, widget, data): try: self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() games = self.filters.getGames() for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return if not limits: print _("No limits found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, blue, red) = self.getRingProfitGraph(playerids, sitenos, limits, games) print _("Graph generated in: %s") %(time() - starttime) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Hands"), fontsize = 12) self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label=_('Hands: %d\nProfit: $%.2f') %(len(green), green[-1])) self.ax.plot(blue, color='blue', label=_('Showdown: $%.2f') %(blue[-1])) self.ax.plot(red, color='red', label=_('Non-showdown: $%.2f') %(red[-1])) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user #print "No hands returned by graph query" else: self.ax.set_title(_("Profit graph for ring games")) #text = "Profit: $%.2f\nTotal Hands: %d" %(green[-1], len(green)) #self.ax.annotate(text, # xy=(10, -10), # xycoords='axes points', # horizontalalignment='left', verticalalignment='top', # fontsize=10) #Draw plot self.ax.plot(green, color='green', label=_('Hands: %d\nProfit: $%.2f') %(len(green), green[-1])) self.ax.plot(blue, color='blue', label=_('Showdown: $%.2f') %(blue[-1])) self.ax.plot(red, color='red', label=_('Non-showdown: $%.2f') %(red[-1])) if sys.version[0:3] == '2.5': self.ax.legend(loc='upper left', shadow=True, prop=FontProperties(size='smaller')) else: self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("***Error: ")+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) #end of def showClicked def getRingProfitGraph(self, names, sites, limits, games): tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #nametest = nametest.replace("L", "") q = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: q.append(n) if len(q) > 0: gametest = str(tuple(q)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)",")") gametest = gametest.replace("u'","'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" tmp = tmp.replace("<game_test>", gametest) lims = [int(x) for x in limits if x.isdigit()] potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl'] nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl'] limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in " # and ( (limit and bb in()) or (nolimit and bb in ()) ) if lims: blindtest = str(tuple(lims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'pl' and gt.bigBlind in " if potlims: blindtest = str(tuple(potlims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) ' else: limittest = limittest + '(-1) ) ' limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in " if nolims: blindtest = str(tuple(nolims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") limittest = limittest + blindtest + ' ) )' else: limittest = limittest + '(-1) ) )' if type == 'ring': limittest = limittest + " and gt.type = 'ring' " elif type == 'tour': limittest = limittest + " and gt.type = 'tour' " #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace("<limit_test>", limittest) tmp = tmp.replace(",)", ")") #print "DEBUG: sql query:" #print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None, None) green = map(lambda x:float(x[1]), winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) blueline = cumsum(blue) redline = cumsum(red) return (greenline/100, blueline/100, redline/100) #end of def getRingProfitGraph def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename() + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class ResultViewer(gtk.Window): def __init__(self,modelf,paramsf,resultsf,auto_update = 1): super(ResultViewer, self).__init__() self.model_file = modelf if modelf!=None else "model.json" self.param_file = paramsf self.results_file = resultsf self.connect("destroy", gtk.main_quit) self.set_size_request(800, 600) self.set_position(gtk.WIN_POS_CENTER) self.vbox = gtk.VBox() self.time = gtk.SpinButton() self.time.set_numeric(True) self.time.set_increments(1,1) self.time.connect('value-changed', self.on_time_changed) self.vbox.pack_start(self.time,False) self.hbox = gtk.HPaned() self.add(self.hbox) self.graph = xdot.DotWidget() self.hbox.pack1(self.graph,True) self.set_focus(self.graph) self.graph.connect('clicked', self.on_url_clicked) self.current_node = None self.hbox.pack2(self.vbox,True) self.hbox.set_position(400) self.init_chart() if auto_update==1: import gobject gobject.timeout_add(500, self.update) self.update() else: self.reload() self.show_all() def reload(self): modelins = get_in_stream(self.model_file or "model.json") parameterins = get_in_stream(self.param_file or "prm.json") resultins = get_in_stream(self.results_file or "res.json") self.model = json.load(modelins) self.params = json.load(parameterins) self.results = json.load(resultins) modelins.close() parameterins.close() resultins.close() self.set_title(self.model["properties"]["name"]) self.time.set_range(0,len(self.results)-1) dotcode = generate_dot(self.model) self.graph.set_dotcode(dotcode, filename='<stdin>') self.draw_chart() dotcode = generate_dot(self.model) self.graph.set_dotcode(dotcode, filename='<stdin>') self.graph.zoom_to_fit() def update(self): import os import subprocess if not hasattr(self, "last_mtime"): self.last_mtime = None current_mtime = os.stat(self.model_file).st_mtime if current_mtime != self.last_mtime: self.last_mtime = current_mtime subprocess.call("make") self.reload() return True def init_chart(self): self.figure = Figure(figsize=(6,4), dpi=72) self.axis = self.figure.add_subplot(111) self.axis.grid(True) self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea self.canvas.show() self.vbox.pack_start(self.canvas, True, True) def on_url_clicked(self, widget, url, event): self.current_node = url self.draw_chart() return True def on_time_changed(self,widget): self.draw_chart() def draw_chart(self): self.axis.clear() if not (self.current_node is None): setup_node_states(self.model["nodes"]) for n in self.model["nodes"]: if n["id"] == self.current_node: node = n break left = map(lambda x: x[0],n["states"]) width = map(lambda x: x[1] - x[0],n["states"]) self.axis.set_xlabel('') self.axis.set_ylabel('Probability') self.axis.grid(True) self.axis.set_title("{1} ({0})".format(self.current_node,n["label"])) values = self.results[int(self.time.get_value())][self.current_node] self.axis.bar(left, values, width, color='b') self.axis.set_xlim(left[0],left[-1]+width[-1]) # self.axis.set_ylim(0,1) self.canvas.draw()
class GuiBankrollGraphViewer (threading.Thread): def __init__(self, settings, db, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.settings = settings self.db = db self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) view = None filters_display = { "Heroes" : True, "Sites" : True, "Games" : False, "Limits" : False, "LimitSep" : False, "LimitType" : False, "Type" : False, "UseType" : 'tour', "Seats" : False, "SeatSep" : False, "Dates" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) numeric_const_pattern = r""" [-+]? # optional sign (?: (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc | (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc ) # followed by optional exponent part if desired (?: [Ee] [+-]? \d+ ) ? """ self.rx = re.compile(numeric_const_pattern, re.VERBOSE) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() #add a button to modify transferts ButtonTransfert=gtk.Button(_("ButtonTransfert")) ButtonTransfert.set_label(_("_Modify Transferts")) ButtonTransfert.connect("clicked", self.transfertsWindow, "clicked") ButtonTransfert.set_sensitive(True) self.filters.mainVBox.pack_start(ButtonTransfert, False) ButtonTransfert.show() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None #update the graph at entry (simulate a «Refresh Graph» click) gobject.GObject.emit (self.filters.Button1, "clicked"); self.db.rollback() #endinit def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, dates, transfersAmount, transfersDate, transferType) = self.getData(playerids, sitenos) print _("Graph generated in: %s") %(time() - starttime) #Set axis labels and grid overlay properites self.ax.set_ylabel("$", fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label=_('Bankroll') + _('Profit') + ': $%.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Bankroll Results")) useDates = True #nothing to draw if (len(green) == 0): return #Get the dates of the action (transfert / cg hand / tourney) #if it has no date, get the most ancient date and assume it's its one if dates[0] is None: i = 1 while i < len(dates) and type(dates[i]) is None: i = i+1 if i == len(dates): print "Wow wow wow : no dates in your whole database" useDates = False else: dates[0] = dates[i] #now, convert date to dateTime format if useDates: for i in range(0, len(dates)): if dates[i] is None: dates[i] = dates[i-1] #~else: #~dates[i] = datetime.datetime.strptime(dates[i], "%Y-%m-%d %H:%M:%S") for i in range(0, len(green)-1): beneficeSinceStart=green[i+1]-self.totalTransfer(dates[i+1], transfersAmount, transfersDate) mycolor = self.color(transferType[i+1], beneficeSinceStart) self.ax.plot([i,i+1], [green[i],green[i+1]], color=mycolor) #show date and gain only 5 times on X axis if (i % (len(green)/5) == 1): #the gain since start at this time if (mycolor=='cyan'): mycolor='green' self.ax.annotate('%.2f' % beneficeSinceStart, xy=(i, 0), color=mycolor, xycoords=('data', 'axes fraction'), xytext=(0, 18), textcoords='offset points', va='top', ha='left') #and show the date too if enabled if useDates: dateMMDD=datetime.datetime.strptime(dates[i], "%Y-%m-%d %H:%M:%S").strftime('%d/%m') self.ax.annotate(dateMMDD, xy=(i, 0), xycoords=('data', 'axes fraction'), xytext=(0, -18), textcoords='offset points', va='top', ha='left') #plot the last one and show the top corner legend i = len(green)-1 bankroll = float(green[i]) profit = bankroll if len(transfersAmount)>0: profit -= transfersAmount[len(transfersAmount)-1] self.ax.plot([i,i+1], [green[i],green[i]], color=self.color(transferType[i], beneficeSinceStart), label=_('Bankroll') + ': \$%.2f' % bankroll + '\n' + _('Profit') + ': \$%.2f' % profit) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #end of def showClicked #return total cash from transfer until «date» def totalTransfer(self, date, amounts, transfersDate): #~print transferts if len(amounts) == 0 or (date < transfersDate[0]): return 0 i=0 while (i < len(amounts)-1 and date > transfersDate[i]): i = i + 1 return amounts[i] def color(self, typ, gain): # 0:play, 1:transfert if typ == 1: return 'cyan' elif gain < 0: return 'red' else: return 'green' def getData(self, names, sites): print "DEBUG: args are :" print names print sites tmp = self.rightRequest('getAllPrintIdSite', names, sites) tmp2 = self.rightRequest('getAllTransfer', names, sites) print "DEBUG: sql query:" print tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.cursor.execute(tmp2) transfers = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return None green = map(lambda x:float(x[0]), winnings) dates = map(lambda x:x[1], winnings) typeOf = map(lambda x:x[2], winnings) transferAmounts = map(lambda x:x[0], transfers) transferDates = map(lambda x:x[1], transfers) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) transferAmounts = cumsum(transferAmounts) return (greenline/100., dates, transferAmounts, transferDates, typeOf) def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename() + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy() #end of def exportGraph def transfertsWindow (self, widget, data) : #if the window is already launched, put it in front if not self.settings['global_lock'].acquire(wait=False, source="GuiBankrollGraphViewer"): return #create the window … #first, check if there is at least one player on database, else quit if (len(self.filters.getHeroes()) == 0): print "No site/hero found, abort" return self.transferWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) self.transferWindow.set_title("Transferts Management") self.transferWindow.set_position(gtk.WIN_POS_CENTER) self.transferWindow.set_transient_for(self.parent) self.transferWindow.connect("destroy", self.release) vbox = gtk.VBox(False, 0) self.transferWindow.add(vbox) ##### ##### #«new transfert» part hboxAdd = gtk.HBox(True, 0) vbox.pack_start(hboxAdd) #calendar cal = gtk.Calendar() vboxSelection = gtk.VBox(False, 0) #hour selection hourLabel = gtk.Label(_('Select hour:')) hourLabel.set_alignment(xalign=0.0, yalign=0.5) hboxHour = gtk.HBox(False, 0) timeHourPicker = gtk.SpinButton(None, 0, 0); timeHourPicker.set_increments(1, 6) timeHourPicker.set_range(0, 23) timeHourPicker.set_value(datetime.datetime.now().hour) # current hour timeMinPicker = gtk.SpinButton(None, 0, 0); timeMinPicker.set_increments(1, 10) timeMinPicker.set_range(0, 59) timeMinPicker.set_value(datetime.datetime.now().minute) # current hour #site/hero selection IDLabel = gtk.Label(_('Site - hero:')) IDLabel.set_alignment(xalign=0.0, yalign=0.5) IDSelection = gtk.combo_box_new_text() for site, hero in self.filters.getHeroes().items(): IDSelection.append_text(site + " - " + hero) IDSelection.set_active(0) #amount of virement amountLabel = gtk.Label(_('Tranfert amount ($):')) amountLabel.set_alignment(xalign=0.0, yalign=0.5) amountEntry = gtk.Entry() amountEntry.set_text('10.00') amountEntry.connect('changed', self.on_changed, 'changed') #button add buttonAdd = gtk.ToolButton(gtk.STOCK_ADD) buttonAdd.connect('clicked', self.newTransfer, 'clicked', cal, timeHourPicker, timeMinPicker, IDSelection, amountEntry) buttonAdd.connect('clicked', self.destroyWindow) hboxAdd.pack_start(cal, 0) hboxAdd.pack_start(vboxSelection, 0) vboxSelection.pack_start(hourLabel, 0) vboxSelection.pack_start(hboxHour, 0) hboxHour.pack_start(timeHourPicker, 0) hboxHour.pack_start(timeMinPicker, 0) vboxSelection.pack_start(IDLabel, 0) vboxSelection.pack_start(IDSelection, 0) vboxSelection.pack_start(amountLabel, 0) vboxSelection.pack_start(amountEntry, 0) vboxSelection.pack_start(buttonAdd, -1) #end of "new transfert" part ##### #### #### #start of "delete transfert" part hboxDelete = gtk.HBox(False, 0) vbox.pack_start(hboxDelete) #tab to create vboxTab = gtk.VBox(False, 0) self.createTab(vboxTab) buttonDelete = gtk.ToolButton(gtk.STOCK_DELETE) buttonDelete.connect('clicked', self.deleteTransfer, 'clicked') hboxDelete.pack_start(vboxTab, 1) hboxDelete.pack_start(buttonDelete, 1) #end of "delete transfert" part #### self.transferWindow.show_all() return #end of def transfertsWindow def release(self, widget, data=None): self.settings['global_lock'].release() self.transferWindow.destroy() return def on_changed(self, widget, data): #~text = widget.get_text().strip() #~widget.set_text(''.join([i for i in text if i in '0123456789'])) entry_text = widget.get_text() newtext = self.rx.findall(entry_text) if len(newtext) : widget.set_text(newtext[0]) else: widget.set_text("") def destroyWindow(self, widget): self.transferWindow.destroy() return def newTransfer(self, widget, data, cal, timeHourPicker, timeMinPicker, IDSelection, amountEntry): year, month, day = cal.get_date() month = month + 1 # because gtk gives it between 0 and 11 ?! hour = timeHourPicker.get_value() minute = timeMinPicker.get_value() (site, separator, hero) = IDSelection.get_active_text().partition(' - ') transfer = float(amountEntry.get_text()) now = datetime.datetime(year, month, day, int(hour), int(minute), 0) #get siteID from siteName (table "sites") self.db.cursor.execute('SELECT id from sites where name LIKE "' + site + '"') siteID = self.db.cursor.fetchall()[0][0] self.db.rollback() #get heroID from heroName and siteID (table "players") self.db.cursor.execute('select id from players where name LIKE "' + hero + '" and siteId = ' + str(siteID)) heroID = self.db.cursor.fetchall()[0][0] self.db.rollback() #insert it in the table now query = "INSERT INTO BankrollsManagement(siteId, playerId, transfer, startTime) VALUES (?, ?, ?, ?)" #~print "DEBUG:\n%s" % query self.db.cursor.execute(query, (siteID, heroID, int(transfer*100), now)) self.db.commit() self.db.rollback() #update the graph gobject.GObject.emit (self.filters.Button1, "clicked"); def deleteTransfer(self, widget, data): #get the active line of the array selected = self.view.get_cursor()[0] #if no row selected, abort if selected is None: return #else, retrieve the line ( /!\ rowNumber != Id from the table ), rowNumber = selected[0] line = self.liststore[0][rowNumber] id = line[0] #then delete it from table and refresh graph self.db.cursor.execute('DELETE FROM BankrollsManagement WHERE id=' + str(id)) self.db.commit() self.db.rollback() #destroy the window self.destroyWindow(widget) gobject.GObject.emit (self.filters.Button1, "clicked"); def createTab(self, vbox) : cols_to_show = [ ["id", False, _("ID"), 0.0, "%s", "str"] , ["siteName", True, _("Site"), 0.0, "%s", "str"] # true not allowed for this line (set in code) , ["playerName", True, _("Name"), 0.8, "%s", "str"] # true not allowed for this line (set in code) , ["amount", True, _("Amount"), 0.0, "%0.2f", "str"] , ["date", True, _("Date"), 0.0, "%s", "str"]] self.liststore=[] self.liststore.append( gtk.ListStore(*([str] * len(cols_to_show))) ) self.view = gtk.TreeView(model=self.liststore[0]) self.view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) #vbox.pack_start(view, expand=False, padding=3) vbox.add(self.view) textcell = gtk.CellRendererText() textcell50 = gtk.CellRendererText() textcell50.set_property('xalign', 0.5) numcell = gtk.CellRendererText() numcell.set_property('xalign', 1.0) listcols = [] listcols.append( [] ) # Create header row eg column: ("game", True, "Game", 0.0, "%s") for i, col in enumerate(cols_to_show): listcols[0].append(gtk.TreeViewColumn(col[_COL_HEADING])) self.view.append_column(listcols[0][i]) if col[_COL_FORMAT] == '%s': if col[_COL_XALIGN] == 0.0: listcols[0][i].pack_start(textcell, expand=True) listcols[0][i].add_attribute(textcell, 'text', i) cellrend = textcell else: listcols[0][i].pack_start(textcell50, expand=True) listcols[0][i].add_attribute(textcell50, 'text', i) cellrend = textcell50 listcols[0][i].set_expand(True) else: listcols[0][i].pack_start(numcell, expand=True) listcols[0][i].add_attribute(numcell, 'text', i) listcols[0][i].set_expand(True) cellrend = numcell query = self.sql.query['getAllTransferInformations'] #~print "DEBUG:\n%s" % query self.db.cursor.execute(query) result = self.db.cursor.fetchall() #~print "result of the big query in addGrid:",result colnames = [desc[0] for desc in self.db.cursor.description] #~for i in range(0, len(tab)) rows = len(result) # +1 for title row counter = 0 row = 0 sqlrow = 0 while sqlrow < rows: treerow = [] for col,column in enumerate(cols_to_show): if column[_COL_ALIAS] in colnames: if column[_COL_ALIAS] == 'amount': #convert $ cents to $ value = result[sqlrow][colnames.index(column[_COL_ALIAS])]/100. else: value = result[sqlrow][colnames.index(column[_COL_ALIAS])] else: value = 111 if value != None and value != -999: treerow.append(column[_COL_FORMAT] % value) else: treerow.append(' ') #print "addGrid, just before end of big for. grid:",grid,"treerow:",treerow iter = self.liststore[0].append(treerow) sqlrow += 1 row += 1 vbox.show_all() def rightRequest(self, request, names, sites): tmp = self.sql.query[request] print "DEBUG: getData. :" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") return tmp
class Backend( backend.Backend ): def init(self): self.layer_to_axes = {} self.axes_to_layer = {} self.layers_cache = [] # copy of self.plot.layers self.layer_signals = {} self.line_caches = {} self.omaps = {} def connect(self): logger.debug("Opening matplotlib session.") self.figure = Figure(dpi=100, facecolor="white") # figsize=(5,4), dpi=100) self.canvas = FigureCanvas(self.figure) self.canvas.show() self.line_caches = {} self.layer_to_axes.clear() self.axes_to_layer.clear() backend.Backend.connect(self) logger.debug("Init finished") def set(self, project,plot): backend.Backend.set(self, project, plot) if self.project is not None: # TODO: connect to notify::layers of Plot pass def disconnect(self): logger.debug("Closing matplotlib session.") if not self.canvas is None: self.canvas.destroy() self.canvas = None if not self.figure is None: self.figure = None backend.Backend.disconnect(self) #---------------------------------------------------------------------- def arrange(self, rows=1, cols=1): layers = self.plot.layers n = len(layers) if n > (rows*cols): rows = int((rows*cols) / n) + 1 cols = rows * n #raise ValueError("Not enough rows and cols for all layers!") self.figure.clear() self.figure.axes = [] self.layer_to_axes.clear() self.axes_to_layer.clear() self.layers_cache = [] for signal_list in self.layer_signals.itervalues(): for signal in signal_list: Signals.disconnect(signal) self.layer_signals = {} j = 1 for layer in layers: print "Setting up layer", layer axes = self.figure.add_subplot("%d%d%d" % (rows,cols,j)) self.layer_to_axes[layer] = axes self.axes_to_layer[axes] = layer self.layers_cache.append(layer) print "Connecting to notify of ", layer self.layer_signals[layer] = \ [Signals.connect(layer, 'notify', self.on_update_layer), Signals.connect(layer, 'notify::labels', self.on_update_labels)] j += 1 def draw(self): self.check_connection() logger.debug("Matplotlib: draw()") if self.plot.layers != self.layers_cache: self.arrange() self.omaps = {} for layer in self.plot.layers: self.update_layer(layer) self.draw_canvas() def draw_canvas(self): self.canvas.draw() #---------------------------------------------------------------------- # Layer # def on_update_layer(self, sender, updateinfo={}): # updateinfo is ignored self.update_layer(sender) self.canvas.draw() def update_layer(self, layer, updateinfo={}): # updateinfo is ignored self.omaps[layer] = {} self.line_caches[layer] = {} axes = self.layer_to_axes[layer] axes.lines = [] line_cache = self.line_caches[layer] = [] #:layer.lines:OK for line in layer.lines: self.update_line(line, layer, axes=axes) #:layer.axes for (key, axis) in layer.axes.iteritems(): #:axis.label #:axis.scale #:axis.start #:axis.end label = axis.label scale = axis.scale start = axis.start end = axis.end logger.debug("start = %s; end = %s" % (start, end)) if key == 'x': set_label = axes.set_xlabel set_scale = axes.set_xscale set_start = (lambda l: axes.set_xlim(xmin=l)) set_end = (lambda l: axes.set_xlim(xmax=l)) elif key == 'y': set_label = axes.set_ylabel set_scale = axes.set_yscale set_start = (lambda l: axes.set_ylim(ymin=l)) set_end = (lambda l: axes.set_ylim(ymax=l)) else: raise RuntimeError("Invalid axis key '%s'" % key) if label is not None: set_label(label) if scale is not None: set_scale(scale) if start is not None: set_start(start) if end is not None: set_end(end) #:layer.visible if layer.visible is False: return # TODO #:layer.title title = layer.title if title is not None: axes.set_title(title) #:layer.grid axes.grid(layer.grid) #:layer.legend:OK self.update_legend(layer) #:layer.labels:OK axes.texts = [] for label in layer.labels: self.update_textlabel(label, layer) #---------------------------------------------------------------------- # Line # def update_line(self, line, layer, axes=None, updateinfo={}): # updateinfo is ignored axes = axes or self.layer_to_axes[layer] omap = self.omaps[layer] line_cache = self.line_caches[layer] data_to_plot = [] #:line.visible if line.visible is False: if line in axes.lines: axes.lines.remove(line) line_cache.remove(line) omap[line] = None return ds = self.get_line_source(line) table = self.get_table(ds) cx, cy = self.get_column_indices(line) xdata, ydata = self.get_table_data(table, cx, cy) #:line.row_first #:line.row_last def limit_data(data, start, end): try: return data[start:end] except IndexError: backend.BackendError("Index range '%s'out of bounds!" % (start,end) ) start, end = line.row_first, line.row_last xdata = limit_data(xdata, start, end) ydata = limit_data(ydata, start, end) #:line.style global linestyle_mappings style = linestyle_mappings[line.style] #:line.marker global linemarker_mappings marker = linemarker_mappings[line.marker] #:line.width:OK #:line.color N = len(layer.group_colors) index = layer.lines.index(line) color = line.rget('color', layer.group_colors[index%N]) #--- PLOT LINE --- l, = axes.plot( xdata, ydata, linewidth=line.width, linestyle=style, marker=marker, color=color) line_cache.append(l) omap[line] = l label = self.get_line_label(line, table=table, cy=cy) if label is not None: l.set_label(label) #---------------------------------------------------------------------- # TextLabel # def on_update_labels(self, layer, updateinfo={}): # updateinfo is ignored # clear existing labels and their corresponding mappings axes = self.layer_to_axes[layer] axes.texts = [] for label in layer.labels: try: self.omaps[layer].pop(label) except KeyError: pass # create new labels for label in layer.labels: self.update_textlabel(label, layer) self.canvas.draw() def update_textlabel(self, label, layer, axes=None, updateinfo={}): # updateinfo is ignored axes = axes or self.layer_to_axes[layer] kwargs = self.label_kwargs(axes, label) if kwargs is None: return transform = kwargs.pop('transform') try: mpl_label = self.omaps[layer][label] except KeyError: mpl_label = Text(**kwargs) self.omaps[layer][label] = mpl_label axes.texts.append(mpl_label) else: mpl_label.update(kwargs) mpl_label.set_transform(transform) def label_kwargs(self, axes, label): if label.x is None or label.y is None: logger.info("Label coordinates contains empty value. Skipped.") return None if label.system == 0: transform = axes.transData elif label.system == 1: transform = axes.transAxes elif label.system == 2: transform = self.figure.transFigure elif label.system == 3: transform = matplotlib.transforms.identity_transform() return {'x': label.x, 'y': label.y, 'text' : label.text, 'horizontalalignment': 'center', 'verticalalignment' : 'center', 'transform' : transform} #---------------------------------------------------------------------- # Legend # def update_legend(self, layer, axes=None, updateinfo={}): # updateinfo is ignored axes = axes or self.layer_to_axes[layer] legend = layer.legend if legend is None: if axes.legend_ is not None: axes.legend_ = None self.omaps[layer][legend] = None else: kw = self.legend_kwargs(legend, layer) border = kw.pop('border') visible = kw.pop('visible') handles, labels = kw.pop('handles'), kw.pop('labels') _legend = axes.legend(handles, labels, **kw) self.omaps[layer][legend] = _legend _legend.draw_frame(border) _legend.set_visible(visible) self.omaps[layer][legend] = axes.legend_ def legend_kwargs(self, legend, layer): """ 'border' must be popped and set via legend.draw_frame 'visible' must be popped and set via set_visible """ visible = legend.visible #:legend.label:TODO label = legend.label if label is not None: pass #:legend.border:OK # (see below but keep it here!) border = legend.border #:legend.position TODO position = legend.position if position == 'at position': position = (legend.x, legend.y) # create legend entries from line labels line_cache = self.line_caches[layer] labels = [l.get_label() for l in line_cache] rv = {'handles' : line_cache, 'labels' : labels, 'loc' : position, 'border' : border, 'visible' : visible} print "LEGEND" print rv return rv
class AnalyzerGTK: def __init__(self): # Set the Glade file self.gladefile = "analyzer.glade" self.wTree = gtk.glade.XML(self.gladefile) # Get the Main Window and connect the "destroy" event self.window = self.wTree.get_widget("MainWindow") if (self.window): self.window.connect("destroy", gtk.main_quit) # Hook up the signals dic = { "on_menuOpen_activate": self.menuOpen_activate, "on_menuQuit_activate": self.menuQuit_activate, "on_menuAbout_activate": self.menuAbout_activate, "on_MainWindow_destroy": gtk.main_quit, "on_NetworkList_row_activated": self.plotRows, "on_btnPlotAnalysis_clicked": self.plotAnalysis, "on_checkShowTemplate_clicked": self.showTemplate, "on_btnClearFilter_clicked": self.clearFilter, "on_tbClear_clicked": self.clearPlot } self.wTree.signal_autoconnect(dic) # Create a LogFile object to handle data self.logfile = LogFile() # Create an empty plot window for tuning curves self.figureDT = Figure(figsize=(6,4), dpi=72) self.axisDT = self.figureDT.add_subplot(111) self.axisDT.set_xlabel('Duration') self.axisDT.set_ylabel('Mean Number of Spikes') self.axisDT.grid(True) self.canvasDT = FigureCanvasGTK(self.figureDT) # a gtk.DrawingArea self.canvasDT.show() self.graphviewDT = self.wTree.get_widget("vboxTuning") self.graphviewDT.pack_end(self.canvasDT) self.maxSpikes = 1 self.showTemplate = False # Create an empty plot window for analysis self.figureAN = Figure(dpi=72) self.axisAN = self.figureAN.add_subplot(111) self.canvasAN = FigureCanvasGTK(self.figureAN) self.canvasAN.show() self.graphviewAN = self.wTree.get_widget("vboxAnalysis") self.graphviewAN.pack_end(self.canvasAN) # Setup the analyze window self.cbXAxis = gtk.combo_box_new_text() self.cbYAxis = gtk.combo_box_new_text() self.cbZAxis = gtk.combo_box_new_text() self.cbXAxis.show() self.cbYAxis.show() self.cbZAxis.show() self.hboxAnalyze = self.wTree.get_widget("hboxAnalyze") labelX = gtk.Label("X-Axis") labelX.show() labelY = gtk.Label("Y-Axis") labelY.show() labelZ = gtk.Label("Z-Axis") labelZ.show() self.hboxAnalyze.pack_start(labelX) self.hboxAnalyze.pack_start(self.cbXAxis) self.hboxAnalyze.pack_start(labelY) self.hboxAnalyze.pack_start(self.cbYAxis) self.hboxAnalyze.pack_start(labelZ) self.hboxAnalyze.pack_start(self.cbZAxis) def plotAnalysis(self, widget): Xvar = self.cbXAxis.get_active_text() Yvar = self.cbYAxis.get_active_text() Zvar = self.cbZAxis.get_active_text() if Xvar == None or Yvar == None or Zvar == None: return if Zvar == "None": XvarIndex = self.logfile.params().index(Xvar)+1 YvarIndex = self.logfile.params().index(Yvar)+1 rowiter = self.treemodelsorted.get_iter_first() values = defaultdict(list) while rowiter != None: X = self.treemodelsorted.get_value(rowiter,XvarIndex) Y = self.treemodelsorted.get_value(rowiter,YvarIndex) values[float(X)].append(float(Y)) rowiter = self.treemodelsorted.iter_next(rowiter) X = [] Y = [] for k in sorted(values.keys()): X.append(k) Y.append(mean(values[k])) self.axisAN.cla() self.figureAN.clf() self.axisAN = self.figureAN.add_subplot(111) self.axisAN.plot(X,Y, 'k', linewidth=4) self.axisAN.set_xlabel(Xvar) self.axisAN.set_ylabel(Yvar) self.canvasAN.draw() else: XvarIndex = self.logfile.params().index(Xvar)+1 YvarIndex = self.logfile.params().index(Yvar)+1 ZvarIndex = self.logfile.params().index(Zvar)+1 rowiter = self.treemodelsorted.get_iter_first() values = {} Ykeys = [] while rowiter != None: X = self.treemodelsorted.get_value(rowiter,XvarIndex) Y = self.treemodelsorted.get_value(rowiter,YvarIndex) Z = self.treemodelsorted.get_value(rowiter,ZvarIndex) Ykeys.append(Y) values.setdefault(X,defaultdict(list))[Y].append(Z) rowiter = self.treemodelsorted.iter_next(rowiter) Ykeys = unique(Ykeys) XY = [] for k in sorted(values.keys()): tmp = [] for k2 in sorted(Ykeys): if values[k].has_key(k2): tmp.append(mean(values[k][k2])) else: tmp.append(0) XY.append(tmp) Z = array(XY) self.axisAN.cla() self.figureAN.clf() self.axisAN = self.figureAN.add_subplot(111) im = NonUniformImage(self.axisAN, interpolation='nearest', extent=(min(values.keys()),max(values.keys()),min(Ykeys),max(Ykeys))) im.set_data(values.keys(), Ykeys, Z.transpose()) self.axisAN.images.append(im) self.axisAN.set_xlim(min(values.keys()),max(values.keys())) self.axisAN.set_ylim(min(Ykeys),max(Ykeys)) self.axisAN.set_xlabel(Xvar) self.axisAN.set_ylabel(Yvar) self.axisAN.set_title(Zvar) self.figureAN.colorbar(im) self.canvasAN.draw() def showTemplate(self, widget): self.showTemplate = widget.get_active() def plotRows(self, widget, path, column): (model, pathlist) = self.treeview.get_selection().get_selected_rows() for p in pathlist: treeiter = self.treemodelsorted.get_iter(p) X = self.logfile.getdurs() Y = self.logfile.getresults(self.treemodelsorted.get_value(treeiter,0)) tmp = Y[:] tmp.append(self.maxSpikes) self.maxSpikes = max(tmp) self.axisDT.plot(X, Y, linewidth=2) self.axisDT.set_ylim( (0, self.maxSpikes+0.1) ) if self.showTemplate: Y = self.logfile.getresults(0) tmp = Y[:] tmp.append(self.maxSpikes) self.maxSpikes = max(tmp) self.axisDT.plot(X, Y, 'k', linewidth=3) self.axisDT.set_ylim( (0, self.maxSpikes+0.1) ) self.canvasDT.draw() def clearPlot(self, widget): self.maxSpikes = 1 self.axisDT.cla() self.axisDT.set_xlabel('Duration') self.axisDT.set_ylabel('Mean Number of Spikes') self.axisDT.grid(True) self.canvasDT.draw() def clearFilter(self, widget): for i in range(len(self.filtercboxes)): self.filtercboxes[i].set_active(0) def applyFilter(self,model,iter): show = True for i in range(len(self.filtercboxes)): f = self.filtercboxes[i].get_active_text() show = show and (f == "All" or f == str(self.liststore.get_value(iter,i+1))) return show def updateFilter(self, widget): self.treemodelfilter = self.liststore.filter_new(root=None) self.treemodelfilter.set_visible_func(self.applyFilter) self.treemodelsorted = gtk.TreeModelSort(self.treemodelfilter) self.treeview.set_model(self.treemodelsorted) def menuOpen_activate(self, widget): chooser = gtk.FileChooserDialog(title="Open Log File", action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) response = chooser.run() if response == gtk.RESPONSE_OK: filename = chooser.get_filename() if self.logfile.open(filename): # Data file opened # Populate the ListStore for our table self.liststore = gtk.ListStore(int, *([float] *len(self.logfile.params()))) self.treeview = self.wTree.get_widget("NetworkList") self.treeview.set_model(self.liststore) self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) # Remove any old columns for c in self.treeview.get_columns(): self.treeview.remove_column(c) self.cbXAxis.get_model().clear() self.cbYAxis.get_model().clear() self.cbZAxis.get_model().clear() self.cbZAxis.append_text("None") # Add columns to filter table and fill analysis dropdowns self.filtertable = self.wTree.get_widget("FilterTable") self.filtertable.resize(len(self.logfile.params()), 2) textrenderer = gtk.CellRendererText() col = 1 self.filtercboxes = [] for p in self.logfile.params(): column = gtk.TreeViewColumn(p, textrenderer, text=col) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) column.set_resizable(True) column.set_clickable(True) column.set_sort_column_id(col) self.treeview.append_column(column) label = gtk.Label(p) label.set_justify(gtk.JUSTIFY_RIGHT) label.show() cbox = gtk.combo_box_new_text() self.filtercboxes.append(cbox) self.filtercboxes[-1].show() self.filtercboxes[-1].connect("changed", self.updateFilter) self.filtertable.attach(label, 0, 1, col-1, col) self.filtertable.attach(cbox, 1, 2, col-1, col) self.cbXAxis.append_text(p) self.cbYAxis.append_text(p) self.cbZAxis.append_text(p) col = col + 1 # Add data to table for n in self.logfile.networkdefs(): itt = self.liststore.append(n) # Add data to columns tmp = [] for i in range(len(self.logfile.params())): tmp.append([]) for n in self.logfile.networkdefs(): for i in range(1,len(self.logfile.params())+1): tmp[i-1].append(n[i]) for i in range(len(tmp)): tmp[i] = unique(tmp[i]) tmp[i].sort() self.filtercboxes[i].append_text("All") self.filtercboxes[i].set_active(0) for n in tmp[i]: self.filtercboxes[i].append_text(str(n)) # Setup the filtered sorted liststores self.treemodelfilter = self.liststore.filter_new(root=None) self.treemodelfilter.set_visible_func(self.applyFilter) self.treemodelsorted = gtk.TreeModelSort(self.treemodelfilter) self.treeview.set_model(self.treemodelsorted) # Destroy the file chooser chooser.destroy() def menuAbout_activate(self, widget): aboutDialog = self.wTree.get_widget("AboutDialog") response = aboutDialog.run() if response == gtk.RESPONSE_CANCEL: aboutDialog.hide() def menuQuit_activate(self, widget): gtk.main_quit()
class GuiTourneyGraphViewer: def __init__(self, querylist, config, parent, debug=True): """Constructor for GraphViewer""" self.sql = querylist self.conf = config self.debug = debug self.parent = parent #print "start of GraphViewer constructor" self.db = Database.Database(self.conf, sql=self.sql) filters_display = { "Heroes" : True, "Sites" : True, "Games" : False, "Currencies" : True, "Limits" : False, "LimitSep" : False, "LimitType" : False, "Type" : False, "UseType" : 'tour', "Seats" : False, "SeatSep" : False, "Dates" : True, "GraphOpsTour" : True, "Groups" : False, "Button1" : True, "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters.registerButton1Name(_("Refresh _Graph")) self.filters.registerButton1Callback(self.generateGraph) self.filters.registerButton2Name(_("_Export to File")) self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) self.mainHBox.show() self.leftPanelBox = self.filters.get_vbox() self.hpane = gtk.HPaned() self.hpane.pack1(self.leftPanelBox) self.mainHBox.add(self.hpane) # hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax self.graphBox = gtk.VBox(False, 0) self.graphBox.show() self.hpane.pack2(self.graphBox) self.hpane.show() self.fig = None #self.exportButton.set_sensitive(False) self.canvas = None self.db.rollback() #update the graph at entry (simulate a "Refresh Graph" click) gobject.GObject.emit (self.filters.Button1, "clicked"); def get_vbox(self): """returns the vbox of this thread""" return self.mainHBox #end def get_vbox def clearGraphData(self): try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig != None: self.fig.clear() self.fig = Figure(figsize=(5,4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea def generateGraph(self, widget, data): self.clearGraphData() sitenos = [] playerids = [] sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() currencies = self.filters.getCurrencies() # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") self.db.rollback() return if not playerids: print _("No player ids found") self.db.rollback() return #Set graph properties self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() (green, datesXAbs) = self.getData(playerids, sitenos, currencies) print _("Graph generated in: %s") %(time() - starttime) currencyLabel = ','.join(['%s' % key for key in currencies.keys()]) #Set axis labels and grid overlay properites self.ax.set_ylabel(currencyLabel, fontsize = 12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) if green == None or green == []: self.ax.set_title(_("No Data for Player(s) Found")) green = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) red = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 500., 500., 500., 500., 500., 500., 500., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) blue = ([ 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 0., 0., 0., 0., 0., 0., 125., 250., 375., 500., 625., 750., 875., 1000., 875., 750., 625., 500., 375., 250., 125., 0., 0., 0., 0., 500., 1000., 900., 800., 700., 600., 500., 400., 300., 200., 100., 0., 500., 1000., 1000.]) self.ax.plot(green, color='green', label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + '(' + currencyLabel + '): %.2f' % green[-1]) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #TODO: Do something useful like alert user else: self.ax.set_title(_("Tournament Results")) useDates = True #nothing to draw if (len(green) == 0): return #Get the dates of tourneys #if first tourney has no date, get the most ancient date and assume it's his one if datesXAbs[0] is None: i = 1 while i < len(datesXAbs) and type(datesXAbs[i]) is None: i = i+1 if i == len(datesXAbs): print "Wow wow wow : no dates in your whole tourneys" useDates = False else: datesXAbs[0] = datesXAbs[i] #now convert date to dateTime format if useDates: for i in range(0, len(datesXAbs)): if datesXAbs[i] is None: datesXAbs[i] = datesXAbs[i-1] else: datesXAbs[i] = datetime.datetime.strptime(datesXAbs[i], "%Y-%m-%d %H:%M:%S") datesXAbs[i] = datesXAbs[i].strftime('%d/%m') mycolor='red' if green[0]>0: mycolor='green' self.ax.plot([0,1], [0,green[0]], color=mycolor, label=_('Tournaments') + ': %d\n' % len(green) + _('Profit') + '(' + currencyLabel + '): %.2f' % green[-1]) for i in range(1, len(green)): final=green[i]-green[i-1] mycolor='red' if (green[i]>0): mycolor='green' self.ax.plot([i,i+1], [green[i-1],green[i]], color=mycolor) if (i % (len(green)/5) == 0): gain="" if (green[i]==0): gain="=" else: if (green[i]>0): gain="+" gain += str(green[i]) self.ax.annotate(gain, xy=(i, 0), color=mycolor, xycoords=('data', 'axes fraction'), xytext=(0, 18), textcoords='offset points', va='top', ha='left') if useDates: self.ax.annotate(datesXAbs[i], xy=(i, 0), xycoords=('data', 'axes fraction'), xytext=(0, -18), textcoords='offset points', va='top', ha='left') #~self.ax.axhline(0, color='black', lw=2) legend = self.ax.legend(loc='upper left', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) legend.draggable(True) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() #self.exportButton.set_sensitive(True) #end of def showClicked def getData(self, names, sites, currencies): tmp = self.sql.query['tourneyGraph'] # print "DEBUG: getData. :" start_date, end_date = self.filters.getDates() #Buggered if I can find a way to do this 'nicely' take a list of integers and longs # and turn it into a tuple readale by sql. # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) currencytest = str(tuple()) #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("<player_test>", nametest) tmp = tmp.replace("<site_test>", sitetest) currencytest = str(tuple(currencies)) currencytest = currencytest.replace(",)",")") currencytest = currencytest.replace("u'","'") currencytest = "AND tt.currency in %s" % currencytest tmp = tmp.replace("<currency_test>", currencytest) tmp = tmp.replace("<startdate_test>", start_date) tmp = tmp.replace("<enddate_test>", end_date) tmp = tmp.replace(",)", ")") # print "DEBUG: sql query:", tmp self.db.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() self.db.rollback() if len(winnings) == 0: return (None, None) green = map(lambda x:float(x[1]), winnings) datesXAbs = map(lambda x:x[8], winnings) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) #blueline = cumsum(blue) #redline = cumsum(red) return (greenline/100, datesXAbs) def exportGraph (self, widget, data): if self.fig is None: return # Might want to disable export button until something has been generated. dia_chooser = gtk.FileChooserDialog(title=_("Please choose the directory you wish to export to:"), action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK,gtk.RESPONSE_OK)) dia_chooser.set_destroy_with_parent(True) dia_chooser.set_transient_for(self.parent) try: dia_chooser.set_filename(self.exportFile) # use previously chosen export path as default except: pass response = dia_chooser.run() if response <> gtk.RESPONSE_OK: print _('Closed, no graph exported') dia_chooser.destroy() return # generate a unique filename for export now = datetime.now() now_formatted = now.strftime("%Y%m%d%H%M%S") self.exportFile = dia_chooser.get_filename() + "/fpdb" + now_formatted + ".png" dia_chooser.destroy() #print "DEBUG: self.exportFile = %s" %(self.exportFile) self.fig.savefig(self.exportFile, format="png") #display info box to confirm graph created diainfo = gtk.MessageDialog(parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Graph created")) diainfo.format_secondary_text(self.exportFile) diainfo.run() diainfo.destroy()
class GuiSessionViewer: def __init__(self, config, querylist, mainwin, owner, debug=True): self.debug = debug self.conf = config self.sql = querylist self.window = mainwin self.owner = owner self.liststore = None self.MYSQL_INNODB = 2 self.PGSQL = 3 self.SQLITE = 4 self.fig = None self.canvas = None self.ax = None self.graphBox = None # create new db connection to avoid conflicts with other threads self.db = Database.Database(self.conf, sql=self.sql) self.cursor = self.db.cursor settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) settings.update(self.conf.get_default_paths()) # text used on screen stored here so that it can be configured self.filterText = { 'handhead': _('Hand Breakdown for all levels listed above') } filters_display = { "Heroes": True, "Sites": True, "Games": True, "Currencies": True, "Limits": True, "LimitSep": True, "LimitType": True, "Type": False, "Seats": True, "SeatSep": False, "Dates": True, "Groups": False, "GroupsAll": False, "Button1": True, "Button2": False } self.filters = Filters.Filters(self.db, self.conf, self.sql, display=filters_display) self.filters.registerButton1Name("_Refresh") self.filters.registerButton1Callback(self.refreshStats) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting self.columns = [(1.0, "SID"), (1.0, "Hands"), (0.5, "Start"), (0.5, "End"), (1.0, "Rate"), (1.0, "Open"), (1.0, "Close"), (1.0, "Low"), (1.0, "High"), (1.0, "Range"), (1.0, "Profit")] self.detailFilters = [] # the data used to enhance the sql select self.main_hbox = gtk.HPaned() self.stats_frame = gtk.Frame() self.stats_frame.show() main_vbox = gtk.VPaned() main_vbox.show() self.graphBox = gtk.VBox(False, 0) self.graphBox.set_size_request(400, 400) self.graphBox.show() self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.main_hbox.pack1(self.filters.get_vbox()) self.main_hbox.pack2(main_vbox) main_vbox.pack1(self.graphBox) main_vbox.pack2(self.stats_frame) self.main_hbox.show() # make sure Hand column is not displayed #[x for x in self.columns if x[0] == 'hand'][0][1] = False # if DEBUG == False: # warning_string = _("Session Viewer is proof of concept code only, and contains many bugs.\n") # warning_string += _("Feel free to use the viewer, but there is no guarantee that the data is accurate.\n") # warning_string += _("If you are interested in developing the code further please contact us via the usual channels.\n") # warning_string += _("Thank you") # self.warning_box(warning_string) def warning_box(self, str, diatitle=_("FPDB WARNING")): diaWarning = gtk.Dialog(title=diatitle, parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK)) label = gtk.Label(str) diaWarning.vbox.add(label) label.show() response = diaWarning.run() diaWarning.destroy() return response def get_vbox(self): """returns the vbox of this thread""" return self.main_hbox def refreshStats(self, widget, data): try: self.stats_vbox.destroy() except AttributeError: pass self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox.show() self.stats_frame.add(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) def fillStatsFrame(self, vbox): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() games = self.filters.getGames() currencies = self.filters.getCurrencies() limits = self.filters.getLimits() seats = self.filters.getSeats() sitenos = [] playerids = [] for i in ('show', 'none'): if i in limits: limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(result) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not games: print _("No games found") return if not currencies: print _("No currencies found") return if not playerids: print _("No player ids found") return if not limits: print _("No limits found") return self.createStatsPane(vbox, playerids, sitenos, games, currencies, limits, seats) def createStatsPane(self, vbox, playerids, sitenos, games, currencies, limits, seats): starttime = time() (results, quotes) = self.generateDatasets(playerids, sitenos, games, currencies, limits, seats) if DEBUG: for x in quotes: print "start %s\tend %s \thigh %s\tlow %s" % (x[1], x[2], x[3], x[4]) self.generateGraph(quotes) heading = gtk.Label(self.filterText['handhead']) heading.show() vbox.pack_start(heading, expand=False, padding=3) # Scrolled window for detailed table (display by hand) swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.show() vbox.pack_start(swin, expand=True, padding=3) vbox1 = gtk.VBox(False, 0) vbox1.show() swin.add_with_viewport(vbox1) self.addTable(vbox1, results) self.db.rollback() print _("Stats page displayed in %4.2f seconds") % (time() - starttime) #end def fillStatsFrame(self, vbox): def generateDatasets(self, playerids, sitenos, games, currencies, limits, seats): if (DEBUG): print "DEBUG: Starting generateDatasets" THRESHOLD = 1800 # Min # of secs between consecutive hands before being considered a new session PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc # Get a list of timestamps and profits q = self.sql.query['sessionStats'] start_date, end_date = self.filters.getDates() q = q.replace("<datestest>", " BETWEEN '" + start_date + "' AND '" + end_date + "'") l = [] for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: for n in games: if games[n]: l.append(n) if len(l) > 0: gametest = str(tuple(l)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)", ")") gametest = gametest.replace("u'", "'") gametest = "AND gt.category in %s" % gametest else: gametest = "AND gt.category IS NULL" q = q.replace("<game_test>", gametest) limittest = self.filters.get_limits_where_clause(limits) q = q.replace("<limit_test>", limittest) l = [] for n in currencies: if currencies[n]: l.append(n) currencytest = str(tuple(l)) currencytest = currencytest.replace(",)", ")") currencytest = currencytest.replace("u'", "'") currencytest = "AND gt.currency in %s" % currencytest q = q.replace("<currency_test>", currencytest) if seats: q = q.replace( '<seats_test>', 'AND h.seats BETWEEN ' + str(seats['from']) + ' AND ' + str(seats['to'])) else: q = q.replace('<seats_test>', 'AND h.seats BETWEEN 0 AND 100') nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)", ")") q = q.replace("<player_test>", nametest) q = q.replace("<ampersand_s>", "%s") if DEBUG: hands = [ (u'10000', 10), (u'10000', 20), (u'10000', 30), (u'20000', -10), (u'20000', -20), (u'20000', -30), (u'30000', 40), (u'40000', 0), (u'50000', -40), (u'60000', 10), (u'60000', 30), (u'60000', -20), (u'70000', -20), (u'70000', 10), (u'70000', 30), (u'80000', -10), (u'80000', -30), (u'80000', 20), (u'90000', 20), (u'90000', -10), (u'90000', -30), (u'100000', 30), (u'100000', -50), (u'100000', 30), (u'110000', -20), (u'110000', 50), (u'110000', -20), (u'120000', -30), (u'120000', 50), (u'120000', -30), (u'130000', 20), (u'130000', -50), (u'130000', 20), (u'140000', 40), (u'140000', -40), (u'150000', -40), (u'150000', 40), (u'160000', -40), (u'160000', 80), (u'160000', -40), ] else: self.db.cursor.execute(q) hands = self.db.cursor.fetchall() #fixme - nasty hack to ensure that the hands.insert() works # for mysql data. mysql returns tuples which can't be inserted # into so convert explicity to list. hands = list(hands) if (not hands): return ([], []) hands.insert(0, (hands[0][0], 0)) # Take that list and create an array of the time between hands times = map(lambda x: long(x[0]), hands) profits = map(lambda x: float(x[1]), hands) #print "DEBUG: times : %s" % times #print "DEBUG: profits: %s" % profits #print "DEBUG: len(times) %s" %(len(times)) diffs = diff( times ) # This array is the difference in starttime between consecutive hands diffs2 = append( diffs, THRESHOLD + 1 ) # Append an additional session to the end of the diffs, so the next line # includes an index into the last 'session' index = nonzero( diffs2 > THRESHOLD ) # This array represents the indexes into 'times' for start/end times of sessions # times[index[0][0]] is the end of the first session, #print "DEBUG: len(index[0]) %s" %(len(index[0])) if len(index[0]) > 0: #print "DEBUG: index[0][0] %s" %(index[0][0]) #print "DEBUG: index %s" %(index) pass else: index = [[0]] #print "DEBUG: index %s" %(index) #print "DEBUG: index[0][0] %s" %(index[0][0]) pass first_idx = 1 quotes = [] results = [] cum_sum = cumsum(profits) / 100 sid = 1 total_hands = 0 total_time = 0 global_open = None global_lwm = None global_hwm = None self.times = [] # Take all results and format them into a list for feeding into gui model. #print "DEBUG: range(len(index[0]): %s" % range(len(index[0])) for i in range(len(index[0])): last_idx = index[0][i] hds = last_idx - first_idx + 1 # Number of hands in session if hds > 0: stime = strftime("%d/%m/%Y %H:%M", localtime( times[first_idx])) # Formatted start time etime = strftime("%d/%m/%Y %H:%M", localtime( times[last_idx])) # Formatted end time self.times.append((times[first_idx], times[last_idx])) minutesplayed = (times[last_idx] - times[first_idx]) / 60 minutesplayed = minutesplayed + PADDING if minutesplayed == 0: minutesplayed = 1 hph = hds * 60 / minutesplayed # Hands per hour end_idx = last_idx + 1 won = sum(profits[first_idx:end_idx]) / 100.0 #print "DEBUG: profits[%s:%s]: %s" % (first_idx, end_idx, profits[first_idx:end_idx]) hwm = max(cum_sum[first_idx - 1:end_idx]) # include the opening balance, lwm = min(cum_sum[first_idx - 1:end_idx]) # before we win/lose first hand open = (sum(profits[:first_idx])) / 100 close = (sum(profits[:end_idx])) / 100 #print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, end_idx, lwm, hwm, open, close) total_hands = total_hands + hds total_time = total_time + minutesplayed if (global_lwm == None or global_lwm > lwm): global_lwm = lwm if (global_hwm == None or global_hwm < hwm): global_hwm = hwm if (global_open == None): global_open = open global_stime = stime results.append([ sid, hds, stime, etime, hph, "%.2f" % open, "%.2f" % close, "%.2f" % lwm, "%.2f" % hwm, "%.2f" % (hwm - lwm), "%.2f" % won ]) quotes.append((sid, open, close, hwm, lwm)) #print "DEBUG: Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won) first_idx = end_idx sid = sid + 1 else: print "hds <= 0" global_close = close global_etime = etime results.append([''] * 11) results.append([ _("all"), total_hands, global_stime, global_etime, total_hands * 60 / total_time, "%.2f" % global_open, "%.2f" % global_close, "%.2f" % global_lwm, "%.2f" % global_hwm, "%.2f" % (global_hwm - global_lwm), "%.2f" % (global_close - global_open) ]) return (results, quotes) def clearGraphData(self): try: try: if self.canvas: self.graphBox.remove(self.canvas) except: pass if self.fig is not None: self.fig.clear() self.fig = Figure(figsize=(5, 4), dpi=100) if self.canvas is not None: self.canvas.destroy() self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print _("Error:") + " " + err[2] + "(" + str(err[1]) + "): " + str( sys.exc_info()[1]) raise def generateGraph(self, quotes): self.clearGraphData() #print "DEBUG:" #print "\tquotes = %s" % quotes #for i in range(len(highs)): # print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i]) # print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i]) self.ax = self.fig.add_subplot(111) self.ax.set_title(_("Session candlestick graph")) #Set axis labels and grid overlay properites self.ax.set_xlabel(_("Sessions"), fontsize=12) self.ax.set_ylabel("$", fontsize=12) self.ax.grid(color='g', linestyle=':', linewidth=0.2) candlestick(self.ax, quotes, width=0.50, colordown='r', colorup='g', alpha=1.00) self.graphBox.add(self.canvas) self.canvas.show() self.canvas.draw() def addTable(self, vbox, results): row = 0 sqlrow = 0 colxalign, colheading = range(2) self.liststore = gtk.ListStore(*([str] * len(self.columns))) for row in results: iter = self.liststore.append(row) view = gtk.TreeView(model=self.liststore) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) vbox.add(view) print view.connect("row-activated", self.row_activated) cell05 = gtk.CellRendererText() cell05.set_property('xalign', 0.5) cell10 = gtk.CellRendererText() cell10.set_property('xalign', 1.0) listcols = [] # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(self.columns): treeviewcolumn = gtk.TreeViewColumn(column[colheading]) listcols.append(treeviewcolumn) treeviewcolumn.set_alignment(column[colxalign]) view.append_column(listcols[col]) if (column[colxalign] == 0.5): cell = cell05 else: cell = cell10 listcols[col].pack_start(cell, expand=True) listcols[col].add_attribute(cell, 'text', col) listcols[col].set_expand(True) vbox.show_all() def row_activated(self, view, path, column): if path[0] < len(self.times): replayer = None for tabobject in self.owner.threads: if isinstance(tabobject, GuiHandViewer.GuiHandViewer): replayer = tabobject self.owner.tab_hand_viewer(None) break if replayer is None: self.owner.tab_hand_viewer(None) for tabobject in self.owner.threads: if isinstance(tabobject, GuiHandViewer.GuiHandViewer): replayer = tabobject break # added the timezone offset ('+00:00') to make the db query work. Otherwise the hands # at the edges of the date range are not included. A better solution may be possible. # Optionally the end date in the call below, which is a Long gets a '+1'. reformat = lambda t: strftime("%Y-%m-%d %H:%M:%S+00:00", gmtime(t)) handids = replayer.get_hand_ids_from_date_range( reformat(self.times[path[0]][0]), reformat(self.times[path[0]][1]), save_date=True) replayer.reload_hands(handids)
class Graphic: def __init__(self, widget): self.figure = Figure(figsize=(4,3), dpi=64) self.axes = self.figure.add_subplot(111) self.axes.grid(True) self.widget = widget self.canvas = FigureCanvasGTK(self.figure) self.graphview = widget self.graphview.pack_start(self.canvas, True, True) #self.cursor = None #self.on_press_cb = None #self.on_release_cb = None #self.on_motion_cb = None self.lx_min = None self.lx_max = None #self.rec = None self.axes2 = None self.span = None self.ticklines = self.axes.get_xticklines() self.ticklines.extend( self.axes.get_yticklines() ) self.gridlines = self.axes.get_xgridlines() self.gridlines.extend( self.axes.get_ygridlines() ) self.ticklabels = self.axes.get_xticklabels() self.ticklabels.extend( self.axes.get_yticklabels() ) for line in self.ticklines: line.set_linewidth(2) for line in self.gridlines: line.set_linestyle('-') for label in self.ticklabels: label.set_fontsize('small') self.canvas.show() #button_ax = axes([0.7, 0.5, 0.1, 0.75]) #button = Button(button_ax, 'Press Me') #button.on_clicked(self.on_button_clicked) def plot(self, x, y): self.axes.clear() self.axes.plot(x, y) self.axes.grid(True) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.widget.pack_start(self.canvas, True, True) def semilogy(self, x, y): self.axes.clear() self.axes.grid(True) self.axes.semilogy(x, y) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.widget.pack_start(self.canvas, True, True) def autocor(self, x): self.axes.clear() self.axes.grid(True) self.axes.acorr(x) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.widget.pack_start(self.canvas, True, True) def power_spectrum(self, x, n, fs): self.axes.clear() self.axes.grid(True) self.axes.psd(x, NFFT = n, Fs = fs) self.canvas.destroy() self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.widget.pack_start(self.canvas, True, True) def clear_figure(self): self.axes.clear() self.canvas.destroy() self.axes.grid(True) self.canvas = FigureCanvasGTK(self.figure) self.canvas.show() self.widget.pack_start(self.canvas, True, True) def enable_span(self): #self.rec = RectangleSelector(self.axes, self.line_select_callback, # drawtype='box',useblit=True, # minspanx=5,minspany=5) # Unref original sublot #xmin, xmax = self.axes.get_xlim() #self.lx_min = xmin #self.lx_max = xmax self.span = SpanSelector(self.axes, self.on_select, 'horizontal', useblit=False, rectprops=dict(alpha=0.5, facecolor='red')) self.span.visible = True #self.lx = self.axes.plot((0,0), (0,0), 'k-') #self.ly = self.axes.plot((0,0), (0,0), 'k-') #self.lx = Line2D([],[], 'k-') #self.ly = Line2D([],[], 'k-') #self.lx.set_axes(self.axes) #self.ly.set_axes(self.axes) #self.lx.visible = True #self.ly.visible = True #self.on_press_cb = self.canvas.mpl_connect('button_press_event', self.on_press) #self.on_release_cb = self.canvas.mpl_connect('button_release_event', self.on_release) #self.on_motion_cb = self.canvas.mpl_connect('motion_notify_event', self.on_motion) #self.canvas.show() def on_select(self, xmin, xmax): #indmin, indmax = npy.searchsorted(x, (xmin, xmax)) #indmax = min(len(x)-1, indmax) #print xmin #print xmax #thisx = x[indmin:indmax] #thisy = y[indmin:indmax] #self.figure.set_data(thisx, thisy) self.lx_min = xmin self.lx_max = xmax self.axes.set_xlim(xmin, xmax) #self.axes.set_ylim(thisy.min(), thisy.max()) self.figure.canvas.draw() def disable_span(self): self.span.visible = False #self.on_press_cb = None #self.on_release_cb = None #self.on_motion_cb = None def line_select_callback(self, event1, event2): x1, y1 = event1.xdata, event1.ydata x2, y2 = event2.xdata, event2.ydata print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)"%(x1,y1,x2,y2) print " The button you used were: ",event1.button, event2.button def destroy(self): self.canvas.destroy()