class MplCanvas(FigureCanvas): def __init__(self, parent=None, width=5, height=4, dpi=100): matplotlib.rcParams['font.size'] = 8 self.figure = Figure(figsize=(width, height), dpi=dpi) self.axes = self.figure.add_subplot(111) FigureCanvas.__init__(self, self.figure) self.setParent(parent) self.toolbar = NavigationToolbar(self, parent) self.toolbar.setIconSize(QSize(16, 16)) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) def getToolbar(self): return self.toolbar def clear(self): self.figure.clear() self.axes = self.figure.add_subplot(111) def test(self): self.axes.plot([1,2,3,4]) def saveAs(self, fname): self.figure.savefig(fname)
def gr_aps_sl(request, scan_year, scan_month, scan_day): scs=Scan.objects.filter(scan_time__year = scan_year).filter(scan_time__month = scan_month).filter(scan_time__day = scan_day) colorlist=[ 'blue','green','red','cyan','magenta','yellow','beige','bisque','brown','burlywood','chartreuse','chocolate','coral','cornsilk','firebrick','gainsboro','gold','goldenrod','gray','grey','honeydew','ivory','khaki','lavender','lime','linen','maroon','moccasin','navy','olive','orange','orchid','peru','pink','plum','purple','salmon','seashell','sienna','snow','tan','thistle','tomato','turquoise','violet','wheat','white','aquamarine','azure'] fig = Figure(figsize=(46,16)) ax=fig.add_subplot(111) ta=timezone.datetime(int(scan_year), int(scan_month), int(scan_day)) tn=ta.replace(tzinfo=timezone.utc) x=[tn+timezone.timedelta(minutes=i) for i in xrange(24 * 60)] dapssl = dict() for s in scs: for ap in s.apoint_set.all(): k = ap.ssid if len(k) == 0: k = ap.bssid if not dapssl.has_key(k): dapssl[k] = [None for i in range(24 * 60)] dapssl[k][(s.scan_time-tn).seconds / 60] = ap.signal_level i = 0 for k in dapssl: ax.plot(x, dapssl[k], 'o', color=colorlist[i]) i += 1 ax.legend(dapssl.keys()) canvas=FigureCanvas(fig) response=HttpResponse(content_type='image/png') canvas.print_png(response) fig.clear() return response
class PlotWidget(QWidget): def __init__(self): super(PlotWidget, self).__init__() self.initUI() self.data = np.arange(20).reshape([4, 5]).copy() self.on_draw() def initUI(self): self.fig = Figure((5.0, 4.0), dpi=50) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() # self.mpl_toolbar = NavigationToolbar(self.canvas, self) # # self.canvas.mpl_connect('key_press_event', self.on_key_press) vbox = QVBoxLayout() vbox.addWidget(self.canvas) # the matplotlib canvas # vbox.addWidget(self.mpl_toolbar) self.setLayout(vbox) def on_draw(self): self.fig.clear() self.axes = self.fig.add_subplot(111) # self.axes.plot(self.x, self.y, 'ro') self.axes.imshow(self.data, interpolation='nearest') # self.axes.plot([1,2,3]) self.canvas.draw() def on_key_press(self, event): print('you pressed', event.key) # implement the default mpl key press events described at # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts key_press_handler(event, self.canvas, self.mpl_toolbar)
class MathTextLabel(qt.QWidget): def __init__(self, mathText, parent=None, **kwargs): qt.QWidget.__init__(self, parent, **kwargs) l=qt.QVBoxLayout(self) l.setContentsMargins(0,0,0,0) r,g,b,a=self.palette().base().color().getRgbF() self._figure=Figure(edgecolor=(r,g,b), facecolor=(r,g,b)) self._canvas=FigureCanvas(self._figure) l.addWidget(self._canvas) self._figure.clear() text=self._figure.suptitle( mathText, x=0.0, y=1.0, horizontalalignment='left', verticalalignment='top', size=qt.qApp.font().pointSize()*3) self._canvas.draw() (x0,y0),(x1,y1)=text.get_window_extent().get_points() w=x1-x0; h=y1-y0 #self._figure.set_size_inches(w/4, h/4) self.setFixedSize(w,h)
class MatplotlibPlot: """ Class encapsulating a matplotlib plot""" def __init__(self, parent = None, dpi = 100, size = (5,5)): """ Class initialiser """ self.dpi = dpi self.figure = Figure(size, dpi = self.dpi) self.canvas = FigureCanvas(self.figure) self.canvas.setParent(parent) # Create the navigation toolbar, tied to the canvas self.toolbar = NavigationToolbar(self.canvas, parent) self.canvas.show() self.toolbar.show() # Reset the plot landscape self.figure.clear() def plotMultiPixel(self, info, data): """ Generate multi-pixel plot """ # Tabula Rasa self.figure.clear() rows = math.ceil(math.sqrt(info['nbeams'])) # Display a subplot per beam (randomly for now) for i in range(info['nbeams']): ax = self.figure.add_subplot(rows, rows, i) ax.plot(data[:,512,i]) def updatePlot(self): self.canvas.draw()
class GraphFrame(wx.Frame): def __init__(self, maze_width=70, maze_height=70, magnification=8): wx.Frame.__init__(self, None, -1, 'Maze Generator') self.Bind(wx.EVT_CLOSE, self.OnClose, self) self.running = False self.maze_width = maze_width self.maze_height = maze_height self.magnification = magnification sizer = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(hSizer) btnStart = wx.Button(self, -1, "Start") self.Bind(wx.EVT_BUTTON, self.OnStart, btnStart) hSizer.Add(btnStart) btnStop = wx.Button(self, -1, "Stop") self.Bind(wx.EVT_BUTTON, self.OnStop, btnStop) hSizer.Add(btnStop) self.fig = Figure() self.canvas = FigureCanvasWxAgg(self, -1, self.fig) sizer.Add(self.canvas, 1, wx.LEFT|wx.TOP|wx.GROW) self.SetSizer(sizer) self.SetSize((800, 500)) def OnClose(self, evt): self.running = False self.plot_thread.join() evt.Skip() def OnStart(self, evt): self.Plot() def OnStop(self, evt): self.running = False def Plot(self): if self.running: return def thread(): self.running = True for m in maze(self.maze_width, self.maze_height): if not self.running: break wx.CallAfter(self.plot_data, magnify(m, magnification=self.magnification)) time.sleep(0.05) self.plot_thread = threading.Thread(target=thread) self.plot_thread.start() def plot_data(self, snapshot): self.fig.clear() self.fig.figimage(snapshot, 0, 0, cmap=plt.cm.binary) self.canvas.draw()
def export_results(self): """save all selected plots""" caption = 'select output folder' out_folder = str(QtGui.QFileDialog.getExistingDirectory(caption=caption)) params = {'threshold': float(self.plot_threshold_box.currentText())} json.dump(self.config, open(os.path.join(out_folder, 'config.json'), 'w')) if not os.path.exists(os.path.join(out_folder, 'timeseries')): os.mkdir(os.path.join(out_folder, 'timeseries')) progdialog = QtGui.QProgressDialog('export results..', 'cancel', 0, len(self.filelist), self) progdialog.setMinimumDuration(0) progdialog.setWindowModality(QtCore.Qt.WindowModal) fig = Figure() for i, session in enumerate(self.filelist): #ToDo: OS independent solution sessionname = ''.join(session.split('/timeseries')) progdialog.setValue(i) for plot_method in self.plot_methods: fig.clear() if not os.path.exists(os.path.join(out_folder, plot_method)): os.mkdir(os.path.join(out_folder, plot_method)) self.plot_methods[plot_method](self.results[session], fig, params) plot_name = sessionname + '_' + plot_method.replace(' ', '_') plot_name += '.' + self.config['format'] fig.savefig(os.path.join(out_folder, plot_method, plot_name)) self.results[session]['mf'].save(os.path.join(out_folder, 'timeseries', sessionname)) progdialog.setValue(len(self.filelist))
class CanvasPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.figure = Figure() self.axes = self.figure.add_subplot(111) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(self.sizer) self.Fit() def show_data(self,fbfile,fields=['cond','imu_a']): if fbfile.data is None: return self.figure.clear() axs=[] for axi,varname in enumerate(fields): if axi==0: sharex=None else: sharex=axs[0] ax=self.figure.add_subplot(len(fields),1,axi+1,sharex=sharex) axs.append(ax) ax.plot_date( fbfile.data['dn_py'], fbfile.data[varname], 'g-') self.figure.autofmt_xdate() # Not sure how to trigger it to actually draw things. self.canvas.draw() self.Fit()
class GraphCanvas(FigureCanvas): def __init__(self, width = 5, height = 4, dpi = 100): # Create a figure self.figure = Figure(figsize=(width, height), dpi=dpi, facecolor = '#D4D0C8') # Add the figure to the canvas FigureCanvas.__init__(self, self.figure) # Set the canvas properties on resizing FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) def plot_figure(self, bars = None, stats = None): data, data_labels = bars time, total, success, error, empty = stats # Add an axis to the figure axis = self.figure.add_subplot(111) axis.hold(False) epsilon = 1e-7 data = numpy.array(data) + epsilon n = len(data) indices = numpy.arange(n) width = 0.35 axis.bar(indices + width, data, width) axis.set_xticks(width + indices + width/2) axis.set_xticklabels(data_labels) axis.set_ylim([0, 100]) axis.set_xlabel("Node ID") axis.set_ylabel("Percentage (%)") axis.grid(which="both") axis.tick_params(axis='both', labelsize=10) axis.yaxis.set_major_locator(MultipleLocator(10)) axis.yaxis.set_minor_locator(MultipleLocator(5)) stats = "Time: " + str(round(time, 2)) + " seconds" + "\n" stats += "Total: " + str(int(total)) + " packets" + "\n" stats += "Success: " + str(round((100.0 * success/total),2)) + "%" + "\n" stats += "Empty: " + str(round(100.0 * empty/total,2)) + "%" + "\n" stats += "Collision: " + str(round(100.0 * error/total,2)) + "%" + "\n" stats += "PHY: " + str(round(total / time,2)) + " pps" + "\n" stats += "MAC: " + str(round(success / time,2)) + " pps" bbox_props = dict(boxstyle="square", fc="grey", ec="0.0", alpha=0.5) axis.text(0.90, 0.75, stats, ha="center", va="center", transform=axis.transAxes, size=12, bbox=bbox_props) self.draw() def restore_figure(self): # Clear the current figure self.figure.clear() def save_figure(self, mac_type = None): self.figure.savefig(str(mac_type) + ".pdf", dpi=300, facecolor='w', bbox_inches='tight')
def initializeCanvas(self, img) : fig = Figure() fig.clear() Graph = fig.add_subplot(111) Graph.imshow(img, zorder=0, extent=[0.0, 1.0, 0.0, 1.0]) return fig
class PlotWidget(QWidget): def __init__(self, name, plotFunction, plot_condition_function_list, plotContextFunction, parent=None): QWidget.__init__(self, parent) self.__name = name self.__plotFunction = plotFunction self.__plotContextFunction = plotContextFunction self.__plot_conditions = plot_condition_function_list """:type: list of functions """ self.__figure = Figure() self.__figure.set_tight_layout(True) self.__canvas = FigureCanvas(self.__figure) self.__canvas.setParent(self) self.__canvas.setFocusPolicy(Qt.StrongFocus) self.__canvas.setFocus() vbox = QVBoxLayout() vbox.addWidget(self.__canvas) self.__toolbar = NavigationToolbar(self.__canvas, self) vbox.addWidget(self.__toolbar) self.setLayout(vbox) self.__dirty = True self.__active = False self.resetPlot() def getFigure(self): """ :rtype: matplotlib.figure.Figure""" return self.__figure def resetPlot(self): self.__figure.clear() def updatePlot(self): if self.isDirty() and self.isActive(): print("Drawing: %s" % self.__name) self.resetPlot() plot_context = self.__plotContextFunction(self.getFigure()) self.__plotFunction(plot_context) self.__canvas.draw() self.setDirty(False) def setDirty(self, dirty=True): self.__dirty = dirty def isDirty(self): return self.__dirty def setActive(self, active=True): self.__active = active def isActive(self): return self.__active def canPlotKey(self, key): return any([plotConditionFunction(key) for plotConditionFunction in self.__plot_conditions])
class PlotWindow(QWidget): def __init__(self, parent=None, devices=None): super(PlotWindow, self).__init__(parent) # matplotlib stuff self.figure = Figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.plot_layout = QtGui.QVBoxLayout() self.plot_layout.addWidget(self.toolbar) self.plot_layout.addWidget(self.canvas) self.setLayout(self.plot_layout) self.devices = [] if not devices is None: for d in devices: self.addDevice(d) # self.updatePlot() def addDevice(self, device): if device not in self.devices: self.devices.append(device) device.dataChanged.connect(self.updateDevice) print "addDevice - new list:" for d in self.devices: print d.mac def removeDevice(self, device): try: self.devices.remove(device) device.dataChanged.disconnect(self.updateDevice) except Exception: pass print "removeDevice - new list:" for d in self.devices: print d.mac def updateDevice(self, device): self.data_x = [] for d in self.devices: x = [] for b in d.history: x.append(b.rssi) self.data_x.append(x) self.updatePlot() def updatePlot(self): self.figure.clear() self.axes = self.figure.add_subplot(111) #self.axes.plot(self.data_x1, self.data_y1, "ro") #self.axes.plot(self.data_x1, self.data_y2, "go") self.axes.hist(self.data_x) self.canvas.draw()
class SpectrumPanel(wx.Panel): def __init__(self, parent, xlabel='m/z', ylabel='Intensity'): wx.Panel.__init__(self, parent) # self.parent = parent self.xlabel = xlabel self.ylabel = ylabel self.SetBackgroundColour("white") # self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) # self.add_toolbar() # sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP| wx.GROW| wx.EXPAND) sizer.Add(self.toolbar, 0, wx.LEFT) self.canvas.mpl_connect('motion_notify_event', self.on_motion) self.SetSizer(sizer) self.Fit() self.clean() # def add_toolbar(self): "" self.toolbar = NavigationToolbar2Wx(self.canvas) mass_txt = wx.StaticText(self.toolbar, label='m/z', pos=(230, 7), size=(25, 17)) mass_txt.SetBackgroundColour("light gray") self.mass = wx.TextCtrl(self.toolbar, pos=(260,4), size=(50, 22), style=wx.TE_READONLY) # self.toolbar.SetToolBitmapSize(wx.Size(24, 25)) self.toolbar.SetMinSize((1500, 31)) self.toolbar.Realize() self.toolbar.Update() # def clean(self): "" self.figure.clear() self.axes = self.figure.add_subplot(111) # def dibuja(self): "dibuja el canvas" self.axes.set_xlabel(self.xlabel) self.axes.set_ylabel(self.ylabel) self.canvas.draw() # def on_motion(self, evt): if evt.inaxes: xpos = evt.xdata self.mass.SetValue(' %0.1f' % (xpos)) print evt.xdata,evt.ydata
class MplPanel(wx.Panel): def __init__(self, *args, **kwds): self.figure = Figure() # begin wxGlade: MplPanel.__init__ kwds["style"] = wx.TAB_TRAVERSAL wx.Panel.__init__(self, *args, **kwds) self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure) self.__set_properties() self.__do_layout() # end wxGlade #connect event for a popup menu self.cidrelease = self.canvas.mpl_connect( 'button_release_event', self.on_right_release) def __set_properties(self): # begin wxGlade: MplPanel.__set_properties pass # end wxGlade def __do_layout(self): # begin wxGlade: MplPanel.__do_layout sizer_3 = wx.BoxSizer(wx.HORIZONTAL) sizer_3.Add(self.canvas, 1, wx.EXPAND, 0) self.SetSizer(sizer_3) sizer_3.Fit(self) # end wxGlade def set_grid(self, nr, nc): self.figure.clear() #setup gridspec with the number of rows and columns given self.gridspec = gridspec.GridSpec(nr, nc) #add axis to each cell of the gridspec for i in range(nr*nc): #instead of built in Axes, create CustomMplAxes self.figure.add_subplot(self.gridspec[i], projection="CustomMplAxes") self.canvas.draw() def on_right_release(self, event): #only right button is considered if event.button == 3: #only if click happened inside axes if event.inaxes: menu = AxesPopupMenu(self.figure, event.inaxes) self.PopupMenu(menu) menu.Destroy() self.canvas.draw()
class GraphicPanel(wx.Panel): def __init__(self,parent): wx.Panel.__init__(self,parent) # CANVAS & FIGURE MATPLOTLIB self.__figure = Figure() self.__canvas = CanvasPanel(self, -1, self.__figure) # SLIDE (MODEL) self.__slide = None # GRAPHIC CONTROL self.__graphicCtrl = GraphicCtlr(self.__canvas) # RESIZE sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.__canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.SetSizer(sizer) self.Fit() self.Show() def draw(self): self.__canvas.draw() def OnPaint(self, event): self.draw() def getCanvas(self): return self.__canvas def getFigure(self): return self.__figure def getGraphicCtrl(self): return self.__graphicCtrl def getSlide(self): return self.__slide def setSlide(self,slide): self.__slide = slide def build(self,*args,**kwargs): self.__figure.clear() if not self.__slide is None: buildFigure(self.__figure,self.__slide) def control(self): self.__graphicCtrl.control()
class AppForm(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) #self.x, self.y = self.get_data() self.data = self.get_data2() self.create_main_frame() self.on_draw() def create_main_frame(self): self.main_frame = QWidget() self.fig = Figure((5.0, 4.0), dpi=100) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) self.canvas.mpl_connect('key_press_event', self.on_key_press) vbox = QVBoxLayout() vbox.addWidget(self.canvas) # the matplotlib canvas vbox.addWidget(self.mpl_toolbar) self.main_frame.setLayout(vbox) self.setCentralWidget(self.main_frame) def get_data2(self): return np.arange(20).reshape([4, 5]).copy() def on_draw(self): self.fig.clear() self.axes = self.fig.add_subplot(111) #self.axes.plot(self.x, self.y, 'ro') self.axes.imshow(self.data, interpolation='nearest') #self.axes.plot([1,2,3]) self.canvas.draw() def on_key_press(self, event): print('you pressed', event.key) # implement the default mpl key press events described at # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts key_press_handler(event, self.canvas, self.mpl_toolbar)
class JwsFileChooserDialog(gtk.FileChooserDialog): def __init__(self, parent, current_folder=None, title=_("Open spectra...")): gtk.FileChooserDialog.__init__( self, title=title, parent=parent, action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_ADD, gtk.RESPONSE_OK), ) self.figure = Figure(figsize=(5, 4)) self.canvas = FigureCanvas(self.figure) self.canvas.set_size_request(200, 200) # tamaño mínimo del widget self.add_filter(ff_jws) self.set_select_multiple(True) if current_folder: self.set_current_folder(current_folder) self.set_preview_widget(self.canvas) self.connect("selection-changed", self._update_preview_cb) self.show_all() def _update_preview_cb(self, widget): input_fn = self.get_preview_filename() error = True if input_fn is not None: results = jwslib.read_file(input_fn) if results[0] == jwslib.JWS_ERROR_SUCCESS: header = results[1] channels = results[2] if len(channels) > 0: error = False if not error: xdata = arange( header.x_for_first_point, # start header.x_for_last_point + header.x_increment, # end+incr. header.x_increment, ) # increment ellipticity = array(channels[0], float32) self.figure.clear() p = self.figure.add_subplot(111) p.plot(xdata, ellipticity) self.canvas.draw() self.set_preview_widget_active(not error)
class MatplotlibPlot: """ Class encapsulating an matplotlib plot""" def __init__(self, parent = None, dpi = 100, size = (5,4)): """ Class initialiser """ self.dpi = dpi self.figure = Figure(size, dpi = self.dpi) self.canvas = FigureCanvas(self.figure) self.canvas.setParent(parent) # Create the navigation toolbar, tied to the canvas self.toolbar = NavigationToolbar(self.canvas, parent) self.canvas.show() self.toolbar.show() def plotCurve(self, data, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""): """ Plot the data as a curve""" # clear the axes and redraw the plot anew self.figure.clear() self.axes = self.figure.add_subplot(111) self.axes.grid(True) self.axes.plot(range(np.size(data)), data) if xAxisRange is not None: self.xAxisRange = xAxisRange self.axes.xaxis.set_major_formatter(ticker.FuncFormatter( lambda x, pos=None: '%.2f' % self.xAxisRange[x] if 0 <= x < len(xAxisRange) else '')) for tick in self.axes.xaxis.get_ticklabels(): tick.set_rotation(15) if yAxisRange is not None: self.yAxisRange = yAxisRange self.axes.xaxis.set_major_formatter(ticker.FuncFormatter( lambda x, pos=None: '%.1f' % self.yAxisRange[y] if 0 <= y < len(yAxisRange) else '')) for tick in self.axes.yaxis.get_ticklabels(): tick.set_rotation(15) self.axes.xaxis.set_label_text(xLabel) self.axes.yaxis.set_label_text(yLabel) self.canvas.draw()
class MyFigure(FigureCanvas): def __init__(self): self.fig = Figure() FigureCanvas.__init__(self, self.fig) self.main_plot = None self.create_main_plot() def create_main_plot(self): self.main_plot = self.fig.add_subplot(111) def reset(self): self.fig.clear() self.main_plot.clear() self.create_main_plot() def save_file(self, file_name): """Supported formats: eps, pdf, pgf, png, ps, raw, rgba, svg, svgz.""" self.fig.savefig(file_name)
class MyStaticMplCanvas(FigureCanvas): """Simple canvas with a sine plot.""" def __init__(self, parent=None, width=5, height=4, dpi=100): self.fig = Figure(figsize=(width, height), dpi=dpi) self.axes = self.fig.add_subplot(111) i = self.axes.imshow(np.outer(np.linspace(0, 1, 10), np.linspace(0, 2, 10)), zorder=1) self.cbar = self.fig.colorbar(i) # We want the axes cleared every time plot() is called # self.axes.hold(False) # FigureCanvas.__init__(self, self.fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) self.crosshairs_x = 0 self.crosshairs_y = 0 self.bg_rect = Rectangle((0, 0), 0, 0, facecolor="blue", edgecolor="blue", alpha=0.3, zorder=8) self.axes.add_patch(self.bg_rect) self.signal_rect = Rectangle((0, 0), 0, 0, facecolor="red", edgecolor="red", alpha=0.3, zorder=9) self.axes.add_patch(self.signal_rect) self.anno = spot_picker.Annotate(self.axes) self.draw() def clear(self): self.fig.clear() # self.axes = self.fig.add_subplot(111) def show_portrait(self, portrait): self.fig.clear() self.axes = self.fig.add_subplot(111) self.axes.imshow(portrait, origin="bottom") self.draw()
def gr(request, scan_year, scan_month, scan_day): scs=Scan.objects.filter(scan_time__year = scan_year).filter(scan_time__month = scan_month).filter(scan_time__day = scan_day) from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.dates import DateFormatter fig = Figure(figsize=(16,6)) ax=fig.add_subplot(111) y=[None for i in range(24 * 60)] ta=timezone.datetime(int(scan_year), int(scan_month), int(scan_day)) tn=ta.replace(tzinfo=timezone.utc) x=[tn+timezone.timedelta(minutes=i) for i in xrange(24 * 60)] for s in scs: y[(s.scan_time-tn).seconds / 60]=s.apoint_set.count() ax.plot(x, y, '.') canvas=FigureCanvas(fig) response=HttpResponse(content_type='image/png') canvas.print_png(response) fig.clear() return response
def createHardnessProfile(widths, heights, show_plot=True): if show_plot: fig = plt.figure() else: fig = Figure() fig.clear() fig.patch.set_facecolor('white') ax = fig.add_subplot(1, 1, 1) currentHeight = 0 for i in range(len(widths) - 1): color = COLOR_CONVERSIONS[widths[i]] patch = patches.Rectangle((0, 1.0 * currentHeight), 1.0 * widths[i], heights[i], color=color) currentHeight += heights[i] ax.add_patch(patch) ax.set_title('Snow Profile Hardness by SnowGeek') ax.set_xticks(range(11)) ax.set_xticklabels(HARDNESSES) ax.set_xlabel('Hardness') ax.set_ylabel('Depth (cm)') ax.set_yticks(range(0, int(sum(heights)) + 1, 10)) ax.invert_yaxis() if show_plot: plt.show() return fig
class LoggerPlot (gtk.VBox): def __init__ (self): gtk.VBox.__init__ (self) self.figure = Figure(figsize=(5,4), dpi=100) self.canvas = FigureCanvas (self.figure) self.toolbar = NavigationToolbar (self.canvas, None) self.pack_start (self.canvas) self.pack_start (self.toolbar, False, False) #FigureCanvas.__init__ (self, self.figure) def plot (self, title, x, y): self.figure.clear() a = self.figure.add_subplot(111) a.set_title (title) a.grid(True) a.plot(x,y) self.canvas.draw() def clear (self): self.figure.clear() self.canvas.draw()
class SpectroCanvas(FigureCanvas): """Class to represent the FigureCanvas widget""" def __init__(self): # setup Matplotlib Figure and Axis self.fig = Figure() # initialization of the canvas FigureCanvas.__init__(self, self.fig) self.ax = self.fig.clear() self.ax = self.fig.add_subplot(111) self.fig.subplots_adjust(left=0.12,right=0.98,bottom=0.1, top=.97) # we define the widget as expandable FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # notify the system of updated policy FigureCanvas.updateGeometry(self)
class RadianceSampleViewer(QtGui.QMainWindow): def __init__(self, parent=None): super(RadianceSampleViewer, self).__init__(parent) self.setWindowTitle("Radiance Sample Viewer") self.setAcceptDrops(True) # Build the main plot canvas self.plot = Figure(facecolor=(0.933, 0.933, 0.933), edgecolor=(0, 0, 0)) self.plotCanvas = FigureCanvas(self.plot) self.setCentralWidget(self.plotCanvas) # Build the sample tree view self.sampleTreeDock = QtGui.QDockWidget("Open Samples", self) self.sampleTreeDock.setAllowedAreas(QtCore.Qt.RightDockWidgetArea) self.sampleTree = QtGui.QTreeWidget() self.sampleTree.setSortingEnabled(True) self.sampleTree.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.sampleTree.itemSelectionChanged.connect(self.SOCKET_handleSampleSelection) self.sampleTree.itemChanged.connect(self.SOCKET_handleSampleCheck) self.sampleTree.setHeaderLabels(["Date", "Time", "Azimuth", "Elevation"]) self.sampleTreeDock.setWidget(self.sampleTree) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.sampleTreeDock) # Build the fisheye view dock self.fisheyeDock = QtGui.QDockWidget("Fisheye Viewer", self) self.fisheyeDock.setAllowedAreas(QtCore.Qt.RightDockWidgetArea) self.fisheyeView = fisheye_view.FisheyeViewer() self.fisheyeDock.setWidget(self.fisheyeView) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.fisheyeDock) # Setup the file menu bar self.menubar = self.menuBar() fileMenu = self.menubar.addMenu("&File") loadRadianceAction = QtGui.QAction("&Load Radiance File", self) loadRadianceAction.triggered.connect(self.SOCKET_loadRadianceData) fileMenu.addAction(loadRadianceAction) loadFisheyeAction = QtGui.QAction("Load Fisheye Image", self) loadFisheyeAction.triggered.connect(self.SOCKET_loadFisheyeImage) fileMenu.addAction(loadFisheyeAction) clearDataAction = QtGui.QAction("&Clear Radiance Data", self) clearDataAction.triggered.connect(self.sampleTree.clear) fileMenu.addAction(clearDataAction) def SOCKET_handleSampleSelection(self): """ Redraw the graph when the user selection changes. """ self.plotRadianceData() def SOCKET_handleSampleCheck(self, item, column): """ Add or remove a sample plot from the radiance plotter bsed on if it is checked or not. """ self.plotRadianceData() def dragEnterEvent(self, event): """ Accept drag events concerning files. """ if event.mimeData().hasUrls(): event.accept() else: event.ignore() def addSampleItem(self, sampleData, sampleFile): """ Add a radiance sample to the tree widget and the radiance plot. """ # Add the file to the tree list treeWidgetItem = RadianceSampleItem(sampleData, self.sampleTree) treeWidgetItem.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable) treeWidgetItem.setCheckState(0, QtCore.Qt.Unchecked) fileInfo = self.parseRadianceFileName(sampleFile) # Add columns for each of the data fields treeWidgetItem.setText(0, fileInfo[0]) # Date treeWidgetItem.setText(1, fileInfo[1]) # Time treeWidgetItem.setText(2, fileInfo[4]) # Azimuth treeWidgetItem.setText(3, fileInfo[5]) # Elevation self.sampleTree.addTopLevelItem(treeWidgetItem) def dropEvent(self, event): """ Handle the file drop event and load the radiance file dropped on the window. """ files = event.mimeData().urls() self.sampleTree.blockSignals(True) for radianceFile in files: # Add the sample data to the file list radianceSample = self.loadRadianceDataFile(radianceFile.toLocalFile()) self.addSampleItem(radianceSample, radianceFile.toLocalFile()) self.sampleTree.blockSignals(False) self.plotRadianceData() def parseRadianceFileName(self, filename): """ Parses out the date, time, and angle information from a radiance file. """ fileComponents = os.path.split(filename) fullFile = fileComponents[1] if fullFile and fullFile.endswith(".asd.rad.txt"): noExt = fullFile[:-12] noExt = re.sub("_+", "_", noExt) fileInfo = noExt.split('_') return fileInfo def plotRadianceData(self): """ Plot the current radiance data loaded into memory. """ self.plot.clear() ax = self.plot.add_subplot(111) ax.axis([350, 800, 0.0, 0.3]) ax.set_ylabel("Radiance ($W/m^2$)") ax.set_xlabel("Wavelength ($nm$)") selectedSample = None selectedIndex = None for i in range(self.sampleTree.topLevelItemCount()): sampleItem = self.sampleTree.topLevelItem(i) sample = sampleItem.radianceData if sampleItem.isSelected(): selectedSample = [sample.keys(), sample.values()] selectedIndex = i # Update the fisheye view with the correct angle pair azimuth = float(sampleItem.text(2)) elevation = float(sampleItem.text(3)) self.fisheyeView.reset() self.fisheyeView.drawAnglePosition(azimuth, elevation, inRadians=False) if sampleItem.checkState(0) == QtCore.Qt.Checked: ax.plot(sample.keys(), sample.values(), color="#000000") # Redraw the selected sample in a thicker line if selectedSample: ax.plot(selectedSample[0], selectedSample[1], color="#4499FF", linewidth=3) self.plot.text(0.05, 0.95, "%d" % selectedIndex) self.plotCanvas.draw() if selectedSample: saveFilename = "C:/Users/dtk47/Desktop/THESIS/plot%05d.png" % selectedIndex self.plot.savefig(saveFilename) def SOCKET_loadRadianceData(self): """ Allow the user to open a new radiance file and display the file in the radiance plot. """ radianceFiles = QtGui.QFileDialog.getOpenFileNames(self, "Radiance File")[0] self.sampleTree.blockSignals(True) for radianceFile in radianceFiles: radianceSample = self.loadRadianceDataFile(radianceFile) self.addSampleItem(radianceSample, radianceFile) self.sampleTree.blockSignals(False) self.plotRadianceData() def SOCKET_loadFisheyeImage(self): """ Allow the user to load a fisheye image to display in conjunction with the radiance samples to display the angle associated with the selected sample. """ fisheyeFile = QtGui.QFileDialog.getOpenFileName(self, "Fisheye File") fisheyeFilename = fisheyeFile[0] self.fisheyeView.loadFisheyeFile(fisheyeFilename) def loadRadianceDataFile(self, filename): """ Read in a radiance file in txt format, and return a dictionary of wavelength to radiance. """ radianceFile = open(filename, 'r') radianceDict = {} for line in radianceFile: fileCols = line.split('\t') try: # Try to parse the first piece as in int wavelength wavelength = int(fileCols[0]) radiance = float(fileCols[1]) radianceDict[wavelength] = radiance except ValueError: # Catch the error on the first line, and continue print line continue radianceFile.close() return radianceDict def quit(self): self.close()
class FS_window(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): #初始化,没有父类 super(FS_window, self).__init__(parent) self.setupUi(self) self.setWindowTitle('基于机器视觉的智慧农药化肥喷洒平台') #给一个窗口标题 self.setStyleSheet("#Main_Window{background-color: white}") self.setStyleSheet("#stackedWidget{background-color: white}") self.train_data.triggered.connect(self.load_traindata) #链接训练数据 self.test_data.triggered.connect(self.load_testdata) #链接测试数据,在界面左上角 self.picture_data.triggered.connect(self.load_picturedata) #链接图片数据 #按钮空间对应界面的不同页面 self.button_reading.clicked.connect( self.topage_1) #一个按钮可以与一个页面(page)连接 self.button_preprocessing.clicked.connect(self.topage_2) self.button_segemation.clicked.connect(self.topage_3) self.button_feature_extraction.clicked.connect(self.topage_4) self.button_classification.clicked.connect(self.topage_8) self.button_color_feature.clicked.connect(self.topage_5) self.button_shape_feature.clicked.connect(self.topage_6) self.button_texture_feature.clicked.connect(self.topage_7) #先让button灰调,也就是按钮按不了。等它前面的步骤都做完了,再亮回来。 #self.button_preprocessing.setEnabled(False) #self.button_segemation.clicked.setEnabled(False) #self.button_feature_extraction.setEnabled(False) #self.button_classification.clicked.setEnabled(False) #self.button_color_feature.clicked.setEnabled(False) #self.button_shape_feature.clicked.setEnabled(False) #self.button_texture_feature.clicked.setEnabled(False) #按钮控件对应函数 self.button_get_picture.clicked.connect( self.get_picture) #和后面的函数连接,也就是我们写的函数 self.button_histogram_equalization.clicked.connect( self.histogram_equalization) self.button_color_segemation.clicked.connect(self.color_segemation) self.button_color_moment.clicked.connect(self.color_moment) #这写函数还未命名 self.button_Hu_invariant_moment.clicked.connect( self.Hu_invariant_moment) self.button_gray_level_co_occurance_matrix.clicked.connect( self.gray_level_co_occurance_matrix) self.button_classifier.clicked.connect(self.adaboost_classifier) ## 画布——对应image(原图) self.fig_image = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_image = FigureCanvas(self.fig_image) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_image = QGraphicsScene() self.graphicscene_image.addWidget(self.canvas_image) self.toolbar_image = NavigationToolbar(self.canvas_image, self.picture_dujuan_1) ## 画布——对应imageH(均衡化后的图) self.fig_imageH = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_imageH = FigureCanvas(self.fig_imageH) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_imageH = QGraphicsScene() self.graphicscene_imageH.addWidget(self.canvas_imageH) self.toolbar_imageH = NavigationToolbar(self.canvas_imageH, self.picture_imageH) ## 画布——对应img_RGB self.fig_img_RGB = Figure((7, 5)) # 15, 8这里应该只确定了figsize self.canvas_img_RGB = FigureCanvas(self.fig_img_RGB) #self.canvas_pca.setParent(self.pca_gongxiantu) self.graphicscene_img_RGB = QGraphicsScene() self.graphicscene_img_RGB.addWidget(self.canvas_img_RGB) self.toolbar_img_RGB = NavigationToolbar(self.canvas_img_RGB, self.picture_img_RGB) #界面切换 def topage_1(self): self.stackedWidget.setCurrentWidget(self.page_1) def topage_2(self): self.stackedWidget.setCurrentWidget(self.page_2) def topage_3(self): self.stackedWidget.setCurrentWidget(self.page_3) def topage_4(self): self.stackedWidget.setCurrentWidget(self.page_4) def topage_5(self): self.stackedWidget_2.setCurrentWidget(self.page_5) def topage_6(self): self.stackedWidget_2.setCurrentWidget(self.page_6) def topage_7(self): self.stackedWidget_2.setCurrentWidget(self.page_7) def topage_8(self): self.stackedWidget.setCurrentWidget(self.page_8) #导入训练数据 def load_traindata(self): try: datafile, _ = QFileDialog.getOpenFileName(self, "选择训练数据") print((datafile)) table = pd.read_csv(datafile) print(table) # table = xlrd.open_workbook(datafile).sheet_by_index(0) nrows = table.shape[0] ncols = table.shape[1] self.trainWidget.setRowCount(nrows) #确定行数 self.trainWidget.setColumnCount(ncols) #确定列数 self.train_data = np.zeros((nrows, ncols)) #设初始值,零矩阵 self.dataArr = np.zeros((nrows, ncols - 1)) self.LabelArr = np.zeros((nrows, 1)) for i in range(nrows): for j in range(ncols): #table.at[i, j] self.trainWidget.setItem( i, j, QTableWidgetItem(str( table.at[i, str(j)]))) #这里的trainWidget是界面的东西 self.train_data[i, j] = table.at[i, str(j)] #把数据一个一个导入进去 for i in range(nrows): for j in range(ncols - 1): self.dataArr[i, j] = self.train_data[i, j] for i in range(nrows): self.LabelArr[i] = self.train_data[i, -1] #print(self.dataArr) #print(self.LabelArr) #print(self.LabelArr.T) self.statusbar.showMessage('训练数据已导入') except: QMessageBox.information(self, 'Warning', '数据为CSV表格', QMessageBox.Ok) #导入测试数据 def load_testdata(self): try: datafile, _ = QFileDialog.getOpenFileName(self, "选择测试数据") table = pd.read_csv(datafile) print(table) nrows = table.shape[0] ncols = table.shape[1] self.testWidget.setRowCount(nrows) self.testWidget.setColumnCount(ncols) self.test_data = np.zeros((nrows, ncols)) self.tsetArr = np.zeros((nrows, ncols - 1)) self.testLabelArr = np.zeros((nrows, 1)) for i in range(nrows): for j in range(ncols): self.testWidget.setItem( i, j, QTableWidgetItem(str(table.at[i, str(j)]))) self.test_data[i, j] = table.at[i, str(j)] self.statusbar.showMessage('测试数据已导入') for i in range(nrows): for j in range(ncols - 1): self.tsetArr[i, j] = self.test_data[i, j] for i in range(nrows): self.testLabelArr[i] = self.test_data[i, -1] except: QMessageBox.information(self, 'Warning', '数据为CSV表格', QMessageBox.Ok) #选择图片 def load_picturedata(self): try: #选择图片 imgName, imgType = QFileDialog.getOpenFileName( self, "打开图片", "img", "*.jpg;*.tif;*.png;;All Files(*)") if imgName == "": return 0 self.img = cv2.imread(imgName) #qt5读取图片 #self.jpg = QPixmap(imgName).scaled(self.picture_dujuan_1.width(), self.picture_dujuan_1.height()) except: QMessageBox.information(self, 'Warning', '导入失败', QMessageBox.Ok) def get_picture(self): try: # img=cv2.imread("dujuan_1.jpg") #img=cv2.cvtColor(self.jpg,cv2.COLOR_RGB2BGR) # gray=cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY) # 修改原图的尺寸 fx = 0.3 fy = 0.3 self.image = cv2.resize(self.img, dsize=None, fx=fx, fy=fy, interpolation=cv2.INTER_AREA) self.fig_image.clear() plt = self.fig_image.add_subplot(111) plt.imshow(cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)) self.canvas_image.draw() self.picture_dujuan_1.setScene(self.graphicscene_image) self.picture_dujuan_1.show() #self.button_preprocessing.setEnabled(True) except: QMessageBox.information(self, 'Warning', '绘制图片的时候出错', QMessageBox.Ok) def histogram_equalization(self): (b, g, r) = cv2.split(self.image) bH = cv2.equalizeHist(b) gH = cv2.equalizeHist(g) rH = cv2.equalizeHist(r) self.imageH = cv2.merge((bH, gH, rH)) self.fig_imageH.clear() plt = self.fig_imageH.add_subplot(111) plt.imshow(cv2.cvtColor(self.imageH, cv2.COLOR_BGR2RGB)) self.canvas_imageH.draw() self.picture_imageH.setScene(self.graphicscene_imageH) self.picture_imageH.show() #self.button_segemation.clicked.setEnabled(True) def color_segemation(self): #基于H分量的双阈值分割 HSV_img = cv2.cvtColor(self.imageH, cv2.COLOR_BGR2HSV) hue = HSV_img[:, :, 0] lower_gray = np.array([1, 0, 0]) upper_gray = np.array([99, 255, 255]) mask = cv2.inRange(HSV_img, lower_gray, upper_gray) # Bitwise-AND mask and original image res2 = cv2.bitwise_and(self.imageH, self.imageH, mask=mask) # 先将这张图进行二值化 ret1, thresh1 = cv2.threshold(res2, 0, 255, cv2.THRESH_BINARY) # 然后是进行形态学操作 # 我们采用矩形核(10,10)进行闭运算 kernel_1 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10)) closing = cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel_1) # 对原图进行RGB三通道分离 (B, G, R) = cv2.split(self.image) #之前得到的图 # 三个通道分别和closing这个模板进行与运算 mask = cv2.cvtColor(closing, cv2.COLOR_BGR2GRAY) and_img_B = cv2.bitwise_and(B, mask) and_img_G = cv2.bitwise_and(G, mask) and_img_R = cv2.bitwise_and(R, mask) # 多通道图像进行混合 zeros = np.zeros(res2.shape[:2], np.uint8) img_RGB = cv2.merge([and_img_R, and_img_G, and_img_B]) # 下面我先用closing的结果,进一步进行处理 # 这个颜色空间转来转去的,要小心 img_BGR = cv2.cvtColor(img_RGB, cv2.COLOR_RGB2BGR) #这个颜色空间转来转去的,要小心 HSV_img = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV) hue = HSV_img[:, :, 0] lower_gray = np.array([1, 0, 0]) upper_gray = np.array([99, 255, 255]) mask = cv2.inRange(HSV_img, lower_gray, upper_gray) # Bitwise-AND mask and original image self.result = cv2.bitwise_and(img_BGR, img_BGR, mask=mask) self.fig_img_RGB.clear() plt = self.fig_img_RGB.add_subplot(111) plt.imshow(cv2.cvtColor(self.result, cv2.COLOR_BGR2RGB)) self.canvas_img_RGB.draw() self.picture_img_RGB.setScene(self.graphicscene_img_RGB) self.picture_img_RGB.show() #self.button_feature_extraction.setEnabled(True) #self.button_color_feature.clicked.setEnabled(True) #self.button_shape_feature.clicked.setEnabled(True) #self.button_texture_feature.clicked.setEnabled(True) def color_moment(self): try: # Convert BGR to HSV colorspace hsv = cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV) # Split the channels - h,s,v h, s, v = cv2.split(hsv) # Initialize the color feature color_feature = [] # N = h.shape[0] * h.shape[1] # The first central moment - average h_mean = np.mean(h) # np.sum(h)/float(N) s_mean = np.mean(s) # np.sum(s)/float(N) v_mean = np.mean(v) # np.sum(v)/float(N) color_feature.extend([h_mean, s_mean, v_mean]) # The second central moment - standard deviation h_std = np.std(h) # np.sqrt(np.mean(abs(h - h.mean())**2)) s_std = np.std(s) # np.sqrt(np.mean(abs(s - s.mean())**2)) v_std = np.std(v) # np.sqrt(np.mean(abs(v - v.mean())**2)) color_feature.extend([h_std, s_std, v_std]) # The third central moment - the third root of the skewness h_skewness = np.mean(abs(h - h.mean())**3) s_skewness = np.mean(abs(s - s.mean())**3) v_skewness = np.mean(abs(v - v.mean())**3) h_thirdMoment = h_skewness**(1. / 3) s_thirdMoment = s_skewness**(1. / 3) v_thirdMoment = v_skewness**(1. / 3) color_feature.extend([h_thirdMoment, s_thirdMoment, v_thirdMoment]) self.lineEdit_H_first.setText(str(color_feature[0])) self.lineEdit_H_second.setText(str(color_feature[1])) self.lineEdit_H_third.setText(str(color_feature[2])) self.lineEdit_S_first.setText(str(color_feature[3])) self.lineEdit_S_second.setText(str(color_feature[4])) self.lineEdit_S_third.setText(str(color_feature[5])) self.lineEdit_V_first.setText(str(color_feature[6])) self.lineEdit_V_second.setText(str(color_feature[7])) self.lineEdit_V_third.setText(str(color_feature[8])) except: QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok) def Hu_invariant_moment(self): try: seg = self.result seg_gray = cv2.cvtColor(seg, cv2.COLOR_BGR2GRAY) moments = cv2.moments(seg_gray) humoments = cv2.HuMoments(moments) humoments = np.log(np.abs(humoments)) # 同样建议取对数 self.fai_1.setText(str(humoments[0])) self.fai_2.setText(str(humoments[1])) self.fai_3.setText(str(humoments[2])) self.fai_4.setText(str(humoments[3])) self.fai_5.setText(str(humoments[4])) self.fai_6.setText(str(humoments[5])) self.fai_7.setText(str(humoments[6])) except: QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok) def gray_level_co_occurance_matrix(self): try: img_shape = self.result.shape resized_img = cv2.resize( self.result, (int(img_shape[1] / 2), int(img_shape[0] / 2)), interpolation=cv2.INTER_CUBIC) img_gray = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY) gray_level = 16 #之前的getGlcm(self,img_gray,d_x,d_y) d_x = 0 d_y = 1 srcdata = img_gray.copy() p = [[0.0 for i in range(gray_level)] for j in range(gray_level)] (height, width) = img_gray.shape #以前的maxGrayLevel(img) max_gray_level = 0 (height, width) = img_gray.shape #print(height,width) for y in range(height): for x in range(width): if img_gray[y][x] > max_gray_level: max_gray_level = img_gray[y][x] max_gray_level = max_gray_level + 1 #若灰度级数大于gray_level,则将图像的灰度级缩小至gray_level,减小灰度共生矩阵的大小 if max_gray_level > gray_level: for j in range(height): for i in range(width): srcdata[j][ i] = srcdata[j][i] * gray_level / max_gray_level for j in range(height - d_y): for i in range(width - d_x): rows = srcdata[j][i] cols = srcdata[j + d_y][i + d_x] p[rows][cols] += 1.0 for i in range(gray_level): for j in range(gray_level): p[i][j] /= float(height * width) #之前的feature_computer() con = 0.0 eng = 0.0 asm = 0.0 idm = 0.0 for i in range(gray_level): for j in range(gray_level): con += (i - j) * (i - j) * p[i][j] asm += p[i][j] * p[i][j] idm += p[i][j] / (1 + (i - j) * (i - j)) if p[i][j] > 0.0: eng -= p[i][j] * math.log(p[i][j]) self.energy_1.setText(str(asm)) self.entrophy_1.setText(str(eng)) self.contrast_ratio.setText(str(con)) self.inverse_variance.setText(str(idm)) except: QMessageBox.information(self, 'Warning', '提取灰度共生矩阵出错', QMessageBox.Ok) @staticmethod def stumpClassify(dataMatrix, dimen, threshVal, threshIneq): """ 单层决策树分类函数 Parameters: dataMatrix - 数据矩阵 dimen - 第dimen列,也就是第几个特征 threshVal - 阈值 threshIneq - 标志 Returns: retArray - 分类结果 """ retArray = np.ones((np.shape(dataMatrix)[0], 1)) # 初始化retArray为1 if threshIneq == 'lt': retArray[ dataMatrix[:, dimen] <= threshVal] = -1.0 # 如果小于阈值,则赋值为-1 else: retArray[dataMatrix[:, dimen] > threshVal] = -1.0 # 如果大于阈值,则赋值为-1 return retArray @staticmethod def buildStump(dataArr, classLabels, D): """ 找到数据集上最佳的单层决策树 Parameters: dataArr - 数据矩阵 classLabels - 数据标签 D - 样本权重 Returns: bestStump - 最佳单层决策树信息 minError - 最小误差 bestClasEst - 最佳的分类结果 """ dataMatrix = np.mat(dataArr) labelMat = np.mat(classLabels).T m, n = np.shape(dataMatrix) numSteps = 10.0 bestStump = {} bestClasEst = np.mat(np.zeros((m, 1))) minError = float('inf') # 最小误差初始化为正无穷大 for i in range(n): # 遍历所有特征 rangeMin = dataMatrix[:, i].min() rangeMax = dataMatrix[:, i].max() # 找到特征中最小的值和最大值 stepSize = (rangeMax - rangeMin) / numSteps # 计算步长 for j in range(-1, int(numSteps) + 1): for inequal in [ 'lt', 'gt' ]: # 大于和小于的情况,均遍历。lt:less than,gt:greater than threshVal = (rangeMin + float(j) * stepSize) # 计算阈值 predictedVals = FS_window.stumpClassify( dataMatrix, i, threshVal, inequal) # 计算分类结果 errArr = np.mat(np.ones((m, 1))) # 初始化误差矩阵 errArr[predictedVals == labelMat] = 0 # 分类正确的,赋值为0 weightedError = D.T * errArr # 计算误差 # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)) if weightedError < minError: # 找到误差最小的分类方式 minError = weightedError bestClasEst = predictedVals.copy() bestStump['dim'] = i bestStump['thresh'] = threshVal bestStump['ineq'] = inequal return bestStump, minError, bestClasEst # def adaboost_classifier(self): # try: # weakClassArr = [] # m = np.shape(self.dataArr)[0] # D = np.mat(np.ones((m, 1)) / m) # 初始化权重 # aggClassEst = np.mat(np.zeros((m, 1))) # numIt = 40 # for i in range(numIt): # # bestStump, error, classEst = buildStump(self.dataArr, self.LabelArr, D) #构建单层决策树 # # dataMatrix = np.mat(self.dataArr); # labelMat = np.mat(self.LabelArr).T # m, n = np.shape(dataMatrix) # numSteps = 10.0; # bestStump = {}; # bestClasEst = np.mat(np.zeros((m, 1))) # minError = float('inf') # 最小误差初始化为正无穷大 # for i in range(n): # 遍历所有特征 # rangeMin = dataMatrix[:, i].min(); # rangeMax = dataMatrix[:, i].max() # 找到特征中最小的值和最大值 # stepSize = (rangeMax - rangeMin) / numSteps # 计算步长 # for j in range(-1, int(numSteps) + 1): # for inequal in ['lt', 'gt']: # 大于和小于的情况,均遍历。lt:less than,gt:greater than # threshVal = (rangeMin + float(j) * stepSize) # 计算阈值 # # predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)#计算分类结果 # dimen = i # threshIneq = inequal # retArray = np.ones((np.shape(dataMatrix)[0], 1)) # 初始化retArray为1 # if threshIneq == 'lt': # retArray[dataMatrix[:, dimen] <= threshVal] = -1.0 # 如果小于阈值,则赋值为-1 # else: # retArray[dataMatrix[:, dimen] > threshVal] = -1.0 # # predictedVals = retArray # errArr = np.mat(np.ones((m, 1))) # 初始化误差矩阵 # errArr[predictedVals == labelMat] = 0 # 分类正确的,赋值为0 # weightedError = D.T * errArr # 计算误差 # # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)) # if weightedError < minError: # 找到误差最小的分类方式 # minError = weightedError # bestClasEst = predictedVals.copy() # bestStump['dim'] = i # bestStump['thresh'] = threshVal # bestStump['ineq'] = inequal # error = minError # classEst = bestClasEst # alpha = float(0.5 * np.log((1.0 - error) / max(error, 1e-16))) # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0 # bestStump['alpha'] = alpha # 存储弱学习算法权重 # weakClassArr.append(bestStump) # 存储单层决策树 # # print("classEst: ", classEst.T) # expon = np.multiply(-1 * alpha * np.mat(self.LabelArr).T, classEst) # 计算e的指数项 # D = np.multiply(D, np.exp(expon)) # D = D / D.sum() # 根据样本权重公式,更新样本权重 # # 计算AdaBoost误差,当误差为0的时候,退出循环 # aggClassEst += alpha * classEst # 计算类别估计累计值 # # print("aggClassEst: ", aggClassEst.T) # aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(self.LabelArr).T, np.ones((m, 1))) # 计算误差 # errorRate = aggErrors.sum() / m # # print("total error: ", errorRate) # if errorRate == 0.0: break # # # predictions = adaClassify(dataArr, weakClassArr) # datToClass = self.dataArr # classifierArr = self.weakClassArr # dataMatrix = np.mat(datToClass) # m = np.shape(dataMatrix)[0] # aggClassEst = np.mat(np.zeros((m, 1))) # for i in range(len(classifierArr)): # 遍历所有分类器,进行分类 # classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], # classifierArr[i]['ineq']) # aggClassEst += classifierArr[i]['alpha'] * classEst # # print(aggClassEst) # predictions = np.sign(aggClassEst) # # errArr = np.mat(np.ones((len(self.dataArr), 1))) # print('训练集的错误率:%.3f%%' % float( # errArr[predictions != np.mat(self.LabelArr).T].sum() / len(self.dataArr) * 100)) # # predictions = adaClassify(testArr, weakClassArr) # datToClass = self.testArr # classifierArr = self.weakClassArr # dataMatrix = np.mat(datToClass) # m = np.shape(dataMatrix)[0] # aggClassEst = np.mat(np.zeros((m, 1))) # for i in range(len(classifierArr)): # 遍历所有分类器,进行分类 # classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], # classifierArr[i]['ineq']) # aggClassEst += classifierArr[i]['alpha'] * classEst # # print(aggClassEst) # predictions = np.sign(aggClassEst) # # errArr = np.mat(np.ones((len(self.testArr), 1))) # print('测试集的错误率:%.3f%%' % float( # errArr[predictions != np.mat(self.testLabelArr).T].sum() / len(self.testArr) * 100)) # # # except: # QMessageBox.information(self, 'Warning', '构建分类器出错', QMessageBox.Ok) #def adaBoostTrainDS(self): def adaboost_classifier(self): """ 使用AdaBoost算法提升弱分类器性能 Parameters: dataArr - 数据矩阵 classLabels - 数据标签 numIt - 最大迭代次数 Returns: weakClassArr - 训练好的分类器 aggClassEst - 类别估计累计值 """ try: weakClassArr = [] m = np.shape(self.dataArr)[0] D = np.mat(np.ones((m, 1)) / m) # 初始化权重 aggClassEst = np.mat(np.zeros((m, 1))) numIt = 40 for i in range(numIt): bestStump, error, classEst = FS_Window.buildStump( self.dataArr, self.classLabels, D) # 构建单层决策树 # print("D:",D.T) alpha = float(0.5 * np.log( (1.0 - error) / max(error, 1e-16)) ) # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0 bestStump['alpha'] = alpha # 存储弱学习算法权重 weakClassArr.append(bestStump) # 存储单层决策树 # print("classEst: ", classEst.T) expon = np.multiply(-1 * alpha * np.mat(self.classLabels).T, classEst) # 计算e的指数项 D = np.multiply(D, np.exp(expon)) D = D / D.sum() # 根据样本权重公式,更新样本权重 # 计算AdaBoost误差,当误差为0的时候,退出循环 aggClassEst += alpha * classEst # 计算类别估计累计值 # print("aggClassEst: ", aggClassEst.T) aggErrors = np.multiply( np.sign(aggClassEst) != np.mat(self.classLabels).T, np.ones((m, 1))) # 计算误差 errorRate = aggErrors.sum() / m # print("total error: ", errorRate) if errorRate == 0.0: break # 误差为0,退出循环 return weakClassArr, aggClassEst except: QMessageBox.information(self, 'Warning', '构建分类器出错', QMessageBox.Ok)
class DGSPlannerGUI(QtGui.QWidget): def __init__(self, ol=None, parent=None): # pylint: disable=unused-argument,super-on-old-class super(DGSPlannerGUI, self).__init__(parent) # OrientedLattice if ValidateOL(ol): self.ol = ol else: self.ol = mantid.geometry.OrientedLattice() self.masterDict = dict() # holds info about instrument and ranges self.updatedInstrument = False self.updatedOL = False self.wg = None # workspace group self.instrumentWidget = InstrumentSetupWidget.InstrumentSetupWidget(self) self.setLayout(QtGui.QHBoxLayout()) controlLayout = QtGui.QVBoxLayout() controlLayout.addWidget(self.instrumentWidget) self.ublayout = QtGui.QHBoxLayout() self.classic = ClassicUBInputWidget.ClassicUBInputWidget(self.ol) self.ublayout.addWidget(self.classic, alignment=QtCore.Qt.AlignTop, stretch=1) self.matrix = MatrixUBInputWidget.MatrixUBInputWidget(self.ol) self.ublayout.addWidget(self.matrix, alignment=QtCore.Qt.AlignTop, stretch=1) controlLayout.addLayout(self.ublayout) self.dimensionWidget = DimensionSelectorWidget.DimensionSelectorWidget(self) controlLayout.addWidget(self.dimensionWidget) plotControlLayout = QtGui.QGridLayout() self.plotButton = QtGui.QPushButton("Plot", self) self.oplotButton = QtGui.QPushButton("Overplot", self) self.helpButton = QtGui.QPushButton("?", self) self.colorLabel = QtGui.QLabel('Color by angle', self) self.colorButton = QtGui.QCheckBox(self) self.colorButton.toggle() self.aspectLabel = QtGui.QLabel('Aspect ratio 1:1', self) self.aspectButton = QtGui.QCheckBox(self) self.saveButton = QtGui.QPushButton("Save Figure", self) plotControlLayout.addWidget(self.plotButton, 0, 0) plotControlLayout.addWidget(self.oplotButton, 0, 1) plotControlLayout.addWidget(self.colorLabel, 0, 2, QtCore.Qt.AlignRight) plotControlLayout.addWidget(self.colorButton, 0, 3) plotControlLayout.addWidget(self.aspectLabel, 0, 4, QtCore.Qt.AlignRight) plotControlLayout.addWidget(self.aspectButton, 0, 5) plotControlLayout.addWidget(self.helpButton, 0, 6) plotControlLayout.addWidget(self.saveButton, 0, 7) controlLayout.addLayout(plotControlLayout) self.layout().addLayout(controlLayout) # figure self.figure = Figure() self.figure.patch.set_facecolor('white') self.canvas = FigureCanvas(self.figure) self.grid_helper = GridHelperCurveLinear((self.tr, self.inv_tr)) self.trajfig = Subplot(self.figure, 1, 1, 1, grid_helper=self.grid_helper) self.trajfig.hold(True) self.figure.add_subplot(self.trajfig) self.toolbar = CustomNavigationToolbar(self.canvas, self) figureLayout = QtGui.QVBoxLayout() figureLayout.addWidget(self.toolbar,0) figureLayout.addWidget(self.canvas,1) self.layout().addLayout(figureLayout) self.needToClear = False self.saveDir = '' # connections self.matrix.UBmodel.changed.connect(self.updateUB) self.matrix.UBmodel.changed.connect(self.classic.updateOL) self.classic.changed.connect(self.matrix.UBmodel.updateOL) self.classic.changed.connect(self.updateUB) self.instrumentWidget.changed.connect(self.updateParams) self.dimensionWidget.changed.connect(self.updateParams) self.plotButton.clicked.connect(self.updateFigure) self.oplotButton.clicked.connect(self.updateFigure) self.helpButton.clicked.connect(self.help) self.saveButton.clicked.connect(self.save) # force an update of values self.instrumentWidget.updateAll() self.dimensionWidget.updateChanges() # help self.assistantProcess = QtCore.QProcess(self) # pylint: disable=protected-access self.collectionFile = os.path.join(mantid._bindir, '../docs/qthelp/MantidProject.qhc') version = ".".join(mantid.__version__.split(".")[:2]) self.qtUrl = 'qthelp://org.sphinx.mantidproject.' + version + '/doc/interfaces/DGS Planner.html' self.externalUrl = 'http://docs.mantidproject.org/nightly/interfaces/DGS Planner.html' # control for cancel button self.iterations = 0 self.progress_canceled = False # register startup mantid.UsageService.registerFeatureUsage("Interface", "DGSPlanner", False) @QtCore.pyqtSlot(mantid.geometry.OrientedLattice) def updateUB(self, ol): self.ol = ol self.updatedOL = True self.trajfig.clear() @QtCore.pyqtSlot(dict) def updateParams(self, d): if self.sender() is self.instrumentWidget: self.updatedInstrument = True if 'dimBasis' in d and 'dimBasis' in self.masterDict and d['dimBasis'] != self.masterDict['dimBasis']: self.needToClear = True if 'dimIndex' in d and 'dimIndex' in self.masterDict and d['dimIndex'] != self.masterDict['dimIndex']: self.needToClear = True self.masterDict.update(copy.deepcopy(d)) def help(self): try: import pymantidplot pymantidplot.proxies.showCustomInterfaceHelp('DGS Planner') except ImportError: self.assistantProcess.close() self.assistantProcess.waitForFinished() helpapp = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.BinariesPath) + QtCore.QDir.separator() helpapp += 'assistant' args = ['-enableRemoteControl', '-collectionFile', self.collectionFile, '-showUrl', self.qtUrl] if os.path.isfile(helpapp) and os.path.isfile(self.collectionFile): self.assistantProcess.close() self.assistantProcess.waitForFinished() self.assistantProcess.start(helpapp, args) else: mqt.MantidQt.API.MantidDesktopServices.openUrl(QtCore.QUrl(self.externalUrl)) def closeEvent(self, event): self.assistantProcess.close() self.assistantProcess.waitForFinished() event.accept() def _create_goniometer_workspaces(self, gonioAxis0values, gonioAxis1values, gonioAxis2values, progressDialog): groupingStrings = [] i = 0 for g0 in gonioAxis0values: for g1 in gonioAxis1values: for g2 in gonioAxis2values: name = "__temp_instrument" + str(i) i += 1 progressDialog.setValue(i) progressDialog.setLabelText("Creating workspace %d of %d..." % (i, self.iterations)) QtGui.qApp.processEvents() if progressDialog.wasCanceled(): self.progress_canceled = True progressDialog.close() return None groupingStrings.append(name) mantid.simpleapi.CloneWorkspace("__temp_instrument", OutputWorkspace=name) mantid.simpleapi.SetGoniometer(Workspace=name, Axis0=str(g0) + "," + self.masterDict['gonioDirs'][0] + "," + str(self.masterDict['gonioSenses'][0]), Axis1=str(g1) + "," + self.masterDict['gonioDirs'][1] + "," + str(self.masterDict['gonioSenses'][1]), Axis2=str(g2) + "," + self.masterDict['gonioDirs'][2] + "," + str(self.masterDict['gonioSenses'][2])) return groupingStrings # pylint: disable=too-many-locals def updateFigure(self): # pylint: disable=too-many-branches if self.updatedInstrument or self.progress_canceled: self.progress_canceled = False # get goniometer settings first gonioAxis0values = numpy.arange(self.masterDict['gonioMinvals'][0], self.masterDict['gonioMaxvals'][0] + 0.1 * self.masterDict['gonioSteps'][0], self.masterDict['gonioSteps'][0]) gonioAxis1values = numpy.arange(self.masterDict['gonioMinvals'][1], self.masterDict['gonioMaxvals'][1] + 0.1 * self.masterDict['gonioSteps'][1], self.masterDict['gonioSteps'][1]) gonioAxis2values = numpy.arange(self.masterDict['gonioMinvals'][2], self.masterDict['gonioMaxvals'][2] + 0.1 * self.masterDict['gonioSteps'][2], self.masterDict['gonioSteps'][2]) self.iterations = len(gonioAxis0values) * len(gonioAxis1values) * len(gonioAxis2values) if self.iterations > 10: reply = QtGui.QMessageBox.warning(self, 'Goniometer', "More than 10 goniometer settings. This might be long.\n" "Are you sure you want to proceed?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.No: return if self.wg is not None: mantid.simpleapi.DeleteWorkspace(self.wg) mantid.simpleapi.LoadEmptyInstrument( mantid.api.ExperimentInfo.getInstrumentFilename(self.masterDict['instrument']), OutputWorkspace="__temp_instrument") if self.masterDict['instrument'] == 'HYSPEC': mantid.simpleapi.AddSampleLog(Workspace="__temp_instrument", LogName='msd', LogText='1798.5', LogType='Number Series') mantid.simpleapi.AddSampleLog(Workspace="__temp_instrument", LogName='s2', LogText=str(self.masterDict['S2']), LogType='Number Series') mantid.simpleapi.LoadInstrument(Workspace="__temp_instrument", RewriteSpectraMap=True, InstrumentName="HYSPEC") elif self.masterDict['instrument'] == 'EXED': mantid.simpleapi.RotateInstrumentComponent(Workspace="__temp_instrument", ComponentName='Tank', Y=1, Angle=str(self.masterDict['S2']), RelativeRotation=False) # masking if 'maskFilename' in self.masterDict and len(self.masterDict['maskFilename'].strip()) > 0: try: __maskWS = mantid.simpleapi.Load(self.masterDict['maskFilename']) mantid.simpleapi.MaskDetectors(Workspace="__temp_instrument", MaskedWorkspace=__maskWS) except (ValueError, RuntimeError) as e: reply = QtGui.QMessageBox.critical(self, 'Error', "The following error has occured in loading the mask:\n" + str(e) + "\nDo you want to continue without mask?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.No: return if self.masterDict['makeFast']: sp = list(range(mantid.mtd["__temp_instrument"].getNumberHistograms())) tomask = sp[1::4] + sp[2::4] + sp[3::4] mantid.simpleapi.MaskDetectors("__temp_instrument", SpectraList=tomask) progressDialog = QtGui.QProgressDialog(self) progressDialog.setMinimumDuration(0) progressDialog.setCancelButtonText("&Cancel") progressDialog.setRange(0, self.iterations) progressDialog.setWindowTitle("DGSPlanner progress") groupingStrings = self._create_goniometer_workspaces(gonioAxis0values, gonioAxis1values, gonioAxis2values, progressDialog) if groupingStrings is None: return progressDialog.close() mantid.simpleapi.DeleteWorkspace("__temp_instrument") self.wg = mantid.simpleapi.GroupWorkspaces(groupingStrings, OutputWorkspace="__temp_instrument") self.updatedInstrument = False # set the UB if self.updatedOL or not self.wg[0].sample().hasOrientedLattice(): mantid.simpleapi.SetUB(self.wg, UB=self.ol.getUB()) self.updatedOL = False # calculate coverage dimensions = ['Q1', 'Q2', 'Q3', 'DeltaE'] progressDialog = QtGui.QProgressDialog(self) progressDialog.setMinimumDuration(0) progressDialog.setCancelButtonText("&Cancel") progressDialog.setRange(0, self.iterations) progressDialog.setWindowTitle("DGSPlanner progress") for i in range(self.iterations): progressDialog.setValue(i) progressDialog.setLabelText("Calculating orientation %d of %d..." % (i, self.iterations)) QtGui.qApp.processEvents() if progressDialog.wasCanceled(): self.progress_canceled = True progressDialog.close() return __mdws = mantid.simpleapi.CalculateCoverageDGS(self.wg[i], Q1Basis=self.masterDict['dimBasis'][0], Q2Basis=self.masterDict['dimBasis'][1], Q3Basis=self.masterDict['dimBasis'][2], IncidentEnergy=self.masterDict['Ei'], Dimension1=dimensions[self.masterDict['dimIndex'][0]], Dimension1Min=float2Input(self.masterDict['dimMin'][0]), Dimension1Max=float2Input(self.masterDict['dimMax'][0]), Dimension1Step=float2Input(self.masterDict['dimStep'][0]), Dimension2=dimensions[self.masterDict['dimIndex'][1]], Dimension2Min=float2Input(self.masterDict['dimMin'][1]), Dimension2Max=float2Input(self.masterDict['dimMax'][1]), Dimension2Step=float2Input(self.masterDict['dimStep'][1]), Dimension3=dimensions[self.masterDict['dimIndex'][2]], Dimension3Min=float2Input(self.masterDict['dimMin'][2]), Dimension3Max=float2Input(self.masterDict['dimMax'][2]), Dimension4=dimensions[self.masterDict['dimIndex'][3]], Dimension4Min=float2Input(self.masterDict['dimMin'][3]), Dimension4Max=float2Input(self.masterDict['dimMax'][3])) if i == 0: intensity = __mdws.getSignalArray()[:, :, 0, 0] * 1. # to make it writeable else: if self.colorButton.isChecked(): tempintensity = __mdws.getSignalArray()[:, :, 0, 0] intensity[numpy.where(tempintensity > 0)] = i + 1. else: tempintensity = __mdws.getSignalArray()[:, :, 0, 0] intensity[numpy.where(tempintensity > 0)] = 1. progressDialog.close() x = numpy.linspace(__mdws.getDimension(0).getMinimum(), __mdws.getDimension(0).getMaximum(), intensity.shape[0]) y = numpy.linspace(__mdws.getDimension(1).getMinimum(), __mdws.getDimension(1).getMaximum(), intensity.shape[1]) Y, X = numpy.meshgrid(y, x) xx, yy = self.tr(X, Y) Z = numpy.ma.masked_array(intensity, intensity == 0) Z = Z[:-1, :-1] # plotting if self.sender() is self.plotButton or self.needToClear: self.figure.clear() self.trajfig.clear() self.figure.add_subplot(self.trajfig) self.needToClear = False self.trajfig.pcolorfast(xx, yy, Z) if self.aspectButton.isChecked(): self.trajfig.set_aspect(1.) else: self.trajfig.set_aspect('auto') self.trajfig.set_xlabel(self.masterDict['dimNames'][0]) self.trajfig.set_ylabel(self.masterDict['dimNames'][1]) self.trajfig.grid(True) self.canvas.draw() mantid.simpleapi.DeleteWorkspace(__mdws) def save(self): fileName = str(QtGui.QFileDialog.getSaveFileName(self, 'Save Plot', self.saveDir, '*.png')) data = "Instrument " + self.masterDict['instrument'] + '\n' if self.masterDict['instrument'] == 'HYSPEC': data += "S2 = " + str(self.masterDict['S2']) + '\n' data += "Ei = " + str(self.masterDict['Ei']) + ' meV\n' data += "Goniometer values:\n" gonioAxis0values = numpy.arange(self.masterDict['gonioMinvals'][0], self.masterDict['gonioMaxvals'][0] + 0.1 * self.masterDict['gonioSteps'][0], self.masterDict['gonioSteps'][0]) gonioAxis1values = numpy.arange(self.masterDict['gonioMinvals'][1], self.masterDict['gonioMaxvals'][1] + 0.1 * self.masterDict['gonioSteps'][1], self.masterDict['gonioSteps'][1]) gonioAxis2values = numpy.arange(self.masterDict['gonioMinvals'][2], self.masterDict['gonioMaxvals'][2] + 0.1 * self.masterDict['gonioSteps'][2], self.masterDict['gonioSteps'][2]) for g0 in gonioAxis0values: for g1 in gonioAxis1values: for g2 in gonioAxis2values: data += " " + self.masterDict['gonioLabels'][0] + " = " + str(g0) data += " " + self.masterDict['gonioLabels'][1] + " = " + str(g1) data += " " + self.masterDict['gonioLabels'][2] + " = " + str(g2) + '\n' data += "Lattice parameters:\n" data += " a = " + str(self.ol.a()) + " b = " + str(self.ol.b()) + " c = " + str(self.ol.c()) + '\n' data += " alpha = " + str(self.ol.alpha()) + " beta = " + str(self.ol.beta()) + " gamma = " + str( self.ol.gamma()) + '\n' data += "Orientation vectors:\n" data += " u = " + str(self.ol.getuVector()) + '\n' data += " v = " + str(self.ol.getvVector()) + '\n' data += "Integrated " + self.masterDict['dimNames'][2] + " between " + \ str(self.masterDict['dimMin'][2]) + " and " + str(self.masterDict['dimMax'][2]) + '\n' data += "Integrated " + self.masterDict['dimNames'][3] + " between " + \ str(self.masterDict['dimMin'][3]) + " and " + str(self.masterDict['dimMax'][3]) + '\n' info = self.figure.text(0.2, 0, data, verticalalignment='top') self.figure.savefig(fileName, bbox_inches='tight', additional_artists=info) self.saveDir = os.path.dirname(fileName) def tr(self, x, y): x, y = numpy.asarray(x), numpy.asarray(y) # one of the axes is energy if self.masterDict['dimIndex'][0] == 3 or self.masterDict['dimIndex'][1] == 3: return x, y else: h1, k1, l1 = (float(temp) for temp in self.masterDict['dimBasis'][self.masterDict['dimIndex'][0]].split(',')) h2, k2, l2 = (float(temp) for temp in self.masterDict['dimBasis'][self.masterDict['dimIndex'][1]].split(',')) angle = numpy.radians(self.ol.recAngle(h1, k1, l1, h2, k2, l2)) return 1. * x + numpy.cos(angle) * y, numpy.sin(angle) * y def inv_tr(self, x, y): x, y = numpy.asarray(x), numpy.asarray(y) # one of the axes is energy if self.masterDict['dimIndex'][0] == 3 or self.masterDict['dimIndex'][1] == 3: return x, y else: h1, k1, l1 = (float(temp) for temp in self.masterDict['dimBasis'][self.masterDict['dimIndex'][0]].split(',')) h2, k2, l2 = (float(temp) for temp in self.masterDict['dimBasis'][self.masterDict['dimIndex'][1]].split(',')) angle = numpy.radians(self.ol.recAngle(h1, k1, l1, h2, k2, l2)) return 1. * x - y / numpy.tan(angle), y / numpy.sin(angle)
class Interface: def __init__(self): # Valores Iniciales self.gravedad = 9.8 self.velocidad_inicial = 10 self.angulo = np.radians(10) self.x0 = 7 self.y0 = 8 self.z0 = 0 self.window = tk.Tk() self.window.title("Fisica") self.window.minsize(800, 600) self.window.maxsize(1280, 960) self.entrada_posicion_x0 = ttk.Entry() self.entrada_posicion_y0 = ttk.Entry() self.entrada_angulo_inicial = ttk.Entry() self.entrada_aceleracion_inicial = ttk.Entry() self.deslizador_posicion_x0 = ttk.Scale() self.deslizador_posicion_y0 = ttk.Scale() self.deslizador_angulo_inicial = ttk.Scale() self.deslizador_aceleracion_inicial = ttk.Scale() self.pestañas = ttk.Notebook(self.window) self.tab_ideal = ttk.Frame(self.pestañas) self.opciones = ttk.Frame(self.tab_ideal) self.graphics = ttk.LabelFrame(self.tab_ideal, text="Gráfica") self.figura = Figure(figsize=(4, 3), dpi=100) # define la proporcion del gráfico self.ecuacion = np.arange(0, 10, .01) self.figura.add_subplot(111).plot(self.ecuacion, self.ecuacion * self.ecuacion) self.canvas = FigureCanvasTkAgg(self.figura, master=self.graphics) self.canvas.draw() self.canvas = self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # Inicializar los botones de la interfaz self.boton_posicion = ttk.Button( self.opciones, text="Posición", width=10, command=lambda: self.boton_posicionf()) self.boton_velocidad = ttk.Button( self.opciones, text="Velocidad", width=10, command=lambda: self.boton_velocidadf()) self.boton_aceleracion = ttk.Button( self.opciones, text="Aceleración", width=10, command=lambda: self.boton_aceleracionf()) self.boton_alcance_horizontal = ttk.Button( self.opciones, text="Alcance Horizontal", width=10, command=lambda: self.boton_alcance_horizontalf()) self.boton_altura_maxima = ttk.Button( self.opciones, text="Altura Màxima", width=10, command=lambda: self.boton_altura_maximaf()) self.boton_camino_recorrido = ttk.Button( self.opciones, text="Camino Recorrido", width=10, command=lambda: self.boton_camino_recorridof()) self.boton_radio_y_centro_de_curvatura_circulo_obsculador = ttk.Button( self.opciones, text="Radio y Centro de Curvatura y Circulo Obsculador", width=10, command=lambda: self. boton_radio_y_centro_de_curvatura_circulo_obsculadorf) self.boton_aceleracion_normal_y_tangencial = ttk.Button( self.opciones, text="A. normal y tangencial", width=10, command=lambda: self.boton_aceleracion_normal_y_tangencialf()) self.boton_vector_normal = ttk.Button( self.opciones, text="Vector normal", width=10, command=lambda: self.boton_vector_normalf()) #self.boton_circulo_osculador = ttk.Button(self.opciones, text="Circulo Osculador", width=10, #command=lambda: self.boton_circulo_osculadorf()) self.create_widgets() def create_widgets(self): def f_posicion_x0(event): print(posicion_x0.get()) def f_posicion_y0(event): print(posicion_y0.get()) def f_angulo_inicial(event): print(angulo_inicial.get()) def f_Rapidez_inicial(event): print(Rapidez_inicial.get()) # Limpia Entry iniciales, de modo que al hacer click estos se vacian def limpiar_entrada_x0(event): if self.entrada_posicion_x0.get() == "X0": self.entrada_posicion_x0.delete(0, 'end') def update_x0(event): # todo ecuacion que se actualiza automatricamente input_x0 = self.entrada_posicion_x0.get() if input_x0 == '': input_x0 = 0 self.actualizar_grafico(self.ecuacion * float(5), 8, 8, 8) self.actualizar_grafico(self.ecuacion * float(5), 8, 8, 8) def limpiar_entrada_y0(event): if self.entrada_posicion_y0.get() == "Y0": self.entrada_posicion_y0.delete(0, 'end') def limpiar_entrada_angulo(event): if self.entrada_angulo_inicial.get() == "Angulo": self.entrada_angulo_inicial.delete(0, 'end') def limpiar_entrada_Rapidez(event): if self.entrada_Rapidez_inicial.get() == "Rapidez Inicial": self.entrada_Rapidez_inicial.delete(0, 'end') # Variables de los deslizadores posicion_x0 = tk.IntVar() posicion_y0 = tk.IntVar() angulo_inicial = tk.IntVar() Rapidez_inicial = tk.IntVar() self.pestañas.pack(side=tk.TOP, fill=tk.BOTH, expand=True, ipadx=10, ipady=10) tab_balistica = tk.Frame(self.pestañas) tab_seguridad = tk.Frame(self.pestañas) self.pestañas.add(self.tab_ideal, text="Movimiento Ideal", compound=tk.TOP) self.pestañas.add(tab_seguridad, text="Parabola de Seguridad", compound=tk.TOP) self.pestañas.add(tab_balistica, text="Movimiento Balistico", compound=tk.TOP) # tutorial = ttk.LabelFrame(self.window, text="Instrucciones") # tutorial.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=10, pady=10) self.opciones.pack(side=tk.RIGHT, fill=tk.BOTH, expand=False, padx=5, pady=5) self.boton_posicion.pack(side=tk.TOP, padx=10, pady=10) self.boton_velocidad.pack(side=tk.TOP, padx=10, pady=10) self.boton_aceleracion.pack(side=tk.TOP, padx=10, pady=10) self.boton_alcance_horizontal.pack(side=tk.TOP, padx=10, pady=10) self.boton_altura_maxima.pack(side=tk.TOP, padx=10, pady=10) self.boton_camino_recorrido.pack(side=tk.TOP, padx=10, pady=10) self.boton_radio_y_centro_de_curvatura_circulo_obsculador.pack( side=tk.TOP, padx=10, pady=10) self.boton_aceleracion_normal_y_tangencial.pack(side=tk.TOP, padx=10, pady=10) self.boton_vector_normal.pack(side=tk.TOP, padx=10, pady=10) #self.boton_circulo_osculador.pack(side=tk.TOP, padx=10, pady=10) self.graphics.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) separador = ttk.Separator(self.tab_ideal, orient="horizontal") separador.pack(side=tk.TOP, expand=False, fill=tk.X) variables = ttk.LabelFrame(self.tab_ideal, text="Controles") variables.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5, pady=5) # Contenedores de los controles posicion = ttk.Frame(variables) posicion.pack(side=tk.LEFT, expand=True, padx=5, pady=5) Rapidez = ttk.Frame(variables) Rapidez.pack(side=tk.LEFT, expand=True, padx=5, pady=5) angulo = ttk.Frame(variables) angulo.pack(side=tk.LEFT, expand=True, padx=5, pady=5) #todo añadir titulos self.entrada_posicion_x0 = ttk.Entry(posicion, justify=tk.CENTER) self.entrada_posicion_x0.pack(side=tk.TOP, fill=tk.BOTH, expand=True) self.entrada_posicion_x0.insert(tk.END, "0") self.entrada_posicion_x0.bind("<Button-1>", limpiar_entrada_x0) self.entrada_posicion_x0.bind("<Key>", update_x0) self.entrada_posicion_y0 = ttk.Entry(posicion, justify=tk.CENTER) self.entrada_posicion_y0.pack(side=tk.TOP, fill=tk.BOTH, expand=True) self.entrada_posicion_y0.insert(tk.END, "0") self.entrada_posicion_y0.bind("<Button-1>", limpiar_entrada_y0) # todo titulos para rapidez inicial self.entrada_Rapidez_inicial = ttk.Entry(Rapidez, justify=tk.CENTER) self.entrada_Rapidez_inicial.pack(side=tk.TOP, fill=tk.BOTH, expand=True) self.entrada_Rapidez_inicial.insert(tk.END, "Rapidez Inicial") self.entrada_Rapidez_inicial.bind("<Button-1>", limpiar_entrada_Rapidez) # todo titulos para angulo inicial self.entrada_angulo_inicial = ttk.Entry(angulo, justify=tk.CENTER) self.entrada_angulo_inicial.pack(side=tk.TOP, fill=tk.BOTH, expand=True) self.entrada_angulo_inicial.insert(tk.END, "Angulo Inicial") self.entrada_angulo_inicial.bind("<Button-1>", limpiar_entrada_angulo) # Añadir elementos deslizadores para actualizar datos self.deslizador_posicion_x0 = ttk.Scale(posicion, variable=posicion_x0, from_=0, to=100, orient=tk.HORIZONTAL) self.deslizador_posicion_x0.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10) self.deslizador_posicion_x0.set(50) self.deslizador_posicion_x0.bind("<B1-Motion>", f_posicion_x0) self.deslizador_posicion_x0.bind("<ButtonRelease-1>", f_posicion_x0) self.deslizador_posicion_y0 = ttk.Scale(posicion, variable=posicion_y0, from_=0, to=100, orient=tk.HORIZONTAL) self.deslizador_posicion_y0.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10) self.deslizador_posicion_y0.set(50) self.deslizador_posicion_y0.bind("<B1-Motion>", f_posicion_y0) self.deslizador_posicion_y0.bind("<ButtonRelease-1>", f_posicion_y0) self.deslizador_angulo_inicial = ttk.Scale(angulo, variable=angulo_inicial, from_=0, to=90, orient=tk.HORIZONTAL) self.deslizador_angulo_inicial.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10) self.deslizador_angulo_inicial.set(180) self.deslizador_angulo_inicial.bind("<B1-Motion>", f_angulo_inicial) self.deslizador_Rapidez_inicial = ttk.Scale(Rapidez, variable=Rapidez_inicial, from_=0, to=100, orient=tk.HORIZONTAL) self.deslizador_Rapidez_inicial.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10) self.deslizador_Rapidez_inicial.set(50) self.deslizador_Rapidez_inicial.bind("<B1-Motion>", f_Rapidez_inicial) self.deslizador_Rapidez_inicial.bind("<ButtonRelease-1>", f_Rapidez_inicial) #Insercion Grafico en la zona indicada # Todo declarar todos los elementos de la interfaz dentro del __init__ def update_position_value(self): self.entrada_posicion_x0.insert(tk.END, self.entrada_posicion_x0.get()) # Todo declarar todos los elementos de la interfaz dentro del __init__ def update_angle_value(self): self.entrada_posicion_x0.insert(tk.END, self.entrada_posicion_x0.get()) # Todo declarar todos los elementos de la interfaz dentro del __init__ def update_acceleration_value(self): self.entrada_posicion_x0.insert(tk.END, self.entrada_posicion_x0.get()) # Declaracion de botones0 def boton_posicionf(self): alcanze_horizontal = self.x0 + ((self.velocidad_inicial*sin(2*self.angulo))/(2*self.gravedad)) + \ ((self.velocidad_inicial*cos(self.angulo)) / (self.gravedad))*sqrt(((self.velocidad_inicial*sin(self.angulo))**2) + 2*self.y0*self.gravedad) x = linspace(0, alcanze_horizontal, 601) ecuacion_parametrica_x = ( self.x0 + self.velocidad_inicial * cos(self.angulo) * x) ecuacion_parametrica_y = ( self.y0 + self.velocidad_inicial * sin(self.angulo) * x - (self.gravedad / 2) * x**2) self.actualizar_grafico(ecuacion_parametrica_x, ecuacion_parametrica_y) # Metodo para almacenar datos de las entradas de datos def copiar_valores(event): self.tiempo_datos[0] = entrada_tiempo.get() master.destroy() # Metodo para validar la entrada de datos (Solo Numeros por ahora) def check(v, p): if p.isdigit(): return True elif p is "": return True else: return False # Datos Iniciales # inicializa la ventana popup master = tk.Tk() master.title("Posicion") # Crea un frame contenedor para la izquierda y la derecha frame_arriba = ttk.Frame(master) frame_centro = ttk.Frame(master) frame_abajo = ttk.Frame(master) frame_aceptar = ttk.Frame(master) validacion_tiempo = (frame_abajo.register(check), '%v', '%P') #validacion_y = (frame_derecha.register(check), '%v', '%P') frame_arriba.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_centro.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_abajo.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_aceptar.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) # Crea las titulos de la entrada de datos tiempo = ttk.Label(frame_abajo, text="Tiempo: ") aceptar = ttk.Button(frame_aceptar, text="ACEPTAR") tiempo_init = ttk.Label(frame_arriba, text="Intervalo de tiempo") tiempo_init_x = ttk.Entry(frame_arriba, state='readonly', justify='center') tiempo_init_y = ttk.Entry(frame_arriba, state='readonly') tiempo_init.pack(side=tk.TOP) tiempo_init_x.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) tiempo_init_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) tiempo_init_x.configure(state='normal') tiempo_init_x.delete(0, 'end') tiempo_init_x.insert(0, "0") tiempo_init_x.configure(state='readonly') # inicializa el punto de interseccion del eje Y tiempo_init_y.configure(state='normal') tiempo_init_y.delete(0, 'end') tiempo_init_y.insert(0, "0") tiempo_init_y.configure(state='readonly') #Separador de datos separador = ttk.Separator(frame_centro, orient="horizontal") separador.pack(side=tk.TOP, expand=False, fill=tk.X) # Crea formularios para entrada de datos entrada_tiempo = ttk.Entry(frame_abajo, validate="key", validatecommand=validacion_tiempo) #entrada_y = ttk.Entry(frame_derecha, validate="key", validatecommand=validacion_y) tiempo.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) #posicion_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) entrada_tiempo.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) # entrada_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) aceptar.pack(fill=tk.BOTH, expand=1) aceptar.bind("<Button-1>", copiar_valores) def boton_velocidadf(self): import matplotlib.pyplot as plt import math def seno(Grado): # funcion para calcualar el seno de un angulo # transforma el angulo a radianes para la funcion sin return math.sin(math.radians(Grado)) def coseno(Grado): # funcion para calcualar el seno de un angulo # transforma el angulo a radianes para la funcion sin return math.cos(math.radians(Grado)) def Ingreso_De_Datos(): # funcion que recibe y retorna los valores para reemplazar en la ecuacion. V_inicial = int(input("Velocidad inicial: ")) Angulo = int(input("Angulo de inclinación:")) Aceleracion = int(input("Aceleracion: ")) Tiempo = int(input("Tiempo: ")) # retorn de los datos leidos por teclado. return V_inicial, Angulo, Aceleracion, Tiempo def Vector_Velocidad(v0, O, a, t): # funcion que calcula el vector velocidad # como parametro recibe los valores de velocidad,angulo,aceleracion y tiempo. Vt = [] Vx = v0 * (coseno(O)) Vy = v0 * (seno(O)) - a * t # se añaden la velocidad en X e Y al vector Vt. Vt.append(Vx) Vt.append(Vy) return Vt def Grafica_Velocidad(Vt): # funcion para graficar el vector velocidad. plt.plot(Vt, "r-") plt.show() def Mostrar_Vector(Vt): # muestra el vector velocidad por consola. print(Vt[0], ",", Vt[1]) if __name__ == "__main__": V_Inicial, Angulo, Aceleracion, Tiempo = Ingreso_De_Datos() Velocidad = Vector_Velocidad(V_Inicial, Angulo, Aceleracion, Tiempo) Mostrar_Vector(Velocidad) Grafica_Velocidad(Velocidad) pass def boton_aceleracionf(self): #funcion para la obtencion de tiempo impacto final def time_impact(self): t = ((self.velocidad_inicial * sin(self.angulo)) / (2 * self.gravedad)) + ( (1 / self.gravedad) * (sqrt(((self.velocidad_inicial * sin(self.angulo))**2) + (2 * self.y0 * self.gravedad)))) print(t) return t # funcion para el calculo de la coordenada horizontal def cord_x(self, t): x = self.x0 + ((self.velocidad_inicial * cos(self.angulo)) * t) return x # funcion para el calculo de la coordenada vertical def cord_y(self, t): y = self.y0 + (((self.velocidad_inicial * (cos(self.angulo))) * t) - ((self.gravedad / 2) * (t**2))) return y # funcion altura maxima para graficar def altura_max(self): r = self.y0 + (((self.velocidad_inicial * (sin(self.angulo)))**2) / (2 * self.gravedad)) return r # funcion alcance maximo para graficar def alcance_max(self): alc = self.x0 + ((self.velocidad_inicial*sin(2*self.angulo))/(2*self.gravedad)) + \ ((self.velocidad_inicial*cos(self.angulo)) / (self.gravedad))*sqrt(((self.velocidad_inicial*sin(self.angulo))**2) + 2*self.y0*self.gravedad) return alc # generamiento de la grafica def GraficarFuncion(self, entrada_tiempo): # generacion de la grafica del tiempo ingresado time = np.arange(0, entrada_tiempo, 0.01) x = cord_x(self, time) y = cord_y(self, time) # grafica completa del lanzamiento time_complete = np.arange(0, time_impact(self) + 4, 0.01) x2 = cord_x(self, time_complete) y2 = cord_y(self, time_complete) # generacion del punto de posicion a medir x3 = cord_x(self, entrada_tiempo) y3 = cord_y(self, entrada_tiempo) # estetica de la grafica mpl.title("Aceleracion") mpl.xlim(0, alcance_max(self) + self.x0) mpl.ylim(0, altura_max(self) + self.y0) mpl.xlabel("-Distancia-") mpl.ylabel("-Altura-") # generamiento de las curvas mpl.plot(self.x0, self.y0, "k-o") # punto pos inicial mpl.plot(x, y, "y-") # curva del usuario mpl.plot(x2, y2, "k--") # lanzamiento completo mpl.plot(x3, y3, "r-o") # punto del usuario mpl.grid() # cuadriculado # generacion del vector con origen en el punto de posicion mpl.plot(x3, y3 - time_impact(self), "g-o") mpl.show() return 0 # pop up de ingreso de datos def copiar_valores(event): self.tiempo_datos[0] = entrada_tiempo.get() master.destroy() # Metodo para validar la entrada de datos (Solo Numeros por ahora) def check(v, p): if p.isdigit(): return True elif p is "": return True else: return False # Datos Iniciales # inicializa la ventana popup master = tk.Tk() master.title("Posicion") # Crea un frame contenedor para la izquierda y la derecha frame_arriba = ttk.Frame(master) frame_centro = ttk.Frame(master) frame_abajo = ttk.Frame(master) frame_aceptar = ttk.Frame(master) validacion_tiempo = (frame_abajo.register(check), '%v', '%P') # validacion_y = (frame_derecha.register(check), '%v', '%P') frame_arriba.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_centro.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_abajo.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_aceptar.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) # Crea las titulos de la entrada de datos tiempo = ttk.Label(frame_abajo, text="Tiempo: ") tiempo_init = ttk.Label(frame_arriba, text="Intervalo de tiempo") tiempo_init_x = ttk.Entry(frame_arriba, state='readonly', justify='center') tiempo_init_y = ttk.Entry(frame_arriba, state='readonly', justify='center') tiempo_init.pack(side=tk.TOP) tiempo_init_x.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) tiempo_init_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) tiempo_init_x.configure(state='normal') tiempo_init_x.delete(0, 'end') tiempo_init_x.insert(0, "0") tiempo_init_x.configure(state='readonly') # inicializa el punto de interseccion del eje Y tiempo_init_y.configure(state='normal') tiempo_init_y.delete(0, 'end') tiempo_init_y.insert(0, time_impact(self)) tiempo_init_y.configure(state='readonly') # Separador de datos separador = ttk.Separator(frame_centro, orient="horizontal") separador.pack(side=tk.TOP, expand=False, fill=tk.X) # Crea formularios para entrada de datos entrada_tiempo = ttk.Entry(frame_abajo, validate="key", validatecommand=validacion_tiempo) # entrada_y = ttk.Entry(frame_derecha, validate="key", validatecommand=validacion_y) tiempo.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) # posicion_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) entrada_tiempo.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) # entrada_y.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) aceptar = ttk.Button(frame_aceptar, text="ACEPTAR") aceptar.pack(fill=tk.BOTH, expand=1) aceptar.bind("<Button-1>", copiar_valores) #posible desplazamiento con pass def boton_alcance_horizontalf(self): pass def boton_altura_maximaf(self): pass def boton_camino_recorridof(self): pass @property def boton_radio_y_centro_de_curvatura_circulo_obsculadorf(self): def check(v, p): if p.isdigit(): return True elif p is "": return True else: return False def time_impact(self): t = ((self.velocidad_inicial * sin(self.angulo)) / (self.gravedad)) + ( (1 / self.gravedad) * (sqrt(((self.velocidad_inicial * sin(self.angulo))**2) + (2 * self.y0 * self.gravedad)))) return round(t, 2) def validarIntervaloTiempo(valor): return (valor > 0 & valor <= time_impact(self)) """def radioButtons(): print(v.get()) return v.get() """ def copiarTiempo(event): self.tiempo_datos[0] = tiempoUsuarioEntry.get() popup.destroy() # DATOS DE PRUEBA ang = np.pi / 3 # REEMPLAZAR POR self.angulo_inicial ? g = 10 # Constante t = 1 # Este parametro se toma desde la ventana generada v0 = 150 # REEMPLAZAR POR self.velocidad_inicial ? x0 = 10 # ---------^ y0 = 20 # x = 0 # Este parametro se toma desde la ventana generada y = 0 # ---------^ ################## # ECUACIONES curvatura_pos = ( np.abs(-g / (np.power(v0 * np.cos(ang), 2))) / (np.power( 1 + np.power( np.tan(ang) - g / np.power(v0 * np.cos(ang), 2) * (x - x0), 2), 3 / 2))) curvatura_t = (np.abs(-(g) / np.power(v0 * np.cos(ang), 2)) / np.power( 1 + np.power(np.tan(ang) - (g / v0 * np.cos(ang) * t), 2), 3 / 2)) r_curvatura_pos = ((np.power( 1 + np.power( np.tan(ang) - g / (np.power(v0 * np.cos(ang), 2) * (x - x0)), 2), 3 / 2)) / (np.abs(-g / np.power(v0 * np.cos(ang), 2)))) r_curvatura_t = ((np.power( 1 + np.power(np.tan(ang) - g / v0 * np.tan(ang) * t, 2), 3 / 2)) / (np.abs(-g / np.power(v0 * np.cos(ang), 2)))) centro_curvatura_x = x - (( (np.tan(ang) - (g / np.power(v0 * np.cos(ang), 2)) * (x - x0)) * (1 + np.power( np.tan(ang) - (g / np.power(v0 * np.cos(ang) * (x - x0), 2)), 2))) / (-g / np.power(v0 * np.cos(ang), 2))) #centro_curvatura_y= centro_curvatura_xt = x0 + v0 * cos(ang) * t + ( ((1 + tan(ang) - (g / v0 * cos(ang)) * t) * (1 + np.power(tan(ang) - (g / v0 * cos(ang)) * t, 2))) / (g / np.power(v0 * cos(ang), 2))) centro_curvatura_yt = y0 + v0 * sin(ang) * t - (1 + np.power( tan(ang) - (g / v0 * cos(ang)) * t, 2) * np.power(v0 * cos(ang), 2) / g) """ print("Curvatura en tiempo X: "+str(curvatura_t)) print("Curvatura en posicion: "+str(curvatura_pos)) print("Radio en posicion: "+str(r_curvatura_pos)) print("Radio en tiempo X:"+str(r_curvatura_t)) print("Centro de curvatura pos x:" +str(centro_curvatura_x)) print("Centro de curvatura X en T1:" + str(centro_curvatura_xt)) print("Centro de curvatura Y en T1" + str(centro_curvatura_yt)) """ ################## # Crear POPUP NUEVO # popup = tk.Tk() popup.title("Radio y centro de curvatura") frame_top = ttk.Frame(popup) frame_mid = ttk.Frame(popup) frame_bot = ttk.Frame(popup) frame_top.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_mid.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) frame_bot.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=5, pady=5) validacion_tiempo = (frame_bot.register(check), '%v', '%P') intervaloLabel = ttk.Label(frame_top, text="Intervalo de tiempo").pack( side=tk.TOP, expand=True) tiempoInicioEntry = ttk.Entry(frame_top, justify='center') tiempoFinalEntry = ttk.Entry(frame_top, justify='center') tiempoLabel = ttk.Label(frame_bot, text="Tiempo: ").pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) tiempoInicioEntry.insert(0, "0") tiempoInicioEntry.configure(state='readonly') tiempoInicioEntry.pack(side=tk.LEFT, expand=True, padx=5, pady=5) tiempoFinalEntry.insert(0, time_impact(self)) tiempoFinalEntry.configure(state='readonly') tiempoFinalEntry.pack(side=tk.LEFT, expand=True, padx=5, pady=5) tiempoUsuarioEntry = ttk.Entry(frame_bot, validate="key", validatecommand=validacion_tiempo) tiempoUsuarioEntry.pack(side=tk.LEFT, expand=True) botonAceptar = ttk.Button(frame_bot, text="Aceptar") botonAceptar.pack(side=tk.BOTTOM, expand=1, fill=tk.BOTH) botonAceptar.bind("<Button-1>", copiarTiempo) """ ########## RADIO BUTTONS v = tk.IntVar() radioB1 = tk.Radiobutton(popup, text="Tiempo", variable=v, value=1, command=radioButtons()) radioB2 = tk.Radiobutton(popup, text="Posicion", variable=v, value=2, command=radioButtons()) ## PACK RADIOB radioB1.pack(side=tk.TOP, fill=tk.BOTH, expand=False, padx=5 , pady=5) radioB2.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=False, padx=5, pady=5) #tiempo = ttk.Label(frame_top) ######################## """ pass def boton_aceleracion_normal_y_tangencialf(self): pass def boton_vector_normalf(self): Pop_Up = tk.Tk() Pop_Up.title("Rango Tiempo") Pop_Up.minsize(400, 300) L1 = tk.Label(Pop_Up, text="Eliga Tiempo a Evaluar") E1 = tk.Entry(Pop_Up, bd=5) E1.pack() L1.pack() label = tk.Label(Pop_Up) label.pack() button = ttk.Button(Pop_Up, text='Evaluar', width=10, command=Pop_Up.destroy) button.pack(side=tk.BOTTOM) # inicializa la ventana popup tiempofinal = 20 xo = int(self.entrada_posicion_x0.get()) yo = int(self.entrada_posicion_y0.get()) vxo = 15 vyo = 90 angulo_inicial = self.entrada_angulo_inicial.get() mpl.title("Vector Normal") mpl.xlabel("-X-") mpl.ylabel("-Y-") x = np.arange(0, tiempofinal, 0.001) print(E1.get()) x1 = 5 h = math.sin(math.degrees(angulo_inicial)) j = math.cos(math.degrees(angulo_inicial)) print(h) x1 = 2 y = yo + vyo * x + (1 / 2) * -9.8 * x**2 z = xo + vxo * x + (1 / 2) * 0 * x**2 y1 = yo + vyo * x1 + (1 / 2) * -9.8 * x1**2 z1 = xo + vxo * x1 + (1 / 2) * 0 * x1**2 vector_velocidadx = (vxo * x1) vector_velocidady = (vyo * h - (9.8 * x1)) mpl.plot(z, y, "-") mpl.plot(vector_velocidadx + z1, vector_velocidady + y1, "-o") mpl.plot((vector_velocidady + z1), (vector_velocidadx), "-o") mpl.plot(z1, y1, "-o") mpl.show() pass def actualizar_grafico(self, ecuacion_x, ecuacion_y): self.figura.clear() # Refresca el gráfico self.figura.add_subplot(111).plot(ecuacion_x, ecuacion_y, "--") # self.figura.add_subplot(111).plot(x0, y0, 'r.') self.figura.canvas.draw() # # def actualizar_grafico(self): # self.figura.clear() # Refresca el gráfico # s = np.cos(2) # self.figura.add_subplot(111).plot(self.ecuacion, self.ecuacion) # self.figura.canvas.draw() # Lista de almacenado de datos tiempo_datos = [0, 0]
class MyPage(): def __init__(self): self.root = tkinter.Tk() self.root.filename="No file loaded yet" self.root.wm_title("Filter Tester") self.start_value = np.random.randint(0,1000,size=10000) self.file_loaded = False self.fig = Figure(figsize=(5, 4), dpi=100) self.ax = self.fig.add_subplot(111) self.ax.plot(self.start_value) self.ax.title.set_text("No filter used") self.canvas = FigureCanvasTkAgg(self.fig, master=self.root) # A tk.DrawingArea. self.canvas.draw() self.canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) self.toolbar = NavigationToolbar2Tk(self.canvas, self.root) self.toolbar.update() self.canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) self.canvas.mpl_connect("key_press_event", self.on_key_press) self.cnt = 1 self.ax.grid() def on_key_press(self,event): print("you pressed {}".format(event.key)) key_press_handler(event, self.canvas, self.toolbar) def quit(self): self.root.quit() # stops mainloop self.root.destroy() # this is necessary on Windows to prevent # Fatal Python Error: PyEval_RestoreThread: NULL tstate def increase(self): self.cnt += 1 mask = [1]*self.cnt res = np.convolve(self.start_value,mask,"valid") / self.cnt print(res) self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(res) self.ax.title.set_text(str("Filter length: " + str(self.cnt)+ "\nfilename: " + self.root.filename)) if self.file_loaded == True: self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.grid() self.canvas.draw() def decrease(self): if self.cnt == 1: return self.cnt -= 1 mask = [1]*self.cnt res = np.convolve(self.start_value,mask,"valid") / self.cnt print(res) self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(res) self.ax.title.set_text(str("Filter length: " + str(self.cnt)+ "\nfilename: " + self.root.filename)) if self.file_loaded == True: self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.grid() self.canvas.draw() def gaussianFilter(self): start_mask = [1,1] res = [1,1] if self.cnt < 3: tkinter.alert("NO") for i in range(self.cnt-1): res = np.convolve(res,start_mask) print("Mask:",res) mask = res res = res / res.sum() res = np.convolve(self.start_value,res,"valid") / self.cnt self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(res) self.ax.title.set_text(str("Gaussian Filter: " + str(mask)+ "\nfilename: " + self.root.filename)) if self.file_loaded == True: self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.grid() self.canvas.draw() def customSized(self,sv): try: val = int(sv.get()) except Exception as e: print(e) return mask = [1]*val res = np.convolve(self.start_value,mask,"valid") / val print(res) self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(res) self.ax.title.set_text(str("Filter length: " + str(val)+ "\nfilename: " + self.root.filename)) if self.file_loaded == True: self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.grid() self.canvas.draw() self.cnt = val def customFilter(self,sv): try: vals = sv.get().split(",") mask = [float(i) for i in vals] except Exception as e: print(e) return print(mask) res = np.convolve(self.start_value,mask,"valid") print(res) self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(res) self.ax.title.set_text(str("Filter: " + str(mask)+ "\nfilename: " + self.root.filename)) if self.file_loaded == True: self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.grid() self.canvas.draw() def LoadFile(self): self.root.filename = tkinter.filedialog.askopenfilename(initialdir = "/",title = "Select file",filetypes = (("CSV files","*.csv"),("all files","*.*"))) print(self.root.filename) with open(start.root.filename,"r") as f: data = f.readlines() self.lines = [] self.start_value = [] self.xlabels = [] for i in range(2,len(data)): converted_data = data[i].split(",") try: self.start_value.append(float(converted_data[1]) / 10) except Exception as e: continue self.xlabels.append(converted_data[0]) self.xsize = len(self.xlabels) self.lines.append(converted_data) self.fig.clear() self.ax = self.fig.add_subplot(111) self.ax.plot(self.start_value) self.ax.set_xticks(np.arange(0,self.xsize,self.xsize/10)) self.ax.set_xticklabels(self.xlabels,fontsize=12) self.ax.title.set_text(str("Filter length: " + str(1) + "\nfilename: " + self.root.filename)) self.ax.grid() self.canvas.draw() self.file_loaded = True
class TiltDepth(QtWidgets.QDialog): """ This is the primary class for the Tilt Depth. Attributes ---------- parent : parent reference to the parent routine indata : dictionary dictionary of input datasets outdata : dictionary dictionary of output datasets self.mmc : FigureCanvas main canvas containing the image """ def __init__(self, parent=None): super().__init__(parent) self.indata = {} self.outdata = {} self.parent = parent self.units = {} self.X = None self.Y = None self.Z = None self.depths = None self.cbar = cm.jet self.showtext = self.parent.showprocesslog self.x0 = None self.x1 = None self.x2 = None self.y0 = None self.y1 = None self.y2 = None self.figure = Figure() self.mmc = FigureCanvas(self.figure) self.axes = self.figure.add_subplot(111) self.cbox_band1 = QtWidgets.QComboBox() self.cbox_cbar = QtWidgets.QComboBox(self) self.dsb_inc = QtWidgets.QDoubleSpinBox() self.dsb_dec = QtWidgets.QDoubleSpinBox() self.btn_apply = QtWidgets.QPushButton() self.btn_save = QtWidgets.QPushButton() self.pbar = misc.ProgressBar() self.setupui() def setupui(self): """ Setup UI """ helpdocs = menu_default.HelpButton('pygmi.raster.tiltdepth') label2 = QtWidgets.QLabel() labelc = QtWidgets.QLabel() label_inc = QtWidgets.QLabel() label_dec = QtWidgets.QLabel() self.dsb_inc.setMaximum(90.0) self.dsb_inc.setMinimum(-90.0) self.dsb_inc.setValue(-67.) self.dsb_dec.setMaximum(360.0) self.dsb_dec.setMinimum(-360.0) self.dsb_dec.setValue(-17.) vbl_raster = QtWidgets.QVBoxLayout() hbl_all = QtWidgets.QHBoxLayout(self) vbl_right = QtWidgets.QVBoxLayout() mpl_toolbar = NavigationToolbar2QT(self.mmc, self) spacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) tmp = sorted(cm.datad.keys()) self.cbox_cbar.addItem('jet') self.cbox_cbar.addItems(tmp) self.setWindowTitle("Tilt Depth Interpretation") label2.setText('Band to perform Tilt Depth:') labelc.setText('Color Bar:') label_inc.setText("Inclination of Magnetic Field:") label_dec.setText("Declination of Magnetic Field:") self.btn_apply.setText('Calculate Tilt Depth') self.btn_save.setText('Save Depths to Text File') vbl_raster.addWidget(label2) vbl_raster.addWidget(self.cbox_band1) vbl_raster.addWidget(labelc) vbl_raster.addWidget(self.cbox_cbar) vbl_raster.addWidget(label_inc) vbl_raster.addWidget(self.dsb_inc) vbl_raster.addWidget(label_dec) vbl_raster.addWidget(self.dsb_dec) vbl_raster.addWidget(self.btn_apply) vbl_raster.addWidget(self.pbar) vbl_raster.addItem(spacer) vbl_raster.addWidget(self.btn_save) vbl_raster.addWidget(helpdocs) vbl_right.addWidget(self.mmc) vbl_right.addWidget(mpl_toolbar) hbl_all.addLayout(vbl_raster) hbl_all.addLayout(vbl_right) self.cbox_cbar.currentIndexChanged.connect(self.change_cbar) self.btn_apply.clicked.connect(self.change_band1) self.btn_save.clicked.connect(self.save_depths) def save_depths(self): """ Save Depths """ if self.depths is None: return ext = "Text File (*.csv)" filename, _ = QtWidgets.QFileDialog.getSaveFileName( self.parent, 'Save File', '.', ext) if filename == '': return False os.chdir(filename.rpartition('/')[0]) np.savetxt(filename, self.depths, delimiter=',', header='x, y, id, depth') def change_cbar(self): """ Change the color map for the color bar """ zout = self.indata['Raster'][0] txt = str(self.cbox_cbar.currentText()) self.figure.clear() self.axes = self.figure.add_subplot(111) self.axes.contour(self.X, self.Y, self.Z, [0]) self.axes.contour(self.X, self.Y, self.Z, [45], linestyles='dashed') self.axes.contour(self.X, self.Y, self.Z, [-45], linestyles='dashed') cmap = cm.get_cmap(txt) cmap2 = np.array([cmap(i) for i in range(cmap.N)]) low = int(cmap.N * (45 / 180)) high = int(cmap.N * (135 / 180)) cmap2[low:high] = cmap2[int(cmap.N / 2)] cmap3 = cm.colors.ListedColormap(cmap2) ims = self.axes.imshow(self.Z, extent=dataprep.dat_extent(zout), cmap=cmap3) if self.x0 is not None: i = 0 self.axes.plot(self.x1[i], self.y1[i], 'oy') self.axes.plot(self.x0[i], self.y0[i], 'sy') self.axes.plot(self.x2[i], self.y2[i], 'oy') self.figure.colorbar(ims) self.figure.canvas.draw() def change_band1(self): """ Action which occurs when button is pressed. Combo box to change the first band. """ txt = str(self.cbox_band1.currentText()) self.btn_apply.setText('Calculating...') QtWidgets.QApplication.processEvents() self.btn_apply.setEnabled(False) for i in self.indata['Raster']: if i.dataid == txt: self.tiltdepth(i) self.change_cbar() self.btn_apply.setEnabled(True) self.btn_apply.setText('Calculate Tilt Depth') QtWidgets.QApplication.processEvents() def settings(self): """ This is called when the used double clicks the routine from the main PyGMI interface""" if 'Raster' not in self.indata: return self.indata['Raster'] = dataprep.merge(self.indata['Raster']) data = self.indata['Raster'] blist = [] for i in data: blist.append(i.dataid) self.cbox_band1.clear() self.cbox_band1.addItems(blist) self.show() QtWidgets.QApplication.processEvents() return True def tiltdepth(self, data): """ Calculate tilt depth """ self.pbar.setValue(0) self.pbar.setMaximum(4) # RTP inc = self.dsb_inc.value() dec = self.dsb_dec.value() zout = dataprep.rtp(data, inc, dec) # Tilt self.pbar.setValue(1) nr, nc = zout.data.shape dy, dx = np.gradient(zout.data) dxtot = np.sqrt(dx**2 + dy**2) dz = cooper.vertical(zout.data) t1 = np.arctan(dz / dxtot) self.pbar.setValue(2) # A negative number implies we are straddling 0 # Contour tilt x = zout.tlx + np.arange(nc) * zout.xdim + zout.xdim / 2 y = zout.tly - np.arange(nr) * zout.ydim - zout.ydim / 2 X, Y = np.meshgrid(x, y) Z = np.rad2deg(t1) self.X = X self.Y = Y self.Z = Z cnt0 = self.axes.contour(X, Y, Z, [0]) cnt45 = self.axes.contour(X, Y, Z, [45], alpha=0) cntm45 = self.axes.contour(X, Y, Z, [-45], alpha=0) self.pbar.setValue(3) gx0, gy0, cgrad0, cntid0 = vgrad(cnt0) gx45, gy45, _, _ = vgrad(cnt45) gxm45, gym45, _, _ = vgrad(cntm45) g0 = np.transpose([gx0, gy0]) self.pbar.setValue(4) dmin1 = [] dmin2 = [] for i, j in self.pbar.iter(g0): dmin1.append(distpc(gx45, gy45, i, j, 0)) dmin2.append(distpc(gxm45, gym45, i, j, 0)) dx1 = gx45[dmin1] - gx0 dy1 = gy45[dmin1] - gy0 dx2 = gxm45[dmin2] - gx0 dy2 = gym45[dmin2] - gy0 grad = np.arctan2(dy1, dx1) * 180 / pi grad[grad > 90] -= 180 grad[grad < -90] += 180 gtmp1 = np.abs(90 - np.abs(grad - cgrad0)) grad = np.arctan2(dy2, dx2) * 180 / pi grad[grad > 90] -= 180 grad[grad < -90] += 180 gtmp2 = np.abs(90 - np.abs(grad - cgrad0)) gtmp = np.logical_and(gtmp1 <= 10, gtmp2 <= 10) gx0 = gx0[gtmp] gy0 = gy0[gtmp] cntid0 = cntid0[gtmp] dx1 = dx1[gtmp] dy1 = dy1[gtmp] dx2 = dx2[gtmp] dy2 = dy2[gtmp] dist1 = np.sqrt(dx1**2 + dy1**2) dist2 = np.sqrt(dx2**2 + dy2**2) dist = np.min([dist1, dist2], 0) self.x0 = gx0 self.x1 = dx1 + gx0 self.x2 = dx2 + gx0 self.y0 = gy0 self.y1 = dy1 + gy0 self.y2 = dy2 + gy0 self.depths = np.transpose([gx0, gy0, cntid0.astype(int), dist])
class streamPick(QtGui.QMainWindow): def __init__(self, stream=None, parent=None): # Initialising QtGui qApp = QtGui.QApplication(sys.argv) self.KeepGoing=False #new value to allow loop in Detex applications to net when false # Init vars if stream is None: msg = 'Define stream = obspy.core.Stream()' raise ValueError(msg) self.st = stream.copy() self._picks = [] self.savefile = None self.onset_types = ['emergent', 'impulsive', 'questionable'] # Load filters from pickle try: self.bpfilter = pickle.load(open('.pick_filters', 'r')) except: self.bpfilter = [] # Internal variables # Gui vars self._shortcuts = {'st_next': 'c', 'st_previous': 'x', 'filter_apply': 'f', 'pick_p': 'q', 'pick_p_end':'a', 'pick_s': 'w', 'pick_s_end':'s', 'pick_custom': 't', 'pick_remove': 'r', 'gain_up':'1', 'gain_down':'2', 'str_next':'v' } self._plt_drag = None self._current_filter = None # Init stations self._initStations() # defines list self._stations self._stationCycle = cycle(self._stations) self._streamStation(self._stationCycle.next()) # Init QtGui QtGui.QMainWindow.__init__(self) self.setupUI() # exec QtApp qApp.exec_() def setupUI(self): ''' Setup the UI ''' self.main_widget = QtGui.QWidget(self) # Init parts of the UI self._initMenu() self._createStatusBar() self._initPlots() self._wadatiPlt = None # Define layout l = QtGui.QVBoxLayout(self.main_widget) l.addLayout(self.btnbar) l.addWidget(self.canvas) self.setCentralWidget(self.main_widget) self.setGeometry(300, 300, 1200, 800) self.setWindowTitle('obspy.core.Stream-Picker') self.show() def _initPlots(self): self.fig = Figure(facecolor='.86', dpi=72, frameon=True) # Change facecolor self.canvas = FigureCanvas(self.fig) self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus) # Draw the matplotlib figure self._drawFig() # Connect the events self.fig.canvas.mpl_connect('scroll_event', self._pltOnScroll) self.fig.canvas.mpl_connect('motion_notify_event', self._pltOnDrag) self.fig.canvas.mpl_connect('button_release_event', self._pltOnButtonRelease) self.fig.canvas.mpl_connect('button_press_event', self._pltOnButtonPress) def _initMenu(self): # Next and Prev Button nxt = QtGui.QPushButton('NextSta >>', shortcut=self._shortcuts['st_next']) nxt.clicked.connect(self._pltNextStation) nxt.setToolTip('shortcut <b>c</d>') nxt.setMaximumWidth(150) prv = QtGui.QPushButton('<< Prev', shortcut=self._shortcuts['st_previous']) prv.clicked.connect(self._pltPrevStation) prv.setToolTip('shortcut <b>x</d>') prv.setMaximumWidth(150) # Stations drop-down self.stcb = QtGui.QComboBox(self) for st in self._stations: self.stcb.addItem(st) self.stcb.activated.connect(self._pltStation) self.stcb.setMaximumWidth(100) self.stcb.setMinimumWidth(80) # Filter buttons self.fltrbtn = QtGui.QPushButton('Filter Trace', shortcut=self._shortcuts['filter_apply']) self.fltrbtn.setToolTip('shortcut <b>f</b>') self.fltrbtn.setCheckable(True) #self.fltrbtn.setAutoFillBackground(True) #self.fltrbtn.setStyleSheet(QtCore.QString( #'QPushButton:checked {background-color: lightgreen;}')) self.fltrbtn.clicked.connect(self._appFilter) self.fltrcb = QtGui.QComboBox(self) self.fltrcb.activated.connect(self._changeFilter) self.fltrcb.setMaximumWidth(170) self.fltrcb.setMinimumWidth(150) self._updateFilterCB() # fill QComboBox # edit/delete filer buttons fltredit = QtGui.QPushButton('Edit') fltredit.resize(fltredit.sizeHint()) fltredit.clicked.connect(self._editFilter) fltrdel = QtGui.QPushButton('Delete') fltrdel.resize(fltrdel.sizeHint()) fltrdel.clicked.connect(self._deleteFilter) nxtstr = QtGui.QPushButton('NextStr >>',shortcut=self._shortcuts['str_next']) nxtstr.clicked.connect(self._pltNextStream) nxtstr.setToolTip('shortcut <b>v</d>') nxtstr.setMaximumWidth(150) btnstyle = QtGui.QFrame(fltredit) btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain) btnstyle = QtGui.QFrame(fltrdel) btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain) # onset type _radbtn = [] for _o in self.onset_types: _radbtn.append(QtGui.QRadioButton(str(_o[0].upper()))) _radbtn[-1].setToolTip('Onset ' + _o) _radbtn[-1].clicked.connect(self._drawPicks) if _o == 'impulsive': _radbtn[-1].setChecked(True) self.onsetGrp = QtGui.QButtonGroup() self.onsetGrp.setExclusive(True) onsetbtns = QtGui.QHBoxLayout() for _i, _btn in enumerate(_radbtn): self.onsetGrp.addButton(_btn, _i) onsetbtns.addWidget(_btn) # Arrange buttons vline = QtGui.QFrame() vline.setFrameStyle(QtGui.QFrame.VLine | QtGui.QFrame.Raised) self.btnbar = QtGui.QHBoxLayout() self.btnbar.addWidget(prv) self.btnbar.addWidget(nxt) self.btnbar.addWidget(nxtstr) self.btnbar.addWidget(QtGui.QLabel('Station')) self.btnbar.addWidget(self.stcb) ## self.btnbar.addWidget(vline) self.btnbar.addWidget(self.fltrbtn) self.btnbar.addWidget(self.fltrcb) self.btnbar.addWidget(fltredit) self.btnbar.addWidget(fltrdel) ## self.btnbar.addWidget(vline) self.btnbar.addWidget(QtGui.QLabel('Pick Onset: ')) self.btnbar.addLayout(onsetbtns) self.btnbar.addStretch(3) # Menubar menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'), 'Save', self._saveCatalog) fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'), 'Save as QuakeML File', self._saveCatalogDlg) fileMenu.addAction(QtGui.QIcon().fromTheme('document-open'), 'Load QuakeML File', self._openCatalogDlg) fileMenu.addSeparator() fileMenu.addAction('Save Plot', self._savePlotDlg) fileMenu.addSeparator() fileMenu.addAction(QtGui.QIcon().fromTheme('application-exit'), 'Exit', self._hardExit) #windowMenu = menubar.addMenu('&Windows') #windowMenu.addAction('Wadati Diagram', self._opnWadatiPlot) aboutMenu = menubar.addMenu('&About') aboutMenu.addAction(QtGui.QIcon().fromTheme('info'), 'Info', self._infoDlg) def _hardExit(self): self.close() def _drawFig(self): ''' Draws all matplotlib figures ''' num_plots = len(self._current_st) self.fig.clear() self._appFilter(draw=False) for _i, tr in enumerate(self._current_st): ax = self.fig.add_subplot(num_plots, 1, _i+1) ax.plot(tr.data, 'k') ax.axhline(0, color='k', alpha=.05) ax.set_xlim([0, tr.data.size]) ax.text(.925, .9, self._current_st[_i].stats.channel, transform=ax.transAxes, va='top', ma='left') ax.channel = tr.stats.channel if _i == 0: ax.set_xlabel('Seconds') # plot picks self._drawPicks(draw=False) self.fig.suptitle('%s - %s - %s' % (self._current_st[-1].stats.network, self._current_st[-1].stats.station, self._current_st[-1].stats.starttime.isoformat()), x=.2) self._updateSB() self._canvasDraw() def _initStations(self): ''' Creates a list holding unique station names ''' self._stations = [] for _tr in self.st: if _tr.stats.station not in self._stations: self._stations.append(_tr.stats.station) self._stations.sort() def _getPhases(self): ''' Creates a list holding unique phase names ''' phases = [] for _pick in self._picks: if _pick.phase_hint not in phases: phases.append(_pick.phase_hint) return phases def _streamStation(self, station): ''' Copies the current stream object from self.st through obspy.stream.select(station=) ''' if station not in self._stations: return self._current_st = self.st.select(station=station).copy() self._current_stname = station self._current_network = self._current_st[0].stats.network # Sort and detrend streams self._current_st.sort(['channel']) self._current_st.detrend('linear') def _setPick(self, xdata, phase, channel, polarity='undecideable'): ''' Write obspy.core.event.Pick into self._picks list ''' picktime = self._current_st[0].stats.starttime +\ (xdata * self._current_st[0].stats.delta) this_pick = event.Pick() overwrite = True # Overwrite existing phase's picktime for _pick in self._getPicks(): if _pick.phase_hint == phase and\ _pick.waveform_id.channel_code == channel: this_pick = _pick overwrite = False break creation_info = event.CreationInfo( author='ObsPy.Stream.pick()', creation_time=UTCDateTime()) # Create new event.Pick() this_pick.time = picktime this_pick.phase_hint = phase this_pick.waveform_id = event.WaveformStreamID( network_code=self._current_st[0].stats.network, station_code=self._current_st[0].stats.station, location_code=self._current_st[0].stats.location, channel_code=channel) this_pick.evaluation_mode = 'manual' this_pick.creation_info = creation_info this_pick.onset = self.onset_types[self.onsetGrp.checkedId()] this_pick.evaluation_status = 'preliminary' this_pick.polarity = polarity #if self._current_filter is not None: # this_pick.comments.append(event.Comment( # text=str(self.bpfilter[self.fltrcb.currentIndex()]))) if overwrite: self._picks.append(this_pick) def _delPicks(self, network, station, channel): ''' Deletes pick from catalog ''' for _i, _pick in enumerate(self._picks): if _pick.waveform_id.network_code == network\ and _pick.waveform_id.station_code == station\ and _pick.waveform_id.channel_code == channel: self._picks.remove(_pick) def _getPicks(self): ''' Create a list of picks for the current plot ''' this_st_picks = [] for _i, pick in enumerate(self._picks): if pick.waveform_id.station_code == self._current_stname and\ self._current_st[0].stats.starttime <\ pick.time < self._current_st[0].stats.endtime: this_st_picks.append(_i) return [self._picks[i] for i in this_st_picks] def _getPickXPosition(self, picks): ''' Convert picktimes into relative positions along x-axis ''' xpicks = [] for _pick in picks: xpicks.append((_pick.time-self._current_st[0].stats.starttime) / self._current_st[0].stats.delta) return np.array(xpicks) def _drawPicks(self, draw=True): ''' Draw picklines onto axes ''' picks = self._getPicks() xpicks = self._getPickXPosition(picks) for _ax in self.fig.get_axes(): lines = [] labels = [] transOffset = offset_copy(_ax.transData, fig=self.fig, x=5, y=0, units='points') for _i, _xpick in enumerate(xpicks): if picks[_i].phase_hint == 'S': color = 'r' elif picks[_i].phase_hint == 'P': color = 'g' else: color = 'b' if _ax.channel != picks[_i].waveform_id.channel_code: alpha = .1 else: alpha = .8 lines.append(matplotlib.lines.Line2D([_xpick, _xpick], [_ax.get_ylim()[0]*.9, _ax.get_ylim()[1]*.8], color=color, alpha=alpha)) lines[-1].obspy_pick = picks[_i] labels.append(matplotlib.text.Text(_xpick, _ax.get_ylim()[0]*.8, text=picks[_i].phase_hint, color=color, size=10, alpha=alpha, transform=transOffset)) # delete all artists del _ax.artists[0:] # add updated objects for line in lines: _ax.add_artist(line) for label in labels: _ax.add_artist(label) if draw: self._canvasDraw() # Plot Controls def _pltOnScroll(self, event): ''' Scrolls/Redraws the plots along x axis ''' if event.inaxes is None: return if event.key == 'control': axes = [event.inaxes] else: axes = self.fig.get_axes() for _ax in axes: left = _ax.get_xlim()[0] right = _ax.get_xlim()[1] extent = right - left dzoom = .2 * extent aspect_left = (event.xdata - _ax.get_xlim()[0]) / extent aspect_right = (_ax.get_xlim()[1] - event.xdata) / extent if event.button == 'up': left += dzoom * aspect_left right -= dzoom * aspect_right elif event.button == 'down': left -= dzoom * aspect_left right += dzoom * aspect_right else: return _ax.set_xlim([left, right]) self._canvasDraw() def _pltOnDrag(self, event): ''' Drags/Redraws the plot upon drag ''' if event.inaxes is None: return if event.key == 'control': axes = [event.inaxes] else: axes = self.fig.get_axes() if event.button == 2: if self._plt_drag is None: self._plt_drag = event.xdata return for _ax in axes: _ax.set_xlim([_ax.get_xlim()[0] + (self._plt_drag - event.xdata), _ax.get_xlim()[1] + (self._plt_drag - event.xdata)]) else: return self._canvasDraw() def _pltOnButtonRelease(self, event): ''' On Button Release Reset drag variable ''' self._plt_drag = None def _pltOnButtonPress(self, event): ''' This Function is evoked when the user picks ''' if event.key is not None: event.key = event.key.lower() if event.inaxes is None: return channel = event.inaxes.channel tr_amp = event.inaxes.lines[0].get_ydata()[int(event.xdata)+3] -\ event.inaxes.lines[0].get_ydata()[int(event.xdata)] if tr_amp < 0: polarity = 'negative' elif tr_amp > 0: polarity = 'positive' else: polarity = 'undecideable' if event.key == self._shortcuts['pick_p'] and event.button == 1: self._setPick(event.xdata, phase='P', channel=channel, polarity=polarity) elif event.key == self._shortcuts['pick_p_end'] and event.button == 1: self._setPick(event.xdata, phase='Pend', channel=channel, polarity=polarity) elif event.key== self._shortcuts['str_next']: self._pltNextStream() elif event.key == self._shortcuts['pick_s_end'] and event.button == 1: self._setPick(event.xdata, phase='Send', channel=channel, polarity=polarity) elif event.key == self._shortcuts['pick_s'] and event.button == 1: self._setPick(event.xdata, phase='S', channel=channel, polarity=polarity) elif event.key == self._shortcuts['pick_custom'] and event.button == 1: text, ok = QtGui.QInputDialog.getItem(self, 'Custom Phase', 'Enter phase name:', self._getPhases()) if ok: self._setPick(event.xdata, phase=text, channel=channel, polarity=polarity) elif event.key == self._shortcuts['pick_remove']: self._delPicks(network=self._current_network, station=self._current_stname, channel=channel) elif event.key == self._shortcuts['gain_up'] or self._shortcuts['gain_down']: self._adjustGain(event) else: return self._updateSB() self._drawPicks() def _adjustGain(self,event): ''' Allows the gain to be changed on plot ''' if event.key is not None: event.key = event.key.lower() if event.inaxes is None: return if event.inaxes is None: return if event.key == self._shortcuts['gain_up'] or self._shortcuts['gain_down']: axes = [event.inaxes] else: axes = self.fig.get_axes() for _ax in axes: up = _ax.get_ylim()[1] down = _ax.get_ylim()[0] extent = up - down dzoom = .2 * extent aspect_up = (event.ydata - _ax.get_ylim()[0]) / extent aspect_down = (_ax.get_ylim()[1] - event.ydata) / extent if event.key == self._shortcuts['gain_up']: down += dzoom * aspect_up up -= dzoom * aspect_down elif event.key == self._shortcuts['gain_down']: down -= dzoom * aspect_up up += dzoom * aspect_down else: return _ax.set_ylim([down, up]) self._canvasDraw() def _pltNextStation(self): ''' Plot next station ''' self._streamStation(self._stationCycle.next()) self._drawFig() def _pltNextStream(self): ''' Plot next Stream, used primarily in Detex loops when streamPick is called to know to exit loop or go to next stream ''' self.KeepGoing=True self.close() #self._streamStation(self._stationCycle.next()) #self._drawFig() def _pltPrevStation(self): ''' Plot previous station ''' for _i in range(len(self._stations)-1): prevStation = self._stationCycle.next() self._streamStation(prevStation) self._drawFig() def _pltStation(self): ''' Plot station from DropDown Menu ''' _i = self.stcb.currentIndex() while self._stationCycle.next() != self._stations[_i]: pass self._streamStation(self._stations[_i]) self._drawFig() # Filter functions def _appFilter(self, button=True, draw=True): ''' Apply bandpass filter ''' _i = self.fltrcb.currentIndex() self._streamStation(self._current_stname) if self.fltrbtn.isChecked() is False: self._current_filter = None else: self._current_st.filter('bandpass', freqmin=self.bpfilter[_i]['freqmin'], freqmax=self.bpfilter[_i]['freqmax'], corners=self.bpfilter[_i]['corners'], zerophase=True) self._current_filter = _i for _i, _ax in enumerate(self.fig.get_axes()): if len(_ax.lines) == 0: continue _ax.lines[0].set_ydata(self._current_st[_i].data) _ax.relim() _ax.autoscale_view() if draw is True: self._drawPicks(draw=False) self._canvasDraw() self._updateSB() def _newFilter(self): ''' Create new filter ''' newFilter = self.defFilter(self) if newFilter.exec_(): self.bpfilter.append(newFilter.getValues()) self._updateFilterCB() self.fltrcb.setCurrentIndex(len(self.bpfilter)-1) self._appFilter() def _editFilter(self): ''' Edit existing filter ''' _i = self.fltrcb.currentIndex() this_filter = self.bpfilter[_i] editFilter = self.defFilter(self, this_filter) if editFilter.exec_(): self.bpfilter[_i] = editFilter.getValues() self._updateFilterCB() self.fltrcb.setCurrentIndex(_i) self._appFilter() def _deleteFilter(self): ''' Delete filter ''' _i = self.fltrcb.currentIndex() self.fltrbtn.setChecked(False) self.bpfilter.pop(_i) self._updateFilterCB() self._appFilter() def _changeFilter(self, index): ''' Evoke this is filter in drop-down is changed ''' if index == len(self.bpfilter): return self._newFilter() else: return self._appFilter() def _updateFilterCB(self): ''' Update the filter QComboBox ''' self.fltrcb.clear() self.fltrcb.setCurrentIndex(-1) for _i, _f in enumerate(self.bpfilter): self.fltrcb.addItem('%s [%.2f - %.2f Hz]' % (_f['name'], _f['freqmin'], _f['freqmax'])) self.fltrcb.addItem('Create new Filter...') # Status bar functions def _createStatusBar(self): ''' Creates the status bar ''' sb = QtGui.QStatusBar() sb.setFixedHeight(18) self.setStatusBar(sb) self.statusBar().showMessage('Ready') def _updateSB(self, statustext=None): ''' Updates the statusbar text ''' if statustext is None: self.stcb.setCurrentIndex( self._stations.index(self._current_stname)) msg = 'Station %i/%i - %i Picks' % ( self._stations.index(self._current_stname)+1, len(self._stations), len(self._getPicks())) if self._current_filter is not None: msg += ' - Bandpass %s [%.2f - %.2f Hz]' % ( self.bpfilter[self._current_filter]['name'], self.bpfilter[self._current_filter]['freqmin'], self.bpfilter[self._current_filter]['freqmax']) else: msg += ' - Raw Data' self.statusBar().showMessage(msg) def _openCatalogDlg(self): filename = QtGui.QFileDialog.getOpenFileName(self, 'Load QuakeML Picks', os.getcwd(), 'QuakeML Format (*.xml)', '20') if filename: self._openCatalog(str(filename)) self.savefile = str(filename) def _openCatalog(self, filename): ''' Open existing QuakeML catalog ''' try: print 'Opening QuakeML Catalog %s' % filename cat = event.readEvents(filename) self._picks = cat[0].picks self._drawPicks() except: msg = 'Could not open QuakeML file %s' % (filename) raise IOError(msg) def _saveCatalogDlg(self): ''' Save catalog through QtDialog ''' self.savefile = QtGui.QFileDialog.getSaveFileName(self, 'Save QuakeML Picks', os.getcwd(), 'QuakeML Format (*.xml)') if not self.savefile: self.savefile = None return self.savefile = str(self.savefile) if os.path.splitext(self.savefile)[1].lower() != '.xml': self.savefile += '.xml' self._saveCatalog() def _saveCatalog(self, filename=None): ''' Saves the catalog to filename ''' if self.savefile is None and filename is None: return self._saveCatalogDlg() if filename is not None: savefile = filename else: savefile = self.savefile cat = event.Catalog() cat.events.append(event.Event(picks=self._picks)) #cat.write(savefile, format='QUAKEML') #print 'Picks saved as %s' % savefile def _savePlotDlg(self): ''' Save Plot Image Qt Dialog and Matplotlib wrapper ''' filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Plot', os.getcwd(), 'Image Format (*.png *.pdf *.ps *.svg *.eps)') if not filename: return filename = str(filename) format = os.path.splitext(filename)[1][1:].lower() if format not in ['png', 'pdf', 'ps', 'svg', 'eps']: format = 'png' filename += '.' + format self.fig.savefig(filename=filename, format=format, dpi=72) def getPicks(self): return self._picks def _opnWadatiPlot(self): self._wadatiPlt = QtGui.NewWindow() self._wadatiPlt.show() def _infoDlg(self): msg = """ <h3><b>obspy.core.stream-Picker</b></h3> <br><br> <div> StreamPick is a lightweight seismological wave time picker for <code>obspy.core.Stream()</code> objects. It further utilises the <code>obspy.core.event</code> class to store picks in the QuakeML format. </div> <h4>Controls:</h4> <blockquote> <table> <tr> <td width=20><b>%s</b></td><td>Next station</td> </tr> <tr> <td width=20><b>%s</b></td><td>Previous station</td> </tr> <tr> <td width=20><b>%s</b></td><td>Toggle filter</td> </tr> <tr> <td width=20><b>%s</b></td> <td>Set P-Phase pick at mouse position</td> </tr> <tr> <td width=20><b>%s</b></td> <td>Set S-Phase pick at mouse position</td> </tr> <tr> <td width=20><b>%s</b></td> <td>Set custom phase pick at mouse position</td> </tr> <tr> <td width=20><b>%s</b></td> <td>Remove last pick in trace</td> </tr> </table> </blockquote> <h4>Plot Controls:</h4> <blockquote> Use mouse wheel to zoom in- and out. Middle mouse button moves plot along x-axis.<br> Hit <b>Ctrl</b> to manipulate a single plot. <br> </blockquote> <div> Programm stores filter parameters in <code>.pick_filter</code> and a backup of recent picks in <code>.picks-obspy.xml.bak</code>.<br><br> See <a href=http://www.github.org/miili/StreamPick> http://www.github.org/miili/StreamPick</a> and <a href=http://www.obspy.org>http://www.obspy.org</a> for further documentation. </div> """ % ( self._shortcuts['st_next'], self._shortcuts['st_previous'], self._shortcuts['filter_apply'], self._shortcuts['pick_p'], self._shortcuts['pick_s'], self._shortcuts['pick_custom'], self._shortcuts['pick_remove'], ) QtGui.QMessageBox.about(self, 'About', msg) def _canvasDraw(self): ''' Redraws the canvas and re-sets mouse focus ''' for _i, _ax in enumerate(self.fig.get_axes()): _ax.set_xticklabels(_ax.get_xticks() * self._current_st[_i].stats.delta) self.fig.canvas.draw() self.canvas.setFocus() def closeEvent(self, evnt): ''' This function is called upon closing the QtGui ''' # Save Picks #pickle.dump(self.bpfilter, open('.pick_filters', 'w')) # Save Catalog if len(self._picks) > 0: self._saveCatalog('.picks-obspy.xml.bak') # if self.savefile is None and len(self._picks) > 0: # ask = QtGui.QMessageBox.question(self, 'Save Picks?', # 'Do you want to save your picks?', # QtGui.QMessageBox.Save | # QtGui.QMessageBox.Discard | # QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save) # if ask == QtGui.QMessageBox.Save: # self._saveCatalog() # elif ask == QtGui.QMessageBox.Cancel: # evnt.ignore() # print self._picks # Filter Dialog class defFilter(QtGui.QDialog): def __init__(self, parent=None, filtervalues=None): ''' Bandpass filter dialog... Qt layout and stuff ''' QtGui.QDialog.__init__(self, parent) self.setWindowTitle('Create new Bandpass-Filter') # Frequency QDoubleSpinBoxes self.frqmin = QtGui.QDoubleSpinBox(decimals=2, maximum=100, minimum=0.01, singleStep=0.1, value=0.1) self.frqmax = QtGui.QDoubleSpinBox(decimals=2, maximum=100, minimum=0.01, singleStep=0.1, value=10.0) # Radio buttons for corners _corners = [2, 4, 8] _radbtn = [] for _c in _corners: _radbtn.append(QtGui.QRadioButton(str(_c))) if _c == 4: _radbtn[-1].setChecked(True) self.corner = QtGui.QButtonGroup() self.corner.setExclusive(True) radiogrp = QtGui.QHBoxLayout() for _i, _r in enumerate(_radbtn): self.corner.addButton(_r, _corners[_i]) radiogrp.addWidget(_radbtn[_i]) # Filter name self.fltname = QtGui.QLineEdit('Filter Name') self.fltname.selectAll() # Make Layout grid = QtGui.QGridLayout() grid.addWidget(QtGui.QLabel('Filter Name'), 0, 0) grid.addWidget(self.fltname, 0, 1) grid.addWidget(QtGui.QLabel('Min. Frequency'), 1, 0) grid.addWidget(self.frqmin, 1, 1) grid.addWidget(QtGui.QLabel('Max. Frequency'), 2, 0) grid.addWidget(self.frqmax, 2, 1) grid.addWidget(QtGui.QLabel('Corners'), 3, 0) grid.addLayout(radiogrp, 3, 1) grid.setVerticalSpacing(10) btnbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) btnbox.accepted.connect(self.accept) btnbox.rejected.connect(self.reject) layout = QtGui.QVBoxLayout() layout.addWidget(QtGui.QLabel('Define a minimum and maximum' + ' frequency\nfor the bandpass filter.\nFunction utilises ' + 'obspy.signal.filter (zerophase=True).\n')) layout.addLayout(grid) layout.addWidget(btnbox) if filtervalues is not None: self.fltname.setText(filtervalues['name']) self.frqmin.setValue(filtervalues['freqmin']) self.frqmax.setValue(filtervalues['freqmax']) self.corner.button(filtervalues['corners']).setChecked(True) self.setLayout(layout) self.setSizeGripEnabled(False) def getValues(self): ''' Return filter dialogs values as a dictionary ''' return dict(name=str(self.fltname.text()), freqmin=float(self.frqmin.cleanText()), freqmax=float(self.frqmax.cleanText()), corners=int(int(self.corner.checkedId())))
class GraphCanvas(FigureCanvas): """Creates the visual representation of the graph and allows it to be displayed in a Qt window. """ def __init__(self, parent=None, width=5, height=4, dpi=100): #The figure and axes that will be shown in the GUI self.fig = Figure(figsize=(width, height), dpi=dpi) # creates the initial figure needed by matplotlib self.axes = self.fig.add_subplot(111) # adds the sub_plot that items will be added to self.axes.axis('off') # do not show the axes self.axes.hold(False) # allows the graph to be displayed #initialize the figure and set the parent FigureCanvas.__init__(self, self.fig) # initializes the parent class from matplotlib to work with Qt self.setParent(parent) # set as parent #allow for changing sizes FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # allows the Figure to be resized FigureCanvas.updateGeometry(self) # update the gemoetry to reflect the changes above #create a network graph and labels self.graph = graph.Graph() # creates the graph that all nodes and links will be added to self.setLayout = lambda g: nx.spring_layout(g) # anonymous function to set the layout of the graph when it displays self.pos = self.setLayout(self.graph) # set the layout of the graph #images for nodes self.routerImg = '../img/router.png' # path to image of a router (unused) #create a stack of old graphs for undo redo max size of 10 self.undoStack = [] # stack that will hold the state for undos self.redoStack = [] # stack that will hold the state for redos def clearScreen(self): """clear the UI screen and all data in the graph""" self.fig.clear() # clear the figure self.axes = self.fig.add_subplot(111) # readd the subplot self.axes.axis('off') # create same settings as __init__ self.axes.hold(False) self.draw() # draw the balnk subplot self.graph = graph.Graph() # create a new graph self.pos = self.setLayout(self.graph) # set the layout def clearAll(self): """clears the screen and stacks for undo and redo""" self.clearScreen() self.clearStacks() #redraw the graph and update the figure def redrawGraph(self): """redraw the graph to the UI""" self.pos = self.setLayout(self.graph) # set the graph layout (labels, linkLabels) = self.graph.getLabels() nx.draw(self.graph, self.pos, ax = self.axes, labels = labels, node_color = "w", node_shape = "s", alpha = 0.75) # draw the graph to the screen # draw the edge labels nx.draw_networkx_edge_labels(self.graph, self.pos, edge_labels = linkLabels, ax = self.axes, label_pos = 0.5) self.draw() # draw the figure to the screen #add a node to the graph def addNode(self, node): """add a node to the graph and display it on the UI""" self.clearRedo() # clear the redo stack self.pushToUndo() # push the state to the undo stack self.graph.addNode(node) # add the node to the graph self.redrawGraph() # redraw the graph to the screen def removeNode(self, nodeName): """remove a node from the graph and display on the UI""" self.clearRedo() self.pushToUndo() self.graph.removeNode(nodeName) # remove the node self.redrawGraph() #add an edge to the graph def addLink(self, link): """add an edge to the graph and display on the UI""" self.clearRedo() self.pushToUndo() self.graph.addLink(link) # add the edge to the graph self.redrawGraph() def removeLink(self, linkName): """remove an edge from the graph and display on the UI""" self.clearRedo() self.pushToUndo() self.graph.removeLink(linkName) # remove the edge self.redrawGraph() #dialog to add a node to the graph def getNewNode(self): """creates a graphical dialog to add a node to the graph""" node, ok = dialogs.AddNode.getDataDialog() # calls the add node dialog from dialogs if ok: self.addNode(node) # adds the new node if ok is hit on the dialog #dialog to remove a node from the graph def getRemoveNode(self): """creates a graphical dialog to remove a node from the graph""" currNodes = self.graph.nodes() # gets the current nodes nodeName, ok = dialogs.RemoveNode.getDataDialog(currNodes) if ok: self.removeNode(nodeName) # removes the selected node def displayNode(self): """creates a graphical dialog to display a nodes information which will be shown in a seperate dialog""" currNodes = self.graph.nodes() nodeName, ok = dialogs.DisplayNode.getDataDialog(currNodes) if ok: node = self.graph.getNode(nodeName) # displays the selected nodes information in a message box message = QtGui.QMessageBox.information(self, "View Node", "Name: {0}\nStorage: {1}".format(node.getName(), node.getStorage())) #dailog to add an edge to the graph def getNewLink(self): """creates a graphical dialog to create a new edge and ensures that the edge is between two compatible nodes""" currNodes = self.graph.nodes(data = True) if len(currNodes) < 2: # ensures that 2 or more nodes are present in order ot make an edge message = QtGui.QMessageBox.warning(self, "Black Hat Risk", "Not enough nodes to create an edge!") return link, ok = dialogs.AddLink.getDataDialog(currNodes) if ok: (n1, n2) = link.getNodes() proto = link.getProtocol() if self.checkLinkCompat(n1, n2, proto): # checks compatability of the nodes and protocol and adds the edge if possible self.addLink(link) else: message = QtGui.QMessageBox.warning(self, "Black Hat Risk", "Incompatible Link between storage devices!") #dialog to remove an edge from the graph def getRemoveLink(self): """creates a graphical dialog to remove an edge from the graph""" currEdges = self.graph.edges(data = True) # gets the current edges and their data linkName, ok = dialogs.RemoveLink.getDataDialog(currEdges) if ok: self.removeLink(linkName) # removes the edge def displayLink(self): """creates a graphical dialog to select an edge and display its information""" currEdges = self.graph.edges(data = True) link, ok = dialogs.DisplayLink.getDataDialog(currEdges) if ok: # gets the user selected edge (node1, node2) = link.getNodes() nodeName1 = node1.getName() nodeName2 = node2.getName() protocol = link.getProtocol() risk = link.getRisk() # display the data for the edge in a message box message = QtGui.QMessageBox.information(self, "View Edge", "Name: {0}\nNode 1: {1}\nNode 2: {2}\nProtocol: {3}\nRisk: {4}".format(link.getName(), nodeName1, nodeName2, protocol, risk)) # All methods to allow undo and redo functionality # def pushToUndo(self): """gets the current state of the graph and pushes it to the undo stack""" # gets a deep copy of the state due to object mutability data = deepcopy(self.graph) if len(self.undoStack) == 10: # only allows stack to grow to 10 states self.undoStack = self.undoStack[1:].append(data) # push the state to the stack else: self.undoStack.append(data) def pushToRedo(self): """gets teh current state of the graph and push it to the redo stack""" data = deepcopy(self.graph) if len(self.redoStack) == 10: # redo stack can only grow to 10 states self.redoStack = self.redoStack[1:].append(data) else: self.redoStack.append(data) def clearRedo(self): """clears the redo stack and pushes the items to the undo stack""" for item in self.redoStack: self.undoStack.append(item) # push items to undo stack self.redoStack = [] def clearStacks(self): """clears teh undo and redo stacks""" self.undoStack = [] self.redoStack = [] def undo(self): """undo to the previous state""" if not (self.undoStack == []): # check to ensure undo is not empty self.pushToRedo() # push the current state to redo self.graph = self.undoStack.pop() # get the previous state from undo self.redrawGraph() # redraw the graph to the previous state else: self.clearScreen() # clear the screen if undo stack is empty def redo(self): """redo to the state before the last undo""" if not (self.redoStack == []): # ensure redo is not empty self.pushToUndo() # push the current state to undo self.graph = self.redoStack.pop() # get the previous data from redo self.redrawGraph() else: self.clearScreen() def checkLinkCompat(self, node1, node2, proto): """checks to ensure the protocol is compatible for use between the two nodes""" stores = [node1.getStorage(), node2.getStorage()] # create a list of the storage devices for the two nodes # follow the logic to ensure that the protocol and nodes storage devices are compatibile if stores[0] == "Paper" and stores[1] == "Paper": if proto == "Sneakernet": return True return False elif "Paper" in stores and "Hard Drive" in stores: if proto == "IO": return True return False elif "Paper" in stores and "Phone" in stores: if proto == "IO": return True return False elif "Hard Drive" in stores and "Phone" in stores: if proto in ["IO", "Bluetooth", "Sharedrive", "Instant Communication", "Nearfield"]: return True return False elif "Hard Drive" in stores and "Removeable Media" in stores: if proto in ["IO", "Bluetooth", "Nearfield"]: return True return False elif stores[0] == "Hard Drive" and stores[1] == "Hard Drive": if proto in ["IO", "Bluetooth", "Sharedrive", "Instant Communication", "Nearfield", "Email"]: return True return False elif "Phone" in stores and "Removeable Media" in stores: if proto in ["IO", "Bluetooth", "Nearfield"]: return True return False elif stores[0] == "Phone" and stores[1] == "Phone": if proto in ["IO", "Bluetooth", "Sharedrive", "Instant Communication", "Nearfield", "GSM", "Email" ]: return True return False elif stores[0] == "Removeable Media" and stores[1] == "Removeable Media": if proto in ["IO", "Bluetooth", "Sharedrive", "Instant Communication", "Nearfield", "GSM", "Email"]: return True return False else: return False
class TelemetryWindow(wx.Frame): def __init__(self, parent): self.telemetry = None self.accel = deque(maxlen=3) self.rpm = deque(maxlen=100) self.line = None wx.Frame.__init__(self, parent, title="FBR-PC Telemetry Viewer", size=(640, 480), style = wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.MINIMIZE_BOX | wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLIP_CHILDREN | wx.MAXIMIZE ) panel = wx.Panel(self, -1) top_sizer = wx.BoxSizer(wx.VERTICAL) # Data Screen data_sizer = wx.BoxSizer(wx.HORIZONTAL) # Figures on LHS numbers_sizer = wx.FlexGridSizer(0, 2, 3, 3) numbers_sizer.AddGrowableCol(1) label = wx.StaticText(panel, label="Battery Voltage"); self.voltage = wx.TextCtrl(panel, style=wx.TE_READONLY); numbers_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) numbers_sizer.Add(self.voltage, flag=wx.EXPAND) label = wx.StaticText(panel, label="Coolant Temp"); self.coolant_temp = wx.TextCtrl(panel, style=wx.TE_READONLY); numbers_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) numbers_sizer.Add(self.coolant_temp, flag=wx.EXPAND) label = wx.StaticText(panel, label="Oil Temp"); self.oil_temp = wx.TextCtrl(panel, style=wx.TE_READONLY); numbers_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) numbers_sizer.Add(self.oil_temp, flag=wx.EXPAND) label = wx.StaticText(panel, label="Manifold Pressure"); self.manifold_pres = wx.TextCtrl(panel, style=wx.TE_READONLY); numbers_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) numbers_sizer.Add(self.manifold_pres, flag=wx.EXPAND) label = wx.StaticText(panel, label="X-acceleration"); self.accel_x = wx.TextCtrl(panel, style=wx.TE_READONLY); numbers_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) numbers_sizer.Add(self.accel_x, flag=wx.EXPAND) data_sizer.Add(numbers_sizer, proportion=0.5, flag=wx.EXPAND, border=3) # Graphs on RHS graph_sizer = wx.GridSizer(0, 1, 3, 3) #graph_sizer = wx.GridSizer(0, 1, 3, 3) self.revs_figure = Figure(None, None) self.revs_canvas = FigureCanvasWxAgg(panel, -1, self.revs_figure) self.g_figure = Figure(None, None) self.g_canvas = FigureCanvasWxAgg(panel, -1, self.g_figure) graph_sizer.Add(self.revs_canvas, flag=wx.EXPAND | wx.CENTER)#, flag=wx.EXPAND) graph_sizer.Add(self.g_canvas, flag=wx.EXPAND | wx.CENTER) data_sizer.Add(graph_sizer, proportion=1, flag=wx.EXPAND, border=3) top_sizer.Add(data_sizer, proportion=1, flag=wx.EXPAND) # Bottom Controls control_sizer = wx.BoxSizer(wx.HORIZONTAL) btnStart = wx.Button(panel, label="Start") btnStop = wx.Button(panel, label="Stop") control_sizer.Add(btnStart, flag=wx.ALL, border=3) control_sizer.Add(btnStop, flag=wx.ALL, border=3) top_sizer.Add(control_sizer) self.revs_canvas.Bind(wx.EVT_IDLE, self.update_revs) self.g_canvas.Bind(wx.EVT_IDLE, self.update_g) btnStart.Bind(wx.EVT_BUTTON, self.btnStart_Click) btnStop.Bind(wx.EVT_BUTTON, self.btnStop_Click) panel.SetSizer(top_sizer) def update_revs(self, event=None): self.revs_figure.clear() plot = self.revs_figure.add_subplot(111) plot.plot(self.rpm) self.revs_canvas.draw() def update_g(self, event=None): self.g_figure.clear() ax = self.g_figure.add_axes([0.1, 0.1, 0.8, 0.8,], polar=True) r = [np.linalg.norm(x) for x in self.accel] theta = [np.arctan2(x[1], x[0]) for x in self.accel] ax.plot(theta, r, color='#cc0000', lw=5) #ax.plot(np.linspace(-np.pi, np.pi), np.ones(50)) ax.set_rmax(5.0) self.g_canvas.draw() def process_message(self, message): self.telemetry = message; self.accel.append(np.array([self.telemetry.accel_x, self.telemetry.accel_y])) self.rpm.append(self.telemetry.rpm) self.voltage.SetValue("{:3.1f} V".format(self.telemetry.voltage)) self.coolant_temp.SetValue("{:3.1f} C".format(self.telemetry.coolant_temp)) self.oil_temp.SetValue("{:3.1f} C".format(self.telemetry.oil_temp)) self.manifold_pres.SetValue("{:3.1f} MPa".format(self.telemetry.manifold_pres)) self.accel_x.SetValue("{:3.1f} g".format(self.telemetry.accel_x)) #print message def update_data(self, event=None): self.show_samples(self.live_buffer, self.live_buffer.maxlen) def show_samples(self, samples, width): if self.line is None or len(samples) < width: plot = self.figure.add_subplot(111) plot.clear() plot.set_xlim(-width, 0) plot.set_ylim(0, 1024) plot.yaxis.tick_right() plot.set_yticks(range(0, 1025, 256)) line, = plot.plot(range(-len(samples), 0), samples) if len(samples) == width: self.line = line else: self.line = None else: self.line.set_ydata(samples) self.canvas.draw() def btnStart_Click(self, event=None): pass def btnStop_Click(self, event=None): pass
class _AbstractMplCanvas(ABC): def __init__(self, width, height, dpi): """Initialize the MplCanvas.""" from matplotlib import rc_context from matplotlib.figure import Figure # prefer constrained layout here but live with tight_layout otherwise context = nullcontext self._extra_events = ('resize',) try: context = rc_context({'figure.constrained_layout.use': True}) self._extra_events = () except KeyError: pass with context: self.fig = Figure(figsize=(width, height), dpi=dpi) self.axes = self.fig.add_subplot(111) self.axes.set(xlabel='Time (sec)', ylabel='Activation (AU)') self.manager = None def _connect(self): for event in ('button_press', 'motion_notify') + self._extra_events: self.canvas.mpl_connect( event + '_event', getattr(self, 'on_' + event)) def plot(self, x, y, label, **kwargs): """Plot a curve.""" line, = self.axes.plot( x, y, label=label, **kwargs) self.update_plot() return line def plot_time_line(self, x, label, **kwargs): """Plot the vertical line.""" line = self.axes.axvline(x, label=label, **kwargs) self.update_plot() return line def update_plot(self): """Update the plot.""" with warnings.catch_warnings(record=True): warnings.filterwarnings('ignore', 'constrained_layout') self.canvas.draw() def set_color(self, bg_color, fg_color): """Set the widget colors.""" self.axes.set_facecolor(bg_color) self.axes.xaxis.label.set_color(fg_color) self.axes.yaxis.label.set_color(fg_color) self.axes.spines['top'].set_color(fg_color) self.axes.spines['bottom'].set_color(fg_color) self.axes.spines['left'].set_color(fg_color) self.axes.spines['right'].set_color(fg_color) self.axes.tick_params(axis='x', colors=fg_color) self.axes.tick_params(axis='y', colors=fg_color) self.fig.patch.set_facecolor(bg_color) def show(self): """Show the canvas.""" if self.manager is None: self.canvas.show() else: self.manager.show() def close(self): """Close the canvas.""" self.canvas.close() def clear(self): """Clear internal variables.""" self.close() self.axes.clear() self.fig.clear() self.canvas = None self.manager = None def on_resize(self, event): """Handle resize events.""" tight_layout(fig=self.axes.figure)
class AppForm(QtGui.QMainWindow): def __init__(self, parent=None, specterCenter=0, columnNumber=0, windowLength=0): QtGui.QMainWindow.__init__(self, parent) #self.x, self.y = self.get_data() self.create_main_frame() self.specter = [] self.currentSpecter = 0 self.abelData = [] self.specterCenter = specterCenter self.columnNumber = columnNumber self.windowLength = windowLength exitAction = QtGui.QAction(QtGui.QIcon('icons/svg/power.svg'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(QtGui.qApp.quit) openAction = QtGui.QAction(QtGui.QIcon('icons/svg/folder-open.svg'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open file sequence') openAction.triggered.connect(self.loadSpecterFromFiles) #plotAction = QtGui.QAction(QtGui.QIcon('icons/svg/chart-line-outline.svg'), '&Plot', self) #plotAction.setShortcut('Ctrl+P') #plotAction.setStatusTip('Plot') #plotAction.triggered.connect(self.on_draw) nextSpecterAction = QtGui.QAction( QtGui.QIcon('icons/svg/chevron-right-outline.svg'), '&Next specter', self) nextSpecterAction.setStatusTip('Next specter') nextSpecterAction.triggered.connect(self.nextSpecter) self.currentSpecterInput = QtGui.QLabel() #self.currentSpecterInput.setMaxLength(150) #self.currentSpecterInput.setValidator(QtGui.QIntValidator()) self.currentSpecterInput.setFixedWidth(500) self.totalSpecterLabel = QtGui.QLabel() self.totalSpecterLabel.setFixedWidth(40) prevSpecterAction = QtGui.QAction( QtGui.QIcon('icons/svg/chevron-left-outline.svg'), '&Next specter', self) prevSpecterAction.setStatusTip('Prev specter') prevSpecterAction.triggered.connect(self.prevSpecter) self.statusBar().showMessage('Ready') self.setWindowTitle('Abel transform and temperature calculation') menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(openAction) #fileMenu.addAction(plotAction) fileMenu.addAction(exitAction) self.toolbar = self.addToolBar('Main') self.toolbar.addAction(openAction) self.toolbar.addAction(prevSpecterAction) self.toolbar.addAction(nextSpecterAction) self.toolbar.addWidget(self.currentSpecterInput) self.toolbar.addWidget(self.totalSpecterLabel) #self.toolbar.addAction(plotAction) #self.toolbar.addAction(exitAction) def create_main_frame(self): self.main_frame = QtGui.QWidget() self.fig = Figure((10.0, 8.0), dpi=72) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) #self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) self.canvas.mpl_connect('key_press_event', self.on_key_press) self.canvas.mpl_connect('motion_notify_event', self.mouse_moved) self.table = QtGui.QTableWidget() self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels( ['L1', "L2", "LNIST", "Aki", "Ek", "g"]) header = self.table.horizontalHeader() header.setResizeMode(QtGui.QHeaderView.Stretch) self.table.itemChanged.connect(self.setLine) self.buttonAddLine = QtGui.QPushButton("Add a line") self.buttonAddLine.clicked.connect(self.addLine) self.buttonComputeTemp = QtGui.QPushButton("Compute temperature") self.buttonComputeTemp.clicked.connect(self.computeTemp) self.lines = [] vbox = QtGui.QGridLayout() vbox.addWidget(self.table, 0, 0, 1, 1) vbox.addWidget(self.buttonAddLine, 1, 0, 1, 1) vbox.addWidget(self.buttonComputeTemp, 2, 0, 1, 1) vbox.addWidget(self.canvas, 0, 1, 1, 4) # the matplotlib canvas vbox.addWidget(self.mpl_toolbar, 1, 1, 1, 4) vbox.setColumnStretch(1, 5) self.main_frame.setLayout(vbox) self.setCentralWidget(self.main_frame) def on_draw(self): self.fig.clear() gs = gridspec.GridSpec(2, 2, width_ratios=[5, 1], height_ratios=[4, 1], wspace=0.12, hspace=0.12, left=0.05, bottom=0.05, right=0.95, top=0.95) self.axes1 = self.fig.add_subplot(gs[0]) self.axes2 = self.fig.add_subplot(gs[1]) self.axes3 = self.fig.add_subplot(gs[2]) self.drawSpecter() self.drawPlots() def drawSpecter(self): abelData = self.abelData[self.currentSpecter] self.axes1.imshow(np.transpose(abelData), interpolation='nearest', aspect='auto') self.axes11 = self.axes1.twiny() self.axes11.set_xticklabels( self.specter[self.currentSpecter].wavelength) majorLocator = FixedLocator(5) #majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(5) #self.axes11.get_xaxis().set_major_locator(majorLocator) #self.axes11.get_xaxis().set_major_formatter(majorFormatter) self.canvas.draw() def drawPlots(self, x=0, y=0): abelData = self.abelData[self.currentSpecter] vertPixels = len(abelData[x]) self.axes2.cla() self.axes2.set_ylim([vertPixels, 0]) self.axes2.grid() self.axes2.plot(abelData[x], np.arange(0, vertPixels, 1)) transp = np.transpose(abelData)[y] self.axes3.cla() self.axes3.set_xlim([0, len(transp)]) self.axes3.grid() self.axes3.plot(transp) for line in self.lines: self.axes3.axvline(x=int(line[0]), color='r', linestyle='-') self.axes3.axvline(x=int(line[1]), color='r', linestyle='-') self.canvas.draw() def on_key_press(self, event): print('you pressed', event.key) def mouse_moved(self, mouse_event): if mouse_event.inaxes: x, y = int(round(mouse_event.xdata)), int(round(mouse_event.ydata)) self.drawPlots(x, y) def loadSpecterFromFiles(self): self.dirPath = QtGui.QFileDialog.getExistingDirectory( self.main_frame, "Open Directory", "D:") fileList = glob.glob(self.dirPath + '\*.asc') for fileName in fileList: self.specter.append( Specter(np.loadtxt(fileName), fileName, self.specterCenter, self.windowLength)) if len(self.specter) > 0: self.currentSpecter = 0 self.updateSpecterInput() for specNum in range(0, len(self.specter)): self.statusBar().showMessage('Busy...') self.computeAbelTransform(specNum) self.statusBar().showMessage('Ready') self.on_draw() def nextSpecter(self): if self.currentSpecter < (len(self.specter) - 1): self.currentSpecter += 1 self.updateSpecterInput() self.on_draw() def prevSpecter(self): if self.currentSpecter > 1: self.currentSpecter -= 1 self.updateSpecterInput() self.on_draw() def updateSpecterInput(self): self.currentSpecterInput.setText( str(self.currentSpecter + 1) + ' / ' + str(len(self.specter)) + ' (' + self.specter[self.currentSpecter].name + ')') def computeAbelTransform(self, specterNum): abelData = [] for column in self.specter[specterNum].dataCombinedHalf: abelData.append(Abel.transform(column)) self.abelData.append(np.array(abelData)) def addLine(self): #self.lines.append((0,0,0,0,0,0)) #test case self.lines.append((244, 265, 250, 10, 3000, 2)) self.lines.append((305, 343, 325, 10, 2000, 2)) self.updateTable() def setLine(self, item): lineNum = item.row() self.lines[lineNum] = (int(self.table.item(lineNum, 0).text()), int(self.table.item(lineNum, 1).text()), float(self.table.item(lineNum, 2).text()), float(self.table.item(lineNum, 3).text()), float(self.table.item(lineNum, 4).text()), float(self.table.item(lineNum, 5).text())) def computeTemp(self): abelData = self.abelData[self.currentSpecter] Tempereture.compute(abelData, self.lines) def updateTable(self): self.table.setRowCount(0) for line in self.lines: currentRowCount = self.table.rowCount() self.table.insertRow(currentRowCount) for col, value in enumerate(line): self.table.setItem(currentRowCount, col, QtGui.QTableWidgetItem(str(value))) def saveDataToFile(self, data, fileName): np.savetxt(fileName, data, fmt='%10.5f')
class PickApex3D(QtWidgets.QMainWindow, Ui_PickApex3D): def __init__(self): super().__init__() # Set up the user interface from Designer. self.setupUi(self) self.currentSeries = 1 # Set sensible initial values in the UI. # These have to be localized, so we must set them here. self.setInitialUIvalues() # Setup and connect the canvas from matplotlib self.canvas = self.makeFigureCanvas(self.display_frame) # Setup the connections self.setInputValidation() self.makeConnections() self.statusbar.showMessage('Ready') # Set up the matplotlib canvas in the display_frame widget def makeFigureCanvas(self, frame): self.fig = Figure((10.0, 8.0), dpi=50) canvas = FigureCanvas(self.fig) canvas.setParent(frame) canvas.setFocus() self.mpl_toolbar = NavigationToolbar(canvas, frame) vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(self.mpl_toolbar) frame.setLayout(vbox) return canvas def setInputValidation(self): ispositivedouble = QtGui.QDoubleValidator() isdouble = QtGui.QDoubleValidator() ispositivedouble.setBottom(0) ispositiveint = QtGui.QIntValidator() ispositiveint.setBottom(0) # self.NeutralMass.setValidator(ispositivedouble) # self.MassAccuracy.setValidator(ispositivedouble) self.MinCS.setValidator(ispositiveint) self.MaxCS.setValidator(ispositiveint) # self.Calibration_a.setValidator(isdouble) # self.Calibration_b.setValidator(isdouble) # self.Calibration_X.setValidator(isdouble) # self.TransferParam.setValidator(ispositivedouble) # self.PusherDelay.setValidator(ispositivedouble) # self.Gas_mass.setValidator(ispositivedouble) def setInitialUIvalues(self): self.NeutralMass.setText(lstr(22870)) self.MassAccuracy.setText(lstr(200)) self.MinCS.setText(lstr(1)) self.MaxCS.setText(lstr(50)) self.Calibration_a.setText(lstr(231.7)) self.Calibration_b.setText(lstr(118.7)) self.Calibration_X.setText(lstr(0.6262)) self.TransferParam.setText(lstr(1.41)) self.PusherDelay.setText(lstr(110)) self.Gas_mass.setText(lstr(28)) print(lstr(255.3)) # Connections go here def makeConnections(self): self.actionLoad_Data_File.triggered.connect(self.openandPlot) self.actionSave_processed.triggered.connect(self.storeData) self.actionQuit.triggered.connect(self.close) self.actionNext_series.triggered.connect(self.nextSeries) self.actionPrevious_series.triggered.connect(self.prevSeries) self.canvas.mpl_connect('key_press_event', self.on_key_press) # Functions for connectSlotsByName() called by Ui from pyuic5 @QtCore.pyqtSlot(int) def on_selectSeries_valueChanged(self, i): """Catches a change in the selectSeries spin box. Args: i : new value for the series """ self.updateSeries(i) # Most function actions go here. def on_key_press(self, event): # implement the default mpl key press events described at # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts key_press_handler(event, self.canvas, self.mpl_toolbar) def openandPlot(self): # All values should be set before loading a data file. Check if it is the case. try: params = self.validate_param() except ValueError: self.statusbar.showMessage('Invalid value for parameters.') raise self.statusbar.showMessage('Opening file') csv_file_list = QtWidgets.QFileDialog.getOpenFileName( self, 'Open file', '/home', '*.csv') if len(csv_file_list) > 2: # Output a warning that we will not handle more than one file. self.statusbar.showMessage('Only opening the first file.') csv_file = csv_file_list[0] if csv_file == '': self.statusbar.showMessage('Ready') return True self.data = CCS_Data() try: self.data.read(csv_file) except: self.statusbar.showMessage('Error reading file: ' + csv_file) return True try: self.data.process(params) except KeyError: self.statusbar.showMessage('Error processing file: ' + csv_file) raise if self.data.num_points() == 0: self.statusbar.showMessage('No matching data points found in:' + csv_file) return True self.fig.clear() self.plotLayers = [0] self.currentSeries = 1 self.ax = self.fig.add_subplot(111) self.data.plot(self.ax) print(locale.getlocale(category=locale.LC_NUMERIC)) print("3" + locale.localeconv()['decimal_point']) self.fig.canvas.mpl_connect('pick_event', self.onpick) print(locale.getlocale(category=locale.LC_NUMERIC)) print("4" + locale.localeconv()['decimal_point']) self.canvas.draw() print(locale.getlocale(category=locale.LC_NUMERIC)) print("5" + locale.localeconv()['decimal_point']) # Make the selectSeries spinBox active and set its initial value as its limits to # sensible values. self.selectSeries.setEnabled(True) self.selectSeries.setMinimum(1) self.selectSeries.setMaximum(1) self.selectSeries.setValue(1) # Initialize the output values for the series. print(locale.getlocale(category=locale.LC_NUMERIC)) print(locale.localeconv()['decimal_point']) self.updateSeriesTable() def storeData(self): csv_file_list = QtWidgets.QFileDialog.getSaveFileName( self, 'Store result in"', '/home', '*.csv') if len(csv_file_list) > 2: # Output a warning that we will not handle more than one file. self.statusbar.showMessage('Only saving to the first file.') csv_file = csv_file_list[0] if csv_file == '': self.statusbar.showMessage('Ready') return True self.updateSeries(self.currentSeries) try: self.data.save(csv_file) except IOError as err: self.statusbar.showMessage('Unable to write file:' + err) return True self.statusbar.showMessage('Saved to file ' + csv_file) return True def onpick(self, event): plotLevel = self.data.toggleSelected(event.ind[0], self.currentSeries, self.ax) self.updateSeriesTable() # Plot has been put on top of the layers. So we just need to check if it # is there or if it should be removed from the layers (empty set). if plotLevel: if self.plotLayers[-1] != self.currentSeries: self.plotLayers.append(self.currentSeries) else: if self.plotLayers[-1] == self.currentSeries: self.plotLayers.pop() def validate_param(self): try: prm = dict(a=atof(self.Calibration_a.text()), b=atof(self.Calibration_b.text()), X=atof(self.Calibration_X.text()), C=atof(self.TransferParam.text()), push=atof(self.PusherDelay.text()), gas=atof(self.Gas_mass.text()), M=atof(self.NeutralMass.text()), ppm=atof(self.MassAccuracy.text())) except ValueError: raise if self.MinCS.text == '': prm['MinCS'] = 1 else: try: prm['MinCS'] = atoi(self.MinCS.text()) except ValueError: raise if self.MaxCS.text == '': prm['MaxCS'] = prm['MinCS'] else: try: prm['MaxCS'] = atoi(self.MaxCS.text()) except ValueError: raise if prm['MaxCS'] < prm['MinCS']: tmp_min = prm['MaxCS'] prm['MaxCS'] = prm['MinCS'] prm['MinCS'] = tmp_min return prm def updateSeries(self, newseries): self.data.saveSeries(self.currentSeries) self.currentSeries = newseries newPlotPos = self.data.updatePlotSeries(self.currentSeries, self.plotLayers, self.ax) if newPlotPos: self.plotLayers.append(self.currentSeries) # Failsafe: should not happen because updateSeries is only called by # the selectSeries.valueChanged() signal and by saving the file which # does not change the series. if self.currentSeries != self.selectSeries.value(): self.selectSeries.setValue(self.currentSeries) self.updateSeriesTable() def updateSeriesTable(self): self.Output_Series.clear() selectedDataStats = self.data.getSelectedDataStats() self.Output_Series.setRowCount(len(selectedDataStats)) self.Output_Series.setColumnCount(2) for row, val in enumerate(selectedDataStats): print(lstr(row + 0.5)) label, value = val title = QtWidgets.QTableWidgetItem(label) self.Output_Series.setItem(row, 0, title) if not isinstance(value, str): value = lstr(value) print(value) value = QtWidgets.QTableWidgetItem(value) self.Output_Series.setItem(row, 1, value) self.Output_Series.resizeColumnsToContents() def nextSeries(self): if self.currentSeries >= self.selectSeries.maximum(): self.selectSeries.setMaximum(self.currentSeries + 1) self.selectSeries.setValue(self.currentSeries + 1) def prevSeries(self): if self.currentSeries > 1: self.selectSeries.setValue(self.currentSeries - 1)
class smileiQtPlot(QWidget): scalarDict=dict() fieldDict=dict() phaseDict=dict() fieldFile=None phaseFile=None nplots=0 ax={} dirName=None someCheckBoxChanged=False pauseSignal=pyqtSignal() shiftPressed=False title='' def __init__(self,parent,dirName): super(smileiQtPlot, self).__init__() self.setParent(parent) uiFile=os.path.dirname(os.path.realpath(__file__))+'/smileiQtPlot.ui' self.ui=uic.loadUi(uiFile,self) self.dirName=dirName self.parent=parent self.parent.timer.timeout.connect(self.next) self.parent.ui.next.released.connect(self.next) self.parent.ui.previous.released.connect(self.previous) self.parent.ui.first.released.connect(self.first) self.parent.ui.last.released.connect(self.last) self.pauseSignal.connect(self.parent.pause) self.setWindowFlags(Qt.Window) self.setWindowTitle(dirName) self.step=0 self.ui.savePoints.setIcon(self.ui.style().standardIcon(QStyle.SP_DialogSaveButton)) self.ui.savePoints.released.connect(self.doSavePoints) self.ui.tabWidget.currentChanged.connect(self.changeTab) self.ui.autoScale.stateChanged.connect(self.doPlots) self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.mpl_connect('motion_notify_event', self.on_movement) self.canvas.mpl_connect('key_press_event', self.on_key_press) self.canvas.mpl_connect('key_release_event', self.on_key_release) self.canvas.mpl_connect('button_press_event', self.on_button_press) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.setFixedHeight(18) self.canvas.setCursor(Qt.CrossCursor) self.ui.plotLayout.addWidget(self.canvas) self.ui.plotLayout.addWidget(self.toolbar) fname=os.path.join(dirName, "scalars.txt") if os.path.isfile(fname) : self.scalarData = np.loadtxt(fname) names=[] for line in open(fname): li=line.strip() if li.startswith("#"): list=line.split() names.append(list[-1]) scalars_names=names[1:-2] for i in range(len(scalars_names)): my_button= QCheckBox(scalars_names[i]) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutScalars.addWidget(my_button) self.ui.layoutScalars.addStretch() else : print "Problem reading ",fname # self.deleteLater() self.fieldSteps=[] fname=os.path.join(dirName, "Fields_avg.h5") if os.path.isfile(fname) : self.fieldFile=tb.openFile(fname) self.cell_length=self.fieldFile.root._v_attrs.cell_length[0] self.res_time=self.fieldFile.root._v_attrs.res_time self.sim_length=self.fieldFile.root._v_attrs.sim_length self.fieldEvery=self.fieldFile.root._v_attrs.every first=True for group in self.fieldFile.listNodes("/", classname='Group'): self.fieldSteps.append(group._v_name) if first: first=False for array in group: my_button= QCheckBox(array._v_name) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutFields.addWidget(my_button) self.ui.layoutFields.addStretch() self.ui.slider.setRange(0,len(self.fieldSteps)-1) else : print "Problem reading ",fname # self.deleteLater() self.ui.spinStep.setSuffix("/"+str(len(self.fieldSteps)-1)) self.ui.spinStep.setMaximum(len(self.fieldSteps)-1) fname=os.path.join(dirName, "PhaseSpace.h5") if os.path.isfile(fname) : self.phaseFile=tb.openFile(fname) for phaseData in self.phaseFile.walkNodes("/", classname='Array'): my_button= QCheckBox(phaseData._v_pathname) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutPhase.addWidget(my_button) self.ui.layoutPhase.addStretch() else : print "Problem reading ",fname # self.deleteLater() self.load_settings() if sys.platform == "darwin": self.raise_() self.show() def doSavePoints(self): fname=QFileDialog.getSaveFileName(self, 'Save Point logger', self.dirName, selectedFilter='*.txt') if fname: f = open(fname, 'w') f.write(self.ui.logger.toPlainText()) f.close() def checkBoxChanged(self): self.someCheckBoxChanged=True def load_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") settings.beginGroup(QDir(self.dirName).dirName()) log.info("settings file: %s"%settings.fileName()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): chkbox.setChecked(settings.value(chkbox.text()).toBool()) settings.endGroup() settings.endGroup() self.ui.tabWidget.setCurrentIndex(0) def save_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") settings.beginGroup(QDir(self.dirName).dirName()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): settings.setValue(chkbox.text(),chkbox.isChecked()) settings.endGroup() settings.endGroup() def next(self): self.ui.slider.setValue(self.step+1) def previous(self): self.ui.slider.setValue(self.step-1) def first(self): self.ui.slider.setValue(0) def last(self): self.ui.slider.setValue(len(self.fieldSteps)-1) def on_slider_valueChanged(self,step): self.step=step self.doPlots() @pyqtSignature("int") def on_spinStep_valueChanged(self,my_step): self.ui.slider.setValue(my_step) @pyqtSignature("int") def changeTab(self, tabNum): if self.ui.tabWidget.currentIndex()==0: self.doPlots() else: self.pauseSignal.emit() def preparePlots(self): log.info("here") self.someCheckBoxChanged=False self.scalarDict=dict() self.fieldDict=dict() self.phaseDict=dict() self.nplots=0 frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : for chkbox in frame.findChildren(QCheckBox): if chkbox.isChecked() : self.nplots+=1 if self.nplots > 0: self.fig.clear() self.title=self.fig.suptitle('') self.ax={} plot=0 col=0 log.info("preparing scalars") for i in self.ui.scalars.findChildren(QCheckBox): col+=1 if i.isChecked() : name=str(i.text()) if not (name in self.fieldDict): x=self.scalarData[:,0] y=self.scalarData[:,col] self.scalarDict[name]=(x,y) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.plot(x,y) ax.set_xlim(x.min(),x.max()) ax.set_ylabel(name) ax.axvline(x=0,c="red",linewidth=2,zorder=0, clip_on=False) self.ax[name]=ax plot+=1 log.info("preparing fields") for i in self.ui.fields.findChildren(QCheckBox): if i.isChecked() : log.info(i.text()) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) data=[] name=str(i.text()) for d in self.fieldFile.root: data.append(d._f_getChild(name)) self.fieldDict[name]=data if len(self.sim_length) == 1 : ax.set_xlim(0,self.sim_length) ax.set_ylabel(name) x=np.array(range(len(data[0])))*self.cell_length y=data[0].read() ax.plot(x,y) self.ax[name]=ax elif len(self.sim_length) == 2 : divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) ax.set_ylabel(name) im=ax.imshow([[0]],extent=(0,self.sim_length[0],0,self.sim_length[1]), aspect='auto',origin='lower') cb=plt.colorbar(im, cax=cax) self.ax[name]=ax plot+=1 log.info("preparing phase") for i in self.ui.phase.findChildren(QCheckBox): if i.isChecked() : name=str(i.text()) node=self.phaseFile.getNode(name) self.phaseDict[name]=node ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.set_ylabel(name) divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) im=ax.imshow([[0]],extent=node._v_parent._v_attrs.extents.reshape(4).tolist(),aspect='auto',origin='lower') cb=plt.colorbar(im, cax=cax) self.ax[name]=ax plot+=1 log.info("done") self.doPlots() def on_movement(self, event): if not event.inaxes: return msg = "%G %G" % (event.xdata, event.ydata) self.ui.pos.setText(msg) def on_key_press(self,event): if not event.inaxes: return if event.key == 'a': for line in event.inaxes.lines : if line.get_xdata().size > 1: data=line.get_ydata() nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : event.inaxes.set_ylim(mini,maxi) for image in event.inaxes.images : data=np.array(image.get_array()) nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : image.set_clim(mini,maxi) self.canvas.draw() elif event.key == 'l': if event.inaxes.lines : scale='log' if event.inaxes.get_yaxis().get_scale()== 'linear' else 'linear' try: event.inaxes.set_yscale(scale) self.canvas.draw() except ValueError: scale='log' if scale == 'linear' else 'linear' event.inaxes.set_yscale(scale) self.canvas.draw() elif event.inaxes.images : for image in event.inaxes.images : mini = np.array(image.get_array()).clip(0).min() if mini >0: maxi = np.array(image.get_array()).clip(0).max() pprint (vars(event.inaxes.images[0].norm)) try: event.inaxes.images[0].set_norm(LogNorm(mini,maxi)) self.canvas.draw() except ValueError: self.canvas.draw() elif event.key == 'shift': self.shiftPressed=True def on_key_release(self,event): if not event.inaxes: return if event.key == 'shift': self.shiftPressed=False def on_button_press(self,event): if not event.inaxes: return if self.shiftPressed == True : self.ui.logger.moveCursor (QTextCursor.End); for i in range(len(self.fig.axes)) : if self.fig.axes[i] == event.inaxes: txt = "%d %G %G %G\n" % (i, self.step/self.res_time*self.fieldEvery, event.xdata, event.ydata) QApplication.clipboard().setText(txt) self.ui.logger.insertPlainText(txt); self.ui.logger.moveCursor (QTextCursor.End); def doPlots(self): if len(self.fieldSteps) == 0 : return if self.someCheckBoxChanged==True: self.preparePlots() self.step %= len(self.fieldSteps) self.slider.setValue(self.step) self.ui.spinStep.setValue(self.step) time=float(self.step)/self.res_time*self.fieldEvery for name in self.scalarDict: self.ax[name].lines[-1].set_xdata(time) for name in self.fieldDict: data=self.fieldDict[name][self.step].read() if len(self.sim_length) == 1 : self.ax[name].lines[-1].set_ydata(data) if self.ui.autoScale.isChecked(): self.ax[name].set_ylim(min(data),max(data)) elif len(self.sim_length) == 2 : im=self.ax[name].images[-1] npData=np.array(data) im.set_data(npData.T) if self.ui.autoScale.isChecked(): im.set_clim(npData.min(),npData.max()) for name in self.phaseDict: data=self.phaseDict[name][self.step].T im=self.ax[name].images[-1] im.set_data(data) if self.ui.autoScale.isChecked(): im.set_clim(data.min(),data.max()) self.title.set_text('Time: %.3f'%time) self.canvas.draw() if self.ui.saveImages.isChecked(): self.fig.savefig(self.dirName+'-%06d.png' % self.step) def closeEvent(self,event): self.save_settings() if self.fieldFile is not None : self.fieldFile.close() if self.phaseFile is not None : self.phaseFile.close() self.parent.plots.remove(self) QApplication.processEvents() self.deleteLater()
class PlotCanvas(FigureCanvas): zoom_factor = 1 def __init__(self, parent=None, width=10, height=10, dpi=80): self.yFile = readConfigFile("sensor config/Stand_Configuration.yaml") self.yFile.dataConfer() self.fig = Figure(figsize=(width, height), facecolor='snow', linewidth=1, dpi=dpi) self.fig.patch.set_alpha(0.0) self.ax = self.fig.add_subplot(111) self.fig.subplots_adjust(left=0.05, right=0.85, top=0.95, bottom=0.05) self.odd_tool = Tool() self.press = None self.colors = [] self.in_view = [] self.in_scale_view = [] self.obj = [] self.text_fr = '' self.sensor_name = [] self.sensor_fr = [] self.sensor_cr = [] self.sensor_sr = [] self.patches = [] self.xlim_default = 60 * self.zoom_factor self.ylim_default = 60 * self.zoom_factor self.xlim_min, self.xlim_max = -self.xlim_default, self.xlim_default self.ylim_min, self.ylim_max = -self.ylim_default, self.ylim_default FigureCanvas.__init__(self, self.fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) self.fig.canvas.mpl_connect('scroll_event', self.scroll_call_back) self.fig.canvas.mpl_connect('button_press_event', self.press_call_back) self.fig.canvas.mpl_connect('button_release_event', self.release_call_back) def init_config(self, param): if param[1][0]: color_ca = 'green' else: color_ca = 'none' if param[1][1]: color_ra = 'blue' else: color_ra = 'none' if param[1][2]: color_li = 'red' else: color_li = 'none' self.colors = [color_ca, color_ra, color_li] if param[4][0]: config_book = load_workbook(param[4][0]) else: config_book = load_workbook('sensor config/Sensor_Configuration.xlsx') sheets = config_book.get_sheet_names() self.sensor_name = [] sensor_x = [] sensor_y = [] sensor_azimuth = [] self.sensor_fr = [] sensor_scale = [] self.sensor_cr = [] self.sensor_sr = [] for i in range(len(sheets)): sheet = config_book[sheets[i]] name_ = [] x_ = [] y_ = [] azimuth_ = [] failure_rate_ = [] view_scale_ = [] c_rate_ = [] s_rate_ = [] for j in range(2, sheet.max_row + 1): name_.append(str(sheet['A' + str(j)].value)) x_.append(float(sheet['C' + str(j)].value) * -self.zoom_factor) y_.append(float(sheet['B' + str(j)].value) * self.zoom_factor) azimuth_.append(int(sheet['D' + str(j)].value) + 90) failure_rate_.append(float(sheet['G' + str(j)].value)) view_scale_.append(float(sheet['H' + str(j)].value)) c_rate_.append(float(sheet['I' + str(j)].value)) s_rate_.append(float(sheet['J' + str(j)].value)) self.sensor_name.append(name_) sensor_x.append(x_) sensor_y.append(y_) sensor_azimuth.append(azimuth_) self.sensor_fr.append(failure_rate_) sensor_scale.append(view_scale_) self.sensor_cr.append(c_rate_) self.sensor_sr.append(s_rate_) x_camera = sensor_x[0] y_camera = sensor_y[0] xy_camera = list(zip(x_camera, y_camera)) azimuth_camera = sensor_azimuth[0] fov_camera = param[2][0] range_camera = param[3][0] camera_scale = sensor_scale[0] config_camera = [xy_camera, azimuth_camera, fov_camera, range_camera, camera_scale] x_radar = sensor_x[1] y_radar = sensor_y[1] xy_radar = list(zip(x_radar, y_radar)) azimuth_radar = sensor_azimuth[1] fov_radar = param[2][1] range_radar = param[3][1] radar_scale = sensor_scale[1] config_radar = [xy_radar, azimuth_radar, fov_radar, range_radar, radar_scale] x_lidar = sensor_x[2] y_lidar = sensor_y[2] xy_lidar = list(zip(x_lidar, y_lidar)) azimuth_lidar = sensor_azimuth[2] fov_lidar = param[2][2] range_lidar = param[3][2] lidar_scale = sensor_scale[2] config_lidar = [xy_lidar, azimuth_lidar, fov_lidar, range_lidar, lidar_scale] config = [config_camera, config_radar, config_lidar] # print(config_camera) return config def loadYaml(self, stand_param): self.patches.clear() i = 0 colorsStand = ['red'] for sensorType in self.yFile.yamlData: if stand_param[i]: for sensorData in self.yFile.yamlData[sensorType]: wedgeParams = self.yFile.yamlData[sensorType][sensorData] wedge = Wedge((wedgeParams['x'], wedgeParams['y']), wedgeParams['range'], wedgeParams['azimuth'] - wedgeParams['fov'] / 2, wedgeParams['azimuth'] + wedgeParams['fov'] / 2, ec="none") self.patches.append(wedge) # print(self.patches) # colors = np.linspace(0, 1, len(self.patches)) # 将patch集合包装成PatchCollection collection = PatchCollection(self.patches, facecolors=colorsStand[0], alpha=0.7, zorder=1) # cmap=plt.cm.hsv # collection.set_array(np.array(colors)) # collection.set_zorder(1) # 设置图层 # 将PatchCollection添加给axes对象 self.patches.clear() self.ax.add_collection(collection) i = i + 1 # s = getImage.StandPlot() # s.plot() # return collection def plot(self, param): self.fig.clear() self.ax = self.fig.add_subplot(111) #添加子图 self.fig.subplots_adjust(left=0.05, right=0.85, top=0.95, bottom=0.05) #设置边距 # self.ax.clear() self.config_all = self.init_config(param) #获取参数 if param[0][0] != '-- Choose ODD please --': self.obj = self.odd_import(self.ax, param[0]) config_select = [] color_select = [] for i in range(len(self.config_all)): if self.colors[i] != 'none': config_select.append(self.config_all[i]) color_select.append(self.colors[i]) else: pass detect = Detection(self.obj, config_select) #opencv检测 patches, paths = detect.plot() # 路径点坐标 # self.loadYaml() # for sensorType in self.yFile.yamlData: # s=self.loadYaml(sensorType) # s.set_zorder(1) # 设置图层 # self.ax.add_collection(s) for i in range(len(patches)): p = PatchCollection(patches[i], color=color_select[i], edgecolor=color_select[i], alpha=0.15) p.set_zorder(6) #设置图层 self.ax.add_collection(p) #将PatchCollection添加进axes对象 for m in range(len(paths)): for n in range(len(paths[m])): patch_polygon = PathPatch(paths[m][n], facecolor=color_select[m], edgecolor=color_select[m], alpha=0.15) patch_polygon.set_zorder(6) self.ax.add_patch(patch_polygon) self.in_view = detect.postdetection_list self.in_scale_view = detect.detection_list self.draw_ego_vehicle() # self.add_region() # self.redraw() def plotStand(self, param, flag, stand_param): self.fig.clear() self.ax = self.fig.add_subplot(111) #添加子图 self.fig.subplots_adjust(left=0.05, right=0.85, top=0.95, bottom=0.05) #设置边距 # self.ax.clear() self.config_all = self.init_config(param) #获取参数 if param[0][0] != '-- Choose ODD please --': self.obj = self.odd_import(self.ax, param[0]) config_select = [] color_select = [] for i in range(len(self.config_all)): if self.colors[i] != 'none': config_select.append(self.config_all[i]) color_select.append(self.colors[i]) else: pass detect = Detection(self.obj, config_select) #opencv检测 patches, paths = detect.plot() # 路径点坐标 if flag: self.loadYaml(stand_param) else: pass # for sensorType in self.yFile.yamlData: # s=self.loadYaml(sensorType) # s.set_zorder(1) # 设置图层 # self.ax.add_collection(s) for i in range(len(patches)): p = PatchCollection(patches[i], color=color_select[i], edgecolor=color_select[i], alpha=0.15) p.set_zorder(6) #设置图层 self.ax.add_collection(p) #将PatchCollection添加进axes对象 for m in range(len(paths)): for n in range(len(paths[m])): patch_polygon = PathPatch(paths[m][n], facecolor=color_select[m], edgecolor=color_select[m], alpha=0.15) patch_polygon.set_zorder(6) self.ax.add_patch(patch_polygon) self.in_view = detect.postdetection_list self.in_scale_view = detect.detection_list self.draw_ego_vehicle() # self.add_region() # self.redraw() def highlight_plot(self, param): color_select = [] for i in range(len(self.config_all)): if self.colors[i] != 'none' and param[1][i]: color_select.append(self.colors[i]) else: pass config_ = [] config_select = [] for i in range(len(self.config_all)): config = [] if param[0][i] and param[1][i]: current_row = param[2][i] for j in range(len(self.config_all[i])): if self.config_all[i][j]: config.append(self.config_all[i][j][current_row]) config_.append(config) config_select_ = list(map(list, zip(*config_))) config_select.append(config_select_) detect = Detection(self.obj, config_select) patches, paths = detect.plot() for i in range(len(patches)): p = PatchCollection(patches[i], color=color_select[i], edgecolor=color_select[i], alpha=0.6) p.set_zorder(6) self.ax.add_collection(p) for m in range(len(paths)): for n in range(len(paths[m])): patch_polygon = PathPatch(paths[m][n], facecolor=color_select[m], edgecolor=color_select[i], alpha=0.6) patch_polygon.set_zorder(6) self.ax.add_patch(patch_polygon) self.redraw() def redraw(self): self.ax.set_xlim(self.xlim_min, self.xlim_max) self.ax.set_ylim(self.ylim_min, self.ylim_max) self.draw() def get_detect_list(self, status): detected = [] scaled = [] total_fr = 0 total_dr = 0 self.text_fr = '' for obj in range(len(self.obj)): detected.append(['OBJECT ' + str(obj + 1)]) scaled.append(['OBJECT ' + str(obj + 1)]) self.text_fr += 'Object' + str(obj + 1) + '\n' obj_fr = 1 obj_dr = 0 for sensor_type in range(len(self.in_view)): if status[sensor_type]: for single_sensor in range(len(self.in_view[sensor_type])): if self.in_view[sensor_type][single_sensor][obj] == 1: detected.append([str(self.sensor_name[sensor_type][single_sensor]) + ': ' + str(self.sensor_fr[sensor_type][single_sensor])]) obj_fr = obj_fr * self.sensor_fr[sensor_type][single_sensor] if self.in_scale_view[sensor_type][single_sensor][obj] == 1: detect_rate = self.sensor_cr[sensor_type][single_sensor] scaled.append([str(self.sensor_name[sensor_type][single_sensor]) + ': ' + str(detect_rate)]) else: detect_rate = self.sensor_sr[sensor_type][single_sensor] scaled.append([str(self.sensor_name[sensor_type][single_sensor]) + ': ' + str(detect_rate)]) obj_dr = (1 - (1 - obj_dr) * (1 - detect_rate)) total_fr = 1 - (1 - total_fr) * (1 - obj_fr) total_dr = 1 - (1 - total_dr) * (1 - obj_dr) detected.append(['Failure Rate: ' + str(round(obj_fr, 8))]) detected.append([' ']) self.text_fr += 'FR: ' + str(round(obj_fr, 8)) + '\n' scaled.append(['Detection Rate: ' + str(round(obj_dr, 5))]) scaled.append([' ']) self.text_fr += 'DR: ' + str(round(obj_dr, 8)) + '\n\n' detected.append(['Total Failure Rate: ' + str(round(total_fr, 8))]) detected.append([' ']) scaled.append(['System Detection Rate: ' + str(round(total_dr, 8))]) scaled.append([' ']) self.text_fr += '(FR: Failure Rate)\n(DR: Detection Rate)\n' self.fig.text(0.86, 0.94, self.text_fr, ha='left', va='top') self.redraw() return detected, scaled def odd_import(self, ax, odd): if odd[1] == -1: odd[1] = 0 self.odd_tool.update_odd() file_name = self.odd_tool.odd_list[odd[0]] odd_path = 'scenarios/' + str(odd[0]) + '/' + file_name[odd[1]] + '.json' with open(odd_path, 'r') as load_f: load_dict = load(load_f) list_dict = list(load_dict.keys()) scenario = load_dict[list_dict[0]] try: lines1 = scenario['lines']['boundary_lines'] lines2 = scenario['lines']['solid_lines'] lines3 = scenario['lines']['dashed_lines'] lines4 = scenario['lines']['thick_lines'] objects = scenario['objects'] common_rotation = scenario['common_rotation'] common_offset = scenario['common_offset'] except Exception: lines1 = [] lines2 = [] lines3 = [] lines4 = [] objects = [] common_rotation = 0.0 common_offset = [0, 0] QMessageBox.warning(self, 'Warning', 'Scenario file format error!') boundary_lines = self.line_rotation(lines1, common_rotation) solid_lines = self.line_rotation(lines2, common_rotation) dashed_lines = self.line_rotation(lines3, common_rotation) thick_lines = self.line_rotation(lines4, common_rotation) for l in boundary_lines: for m in l: m[0] = (m[0] + common_offset[0]) * self.zoom_factor m[1] = (m[1] + common_offset[1]) * self.zoom_factor for l in solid_lines: for m in l: m[0] = (m[0] + common_offset[0]) * self.zoom_factor m[1] = (m[1] + common_offset[1]) * self.zoom_factor for l in dashed_lines: for m in l: m[0] = (m[0] + common_offset[0]) * self.zoom_factor m[1] = (m[1] + common_offset[1]) * self.zoom_factor for l in thick_lines: for m in l: m[0] = (m[0] + common_offset[0]) * self.zoom_factor m[1] = (m[1] + common_offset[1]) * self.zoom_factor line_segments1 = LineCollection(boundary_lines, linewidths=2, colors=(0, 0, 0), linestyles='solid') line_segments1.set_zorder(0) line_segments2 = LineCollection(solid_lines, linewidths=1, colors=(0.1, 0.1, 0.1), linestyles='solid') line_segments2.set_zorder(0) line_segments3 = LineCollection(dashed_lines, linewidths=1, colors=(0.2, 0.2, 0.2), linestyles=(0, (20, 20))) line_segments3.set_zorder(0) line_segments4 = LineCollection(thick_lines, linewidths=4.5, colors=(0.8, 0.8, 0.8), linestyles='solid') line_segments4.set_zorder(0) self.ax.add_collection(line_segments1) self.ax.add_collection(line_segments2) self.ax.add_collection(line_segments3) self.ax.add_collection(line_segments4) patch = [] for obj in range(len(objects)): objects_xy = self.object_rotation(objects[obj][1], common_rotation) objects_xy[0] = objects_xy[0] + common_offset[0] objects_xy[1] = objects_xy[1] + common_offset[1] objects_r = objects[obj][2] + common_rotation patch.append(self.add_object(objects[obj][0], objects_xy, objects_r)) self.ax.text((objects_xy[0]) * self.zoom_factor, (objects_xy[1] + 2.5) * self.zoom_factor, 'obj' + str(obj + 1), fontsize=10) patch_segment = PatchCollection(patch, facecolors='gray') patch_segment.set_zorder(2) ax.add_collection(patch_segment) return patch def add_region(self): lines_r = [[[-30, 2.5], [30, 2.5]], [[-30, 2.5], [-30, 30]], [[-30, 30], [-5, 30]], [[30, 2.5], [30, 30]], [[30, 30], [5, 30]], [[-9, 2.5], [-9, -60]], [[-9, -60], [-5.4, -60]], [[9, 2.5], [9, -60]], [[9, -60], [5.4, -60]], [[-1, -2.5], [1, -2.5]], [[-1, -2.5], [-1, -80]], [[1, -2.5], [1, -80]]] lines_b = [[[0, 0], [-5, 30]], [[0, 0], [5, 30]], [[-5.4, 2.5], [-5.4, -80]], [[-5.4, -80], [5.4, -80]], [[5.4, -80], [5.4, 2.5]]] line_segments_r = LineCollection(lines_r, linewidths=2, colors='red', linestyles='solid') line_segments_r.set_zorder(0) line_segments_b = LineCollection(lines_b, linewidths=2, colors='blue', linestyles='solid') line_segments_b.set_zorder(0) self.ax.add_collection(line_segments_r) self.ax.add_collection(line_segments_b) def add_object(self, obj_type, xy, angle): if obj_type == 0: vehicle_length = 4.5 * self.zoom_factor vehicle_width = 1.8 * self.zoom_factor x = xy[0] * self.zoom_factor y = xy[1] * self.zoom_factor patch = Rectangle(xy=(x, y), width=vehicle_length, height=vehicle_width, angle=angle) return patch if obj_type == 1: vehicle_length = 7.2 * self.zoom_factor vehicle_width = 2.3 * self.zoom_factor x = xy[0] * self.zoom_factor y = xy[1] * self.zoom_factor patch = Rectangle(xy=(x, y), width=vehicle_length, height=vehicle_width, angle=angle) return patch if obj_type == 2: vehicle_length = 1.5 * self.zoom_factor vehicle_width = 0.8 * self.zoom_factor x = xy[0] * self.zoom_factor y = xy[1] * self.zoom_factor patch = Rectangle(xy=(x, y), width=vehicle_length, height=vehicle_width, angle=angle) return patch if obj_type == 3: vehicle_length = 0.5 * self.zoom_factor vehicle_width = 0.5 * self.zoom_factor x = xy[0] * self.zoom_factor y = xy[1] * self.zoom_factor patch = Rectangle(xy=(x, y), width=vehicle_length, height=vehicle_width, angle=angle) return patch else: QMessageBox.information(self, 'Object Type Error!') def line_rotation(self, lines, angle): angle = angle * math.pi / 180.0 point_list = [] for i in range(len(lines)): point1 = lines[i][0] point2 = lines[i][1] point1_x = point1[0] * math.cos(angle) - point1[1] * math.sin(angle) point1_y = point1[0] * math.sin(angle) + point1[1] * math.cos(angle) point2_x = point2[0] * math.cos(angle) - point2[1] * math.sin(angle) point2_y = point2[0] * math.sin(angle) + point2[1] * math.cos(angle) list_ = [[np.round(point1_x, 1), np.round(point1_y, 1)], [np.round(point2_x, 1), np.round(point2_y, 1)]] point_list.append(list_) return point_list def object_rotation(self, point, angle): angle = angle * math.pi / 180.0 point_x = point[0] * math.cos(angle) - point[1] * math.sin(angle) point_y = point[0] * math.sin(angle) + point[1] * math.cos(angle) new_point = [np.round(point_x, 1), np.round(point_y, 1)] return new_point def draw_ego_vehicle(self): #车 lines_1 = [[0.45, 2.5], [0.9, 2.2], [0.95, 1.95], [0.95, -1.6], [0.9, -2.3], [0.35, -2.5], [-0.35, -2.5], [-0.9, -2.3], [-0.95, -1.6], [-0.95, 1.95], [-0.9, 2.2], [-0.45, 2.5]] # lines_1 = [[0, -2.51], [0.55, -2.47], [0.91, -2.28], [1, -1.94], [1, 1.84], [0.93, 2.19], [0.45, 2.47], # [0, 2.51], [-0.45, 2.47], [-0.93, 2.19], [-1, 1.84], [-1, -1.94], [-0.91, -2.28], [-0.55, -2.47]] lines_2 = [[0, 1.4], [0.35, 1.4], [0.8, 1.3], [0.9, 1.1], [0.85, -1.5], [0.8, -2.2], [0.35, -2.4], [0, -2.4], [-0.35, -2.4], [-0.8, -2.2], [-0.85, -1.5], [-0.9, 1.1], [-0.8, 1.3], [-0.35, 1.4]] lines_3 = [[0, 0.5], [0.65, 0.35], [0.6, -2.1], [-0.6, -2.1], [-0.65, 0.35]] lines_4 = [[0.87, 0.95], [0.95, 0.95], [1.13, 0.82], [1.13, 0.65], [0.93, 0.74], [0.87, 0.85]] lines_5 = [[-0.87, 0.95], [-0.95, 0.95], [-1.13, 0.82], [-1.13, 0.65], [-0.93, 0.74], [-0.87, 0.85]] nplines_1 = np.array(lines_1) * self.zoom_factor nplines_2 = np.array(lines_2) * self.zoom_factor nplines_3 = np.array(lines_3) * self.zoom_factor nplines_4 = np.array(lines_4) * self.zoom_factor nplines_5 = np.array(lines_5) * self.zoom_factor path_1 = self.get_path(nplines_1.tolist(), (0.5, 0.7, 0.8)) path_2 = self.get_path(nplines_2.tolist(), (0.3, 0.3, 0.3)) path_3 = self.get_path(nplines_3.tolist(), (0.2, 0.2, 0.2)) path_4 = self.get_path(nplines_4.tolist(), (0.2, 0.2, 0.2)) path_5 = self.get_path(nplines_5.tolist(), (0.2, 0.2, 0.2)) self.ax.add_patch(path_1) self.ax.add_patch(path_4) self.ax.add_patch(path_5) self.ax.add_patch(path_2) self.ax.add_patch(path_3) def get_path(self, lines, color): path_data = [] path_data.append((Path.MOVETO, (lines[0][0], lines[0][1]))) for i in range(len(lines) - 1): path_data.append((Path.LINETO, (lines[i + 1][0], lines[i + 1][1]))) path_data.append((Path.CLOSEPOLY, (lines[0][0], lines[0][1]))) codes, verts = zip(*path_data) path = PathPatch(Path(verts, codes), facecolor=color) path.set_zorder(4) return path def scroll_call_back(self, event): try: axtemp = event.inaxes x_min, x_max = axtemp.get_xlim() y_min, y_max = axtemp.get_ylim() except Exception: print(str(Exception)) else: if event.button == 'up': x_left = x_min - event.xdata x_right = x_max - event.xdata y_down = y_min - event.ydata y_up = y_max - event.ydata self.xlim_min = x_left * 1.1 + event.xdata self.xlim_max = x_right * 1.1 + event.xdata self.ylim_min = y_down * 1.1 + event.ydata self.ylim_max = y_up * 1.1 + event.ydata elif event.button == 'down': x_left = x_min - event.xdata x_right = x_max - event.xdata y_down = y_min - event.ydata y_up = y_max - event.ydata self.xlim_min = x_left / 1.1 + event.xdata self.xlim_max = x_right / 1.1 + event.xdata self.ylim_min = y_down / 1.1 + event.ydata self.ylim_max = y_up / 1.1 + event.ydata else: pass if self.ylim_max > 10 * self.ylim_default: self.xlim_min, self.xlim_max = -10 * self.xlim_default, 10 * self.xlim_default self.ylim_min, self.ylim_max = -10 * self.ylim_default, 10 * self.ylim_default else: pass self.redraw() def press_call_back(self, event): try: axtemp = event.inaxes self.press = axtemp.get_xlim(), axtemp.get_ylim(), event.xdata, event.ydata except Exception: print(Exception) else: pass def motion_call_back(self, event): if self.press is None: return if event.inaxes != self.ax: return xlim, ylim, xpress, ypress = self.press x_min, x_max = xlim y_min, y_max = ylim dx = event.xdata - xpress dy = event.ydata - ypress self.xlim_min, self.xlim_max = x_min - dx, x_max - dx self.ylim_min, self.ylim_max = y_min - dy, y_max - dy def release_call_back(self, event): if self.press is None: return if event.inaxes != self.ax: return xlim, ylim, xpress, ypress = self.press x_min, x_max = xlim y_min, y_max = ylim dx = event.xdata - xpress dy = event.ydata - ypress self.xlim_min, self.xlim_max = x_min - dx, x_max - dx self.ylim_min, self.ylim_max = y_min - dy, y_max - dy self.redraw() self.press = None
class Graph: """ The Graph class presents a tkinter interface for Matplotlib plots. It requires a Toplevel tkinter object for initialization. Attributes ---------- default_title : str The default title for a new or reset window and plot. master : tk.Toplevel The Toplevel tkinter object that must exist for Graph to exist. menubar : tk.menu The tkinter menubar object for user operations. fig : matplotlib.figure.Figure The matplotlib figure object contained within Graph. canvas : matplotlib.backends.backend_tkagg.FigureCanvasTkAgg The matplotlib drawing canvas object contained within Graph. toolbar: matplotlib.backends.backend_tkagg.NavigationToolbar2Tk The matplotlib toolbar object contained within Graph. ax : matplotlib.axes.Axes The matplotlib axis upon which line and legend operations are performed. hasLegend : tk.BooleanVar A state variable used to maintain the legend's existence state between graph updates (default is false) lines : DataSet[] A list of DataSet objects containing the data points and their formal names. line_counter : int An autoincrementing counter to assign numeric names to lines plotted without a specified name. Methods ------- plot(x=None, y=None, name=None) Plots x and y data on a Graph. clear(value) Deletes a stored DataSet value from the graph's self.lines DataSet objects list and removes its line and legend from the plot. legend(include=None) Updates the legend's values and maintains its state. Can be used to activate/deactivate the legend. linewidth(size) Changes the linewidth of all plotted lines. title(title) Sets the window title and the graph title. xlabel(xlabel) Sets the x-axis label. ylabel(ylabel) Sets the y-axis label. """ # Default window and plot title default_title = "Graph" ######################################################################### # # # GRAPH INITIALIZATION FUNCTIONS # # # ######################################################################### def __init__(self, parent: tk.Toplevel, window_title=None, additional_menus=None, onCloseCallback=None): # The master tk object self.parent = parent self.master = tk.Toplevel(parent) self.master.protocol("WM_DELETE_WINDOW", self.on_closing) # self.master = parent if window_title == None: self.master.title(Graph.default_title) else: self.master.title(window_title) self.menubar = tk.Menu(self.master) self.hasLegend = tk.BooleanVar() # The only real objects we'll need to interact with to plot and unplot self.fig = Figure(figsize=(5, 4), dpi=100) # Objects needed simply for the sake of embedding the graph in tk self.canvas = FigureCanvasTkAgg(self.fig, master=self.master) self.toolbar = NavigationToolbar2Tk(self.canvas, self.master) self.toolbar.update() self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.canvas.mpl_connect("key_press_event", self.on_key_press) # Setup the plot area, stored lines, and setup the menu now that all # variables exist. self.reset() self.init_menu(additional_menus=additional_menus) self.master.config(menu=self.menubar) self.onCloseCallback = onCloseCallback def reset(self): """Clears the figure, adds a new axis, resets the title, and clears all stored DataSet lines.""" self.fig.clear() self.ax = self.fig.add_subplot(111) self.hasLegend.set(False) self.title(Graph.default_title) # Lines is a list of DataSet objects. The user should take care to make # DataSet names unique, as there is no error checking done by Graph. # If a DataSet line is deleted by its formal name, Graph will delete the # first line in the list that matches the name. self.lines = {} self.line_counter = 1 def raise_window(self): self.master.attributes('-topmost', True) self.master.attributes('-topmost', False) def on_closing(self): if self.onCloseCallback is not None: self.onCloseCallback() self.master.destroy() ######################################################################### # # # MENU BUTTON IMPLEMENTATIONS # # # ######################################################################### def init_menu(self, additional_menus=None): filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="New", command=self.filemenu_New) #filemenu.add_command(label="Open", command=self.filemenu_Open) filemenu.add_command(label="Close", command=self.filemenu_Close) filemenu.add_separator() filemenu.add_command(label="Export to...", command=self.filemenu_Export) #filemenu.add_separator() #filemenu.add_command(label="Print") self.menubar.add_cascade(label="File", menu=filemenu) editmenu = tk.Menu(self.menubar, tearoff=0) editmenu.add_command(label="Delete line...", command=self.editmenu_DeleteLine) editmenu.add_command(label="Rename line...", command=self.editmenu_RenameLine) linewidth_submenu = tk.Menu(editmenu, tearoff=0) linewidth_submenu.add_command(label="Ultrathin", command=lambda: self.linewidth(0.5)) linewidth_submenu.add_command(label="Thin", command=lambda: self.linewidth(1.0)) linewidth_submenu.add_command(label="Default", command=lambda: self.linewidth(1.5)) linewidth_submenu.add_command(label="Thick", command=lambda: self.linewidth(2.0)) linewidth_submenu.add_command(label="Ultrathick", command=lambda: self.linewidth(2.5)) editmenu.add_cascade(label="Set linewidth", menu=linewidth_submenu) windowsize_submenu = tk.Menu(editmenu, tearoff=0) windowsize_submenu.add_command(label="Small") windowsize_submenu.add_command(label="Default") windowsize_submenu.add_command(label="Large") editmenu.add_cascade(label="Resize window", menu=windowsize_submenu) editmenu.add_command(label="Tight layout", command=self.tight_layout) self.menubar.add_cascade(label="Edit", menu=editmenu) insertmenu = tk.Menu(self.menubar, tearoff=0) insertmenu.add_command(label="X Label", command=self.insertmenu_XLabel) insertmenu.add_command(label="Y Label", command=self.insertmenu_YLabel) insertmenu.add_command(label="Title", command=self.insertmenu_Title) insertmenu.add_separator() insertmenu.add_checkbutton(label="Legend", onvalue=True, offvalue=False, variable=self.hasLegend, command=self.legend) self.menubar.add_cascade(label="Insert", menu=insertmenu) # An "additional_menu" is a dictionary where each key is the name of # the cascade to be added, and its corresponding value is a list of # MenuItem objects (each as a name and a callback function). if additional_menus != None: for cascade in additional_menus: cascade_menu = tk.Menu(self.menubar, tearoff=0) commands = additional_menus[cascade] for item in commands: cascade_menu.add_command(label=item.label, command=item.callback) self.menubar.add_cascade(label=cascade, menu=cascade_menu) helpmenu = tk.Menu(self.menubar, tearoff=0) helpmenu.add_command(label="About") helpmenu.add_command(label="Keyboard shortcuts") helpmenu.add_command(label="LaTeX") self.menubar.add_cascade(label="Help", menu=helpmenu) def filemenu_New(self): Graph(self.parent) #Graph(tk.Toplevel()) def filemenu_Open(self): options = {} options['initialdir'] = os.path.expanduser('~') options['parent'] = self.master f = filedialog.askopenfilename(**options) print("TODO") def filemenu_Export(self): """ If saved as .npz, note that it's a dictionary of lines being saved. On loading, you must specify allow_pickle=True. To access items in the dictionary, first take them out of the array. Example: -------- a = np.load('sample.npz') contents = a['lines'].item() """ line_dict = {} for line in self.lines.values(): for name, arr in line.to_mat().items(): line_dict[name] = arr fileTypes = [("MATLAB file", "*.mat"), ("NumPy file", "*.npz")] options = {} options['initialdir'] = os.path.expanduser('~') options['filetypes'] = fileTypes options['parent'] = self.master filename = filedialog.asksaveasfilename(**options) if filename: _, ext = os.path.splitext(filename) if ext == ".mat": sio.savemat(filename, line_dict) elif ext == ".npz": np.savez(filename, lines=line_dict) def editmenu_DeleteLine(self): linelist = [] for line in self.lines.values(): linelist.append(line.name) child_window = tk.Toplevel(self.master) delete = ListSelectDeleteDialog(child_window).askdeletelist(linelist) if delete != None: for item in delete: self.clear(item) def editmenu_RenameLine(self): linelist = [] for line in self.lines.values(): linelist.append(line.name) child_window = tk.Toplevel(self.master) orig, final = ListSelectRenameDialog(child_window).askrenamelist( linelist) if final: line = self.lines.pop(orig) line.name = final self.lines[final] = line self.legend() def insertmenu_XLabel(self): label = simpledialog.askstring("Edit X Label", "Wrap LaTeX in $", parent=self.master, initialvalue=self.ax.get_xlabel()) if label is not None: self.xlabel(label) def insertmenu_YLabel(self): label = simpledialog.askstring("Edit Y Label", "Wrap LaTeX in $", parent=self.master, initialvalue=self.ax.get_ylabel()) if label is not None: self.ylabel(label) def insertmenu_Title(self): label = simpledialog.askstring("Edit Title", "Wrap LaTeX in $", parent=self.master, initialvalue=self.ax.get_title()) if label is not None: self.title(label) def on_key_press(self, event): """Registers a key press event (default matplotlib keybindings are implemented). Parameters ---------- event : Event An event like a key press that is passed to the matplotlib key press handler. """ #print("you pressed {}".format(event.key)) key_press_handler(event, self.canvas, self.toolbar) def filemenu_Close(self): """Destroys the child tkinter object upon closing.""" self.on_closing() ######################################################################### # # # PLOTTING AND AXIS MANIPULATION FUNCTIONS # # # ######################################################################### def plot(self, x: np.array, y: np.array, name: str = None): """Plots x and y data on a Graph. Parameters ---------- x : np.array The x axis values y : np.array The y axis values name : str, optional The name for this line (default = None). Line names are required to be unique, and Graph raises a ValueError if the unique name constraint is not satisfied. Raises ------ ValueError If the shapes of x or y are different. """ if x.shape == y.shape and name not in self.lines: if name == None: name = "Line " + str(self.line_counter) self.line_counter += 1 dataset = DataSet(x, y, name) dataset.setObjectID(self.ax.plot(dataset.x, dataset.y)) self.lines[dataset.name] = dataset self.legend() self.canvas.draw() else: if x.shape != y.shape: raise ValueError("x and y array shapes do not match.") if (name in self.lines): raise ValueError( "line with specified name already exists (unique constraint failed)." ) raise ValueError("Error in required arguments for plotting.") # Much help derived from https://stackoverflow.com/questions/4981815/how-to-remove-lines-in-a-matplotlib-plot def clear(self, value=None): """Deletes a stored DataSet value from the graph's self.lines DataSet objects list and removes its line and legend from the plot. The user should take care to make DataSet names unique, as Graph will raise a value error if attempts are made to plot a duplicate. Parameters ---------- value : str The line with the specified name is deleted (no effect if it doesn't exist). If None, all lines are cleared from the graph. """ if value is not None: for line in self.lines.values(): if line.name == value: self.ax.lines.remove(line.getObjectID()) self.lines.pop(line.name) break else: self.reset() # Remove the lines that have been cleared from the legend. self.legend() self.canvas.draw() def legend(self, include: bool = None): """Updates the legend's values and maintains its state. Parameters ---------- include : bool, optional If not specified, default behavior is to maintain the legend's present state (self.hasLegend). If true, a draggable legend is placed onto the Graph. If false, the legend is turned off. """ if include == None: if self.hasLegend.get() == True: include = True else: include = False if include == True: labels = [] for line in self.lines.values(): labels.append(line.name) self.ax.legend(labels).set_draggable(True) self.hasLegend.set(True) else: self.ax.legend().remove( ) # This line complains to the console if no legend exists when it's removed self.hasLegend.set(False) self.canvas.draw() def linewidth(self, size: float): """Changes the linewidth of all plotted lines. Some suggested line sizes: Ultrathin Thin Default Thick Ultrathick Custom 0.5 1.0 1.5 2.0 2.5 _._ Parameters ---------- size : float A floating point value of the thickness to use. """ for line in self.ax.lines: line.set_linewidth(size) self.canvas.draw() def title(self, title: str): """Sets the window title and the graph title. Parameters ---------- title : str The graph and window Title. """ #self.master.title(title) self.ax.set_title(title) self.canvas.draw() def xlabel(self, xlabel: str): """Sets the x-axis label. Parameters ---------- xlabel : str The x-axis label. """ self.ax.set_xlabel(xlabel) self.canvas.draw() def ylabel(self, ylabel: str): """Sets the y-axis label. Parameters ---------- ylabel : str The y-axis label. """ self.ax.set_ylabel(ylabel) self.canvas.draw() def get_lines(self): """Returns all lines (DataSet) objects stored within the graph Since these contain references to the line objects, they can be altered and updated. This allows externally implemented menus to access the data within the graph and perform operations on it, e.g. converting the x-axis from frequency to wavelength. """ return self.lines def refresh(self): """Refreshes the axis plot. If data within the lines has changed, the lines are redrawn and the plot rescaled to fit them. """ self.ax.relim() self.ax.autoscale_view() self.canvas.draw() def tight_layout(self): """Applies the tight layout to the figure. """ self.fig.tight_layout() self.canvas.draw()
class MainPanel(wx.Dialog): def __init__(self, parent, pathToPlugins=None): #, main_playlist, nb_playlist): if (not pathToPlugins == None): RESFILE = os.path.join(pathToPlugins, 'x2') + os.sep + "layout_x2.xml" wx.Dialog.__init__(self, parent, -1, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) self.parent = parent self.nb_playlist = 0 self.main_playlist = self.parent.lc_playlist #self.super_parent = super_parent # XML Resources can be loaded from a file like this: res = xrc.XmlResource(RESFILE) # Now create a panel from the resource data panel = res.LoadPanel(self, "m_pa_x2main") #self.panel = panel #background = 'tulips.jpg' #img = wx.Image(background, wx.BITMAP_TYPE_ANY) #self.buffer = wx.BitmapFromImage(img) #dc = wx.BufferedDC(wx.ClientDC(panel), self.buffer) #self.panel.Bind(wx.EVT_PAINT, self.OnPaint) # control references -------------------- self.pa_x2main = xrc.XRCCTRL(self, 'm_pa_x2main') self.pa_x2_graph = xrc.XRCCTRL(self, 'm_pa_x2_graph') self.lc_x2_plist = xrc.XRCCTRL(self, 'm_lc_x2_plist') self.cl_x2_features = xrc.XRCCTRL(self, 'm_cl_x2_features') self.sl_x2_pointsize = xrc.XRCCTRL(self, 'm_sl_x2_pointsize') self.lc_x2_plist.InsertColumn(0, "Artist") self.lc_x2_plist.InsertColumn(1, "Song") self.lc_x2_plist.SetColumnWidth(0, 100) self.lc_x2_plist.SetColumnWidth(1, 100) self.Bind(wx.EVT_BUTTON, self.OnAutoGenerateX2Playist, id=xrc.XRCID('m_bu_x2_plize')) self.Bind(wx.EVT_BUTTON, self.OnCenterClick, id=xrc.XRCID('m_bu_x2_center')) self.Bind(wx.EVT_SLIDER, self.OnPointSizeClick, id=xrc.XRCID('m_sl_x2_pointsize')) self.Bind(wx.EVT_SPIN, self.OnZoomClick, id=xrc.XRCID('m_sb_x2_zoom')) self.Bind(wx.EVT_SPIN, self.OnPanXClick, id=xrc.XRCID('m_sb_x2_panx')) self.Bind(wx.EVT_SPIN, self.OnPanYClick, id=xrc.XRCID('m_sb_x2_pany')) self.Bind(wx.EVT_CHECKBOX, self.OnXAxisClick, id=xrc.XRCID('m_cb_x2_xlog')) self.Bind(wx.EVT_CHECKBOX, self.OnYAxisClick, id=xrc.XRCID('m_cb_x2_ylog')) self.Bind(wx.EVT_CHECKLISTBOX, self.OnCheckListBox, self.cl_x2_features) self.current_zoom = 0 self.current_panx = 0 self.current_pany = 0 #features array #tag_array = GetTags() self.cl_x2_features.Set(FEATURES_ARRAY) #self.cl_x2_features.AppendItems(tag_array) self.figure = Figure(None, None, (1, 1, 1), None, 1.0, True, None) #facecolor=0.75, edgecolor='white') #(figsize=None, dpi=None, facecolor=None, edgecolor=None, linewidth=1.0, frameon=True, subplotpars=None) self.MakeScatt([0, 1, 2, 3]) self.build_graph() self.build_collection() self.canvas = FigureCanvas(self.pa_x2_graph, -1, self.figure) self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseRightDown) #self.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.Bind(wx.EVT_RIGHT_UP, self.OnMouseRightUp) self.canvas.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseRightDown) #self.canvas.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.canvas.Bind(wx.EVT_RIGHT_UP, self.OnMouseRightUp) # Note that event is a MplEvent #self.canvas.mpl_connect('motion_notify_event', self.OnMouseMotion) #self.canvas.Bind(wx.EVT_ENTER_WINDOW, self.ChangeCursor) #lasso self.mpl = self.canvas.mpl_connect('button_press_event', self.onpress) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.pa_x2main, 1, wx.EXPAND | wx.ALL, 5) self.SetSizer(sizer) self.SetAutoLayout(True) self.Fit() # ----------------------------------------- # ----------------------------------------- def OnPaint(self, evt): dc = wx.BufferedPaintDC(self.panel, self.buffer) def ChangeCursor(self, curtype): self.canvas.SetCursor(wx.StockCursor(curtype)) def OnMouseRightDown(self, evt): self.canvas.mpl_disconnect(self.mpl) self.canvas.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.ChangeCursor(wx.CURSOR_HAND) self.Refresh() self.oldx = evt.GetPosition()[0] self.oldy = evt.GetPosition()[1] #self.wPos = self.ClientToScreen((0,0)) self.CaptureMouse() #print 'right-down' def OnMouseMotion(self, evt): if evt.Dragging() and evt.RightIsDown(): dPos = evt.GetPosition( ) #evt.GetEventObject().ClientToScreen(evt.GetPosition()) #nPos = (self.wPos.x + (dPos.x - self.ldPos.x), -2) #nPos = (self.wPos.x + (dPos.x - self.ldPos.x), self.wPos.y + (dPos.y - self.ldPos.y)) #print(nPos) #print self.ldPos curx = dPos[0] cury = dPos[1] x = self.axes.get_xaxis() y = self.axes.get_yaxis() if (curx - self.oldx) < -10: x.pan(.5) self.oldx = curx if (curx - self.oldx) > 10: x.pan(-.5) self.oldx = curx if (cury - self.oldy) > 10: y.pan(.5) self.oldy = cury if (cury - self.oldy) < -10: y.pan(-.5) self.oldy = cury self.canvas.draw() def OnMouseRightUp(self, evt): try: self.ReleaseMouse() except wx._core.PyAssertionError: pass self.ChangeCursor(wx.CURSOR_DEFAULT) self.canvas.Unbind(wx.EVT_MOTION) self.Unbind(wx.EVT_MOTION) self.mpl = self.canvas.mpl_connect('button_press_event', self.onpress) def UpdateStatusBar(self, event): if event.inaxes: x, y = event.xdata, event.ydata self.statusBar.SetStatusText(("x= " + str(x) + " y=" + str(y)), 0) def OnPointSizeClick(self, event): self.point_size = self.sl_x2_pointsize.GetValue( ) + 50 # range 50 to 300 self.figure.clear() self.build_graph() self.build_collection() self.canvas.draw() def OnCenterClick(self, event): self.figure.clear() self.build_graph() self.build_collection() self.canvas.draw() def OnZoomClick(self, event=None): x = self.axes.get_xaxis() y = self.axes.get_yaxis() if event.GetPosition() > self.current_zoom: x.zoom(1) y.zoom(1) else: x.zoom(-1) y.zoom(-1) self.current_zoom = event.GetPosition() self.canvas.draw() def OnMouseWheel(self, evt): rotation = evt.GetWheelRotation() x = self.axes.get_xaxis() y = self.axes.get_yaxis() if rotation > 0: x.zoom(1) y.zoom(1) else: x.zoom(-1) y.zoom(-1) self.canvas.draw() # Done handling event #evt.Skip() def OnPanXClick(self, event): x = self.axes.get_xaxis() y = self.axes.get_yaxis() if event.GetPosition() > self.current_panx: x.pan(1) else: x.pan(-1) self.current_panx = event.GetPosition() self.canvas.draw() def OnPanYClick(self, event): x = self.axes.get_xaxis() y = self.axes.get_yaxis() if event.GetPosition() > self.current_pany: y.pan(1) else: y.pan(-1) self.current_pany = event.GetPosition() self.canvas.draw() def OnXAxisClick(self, event): if self.axes.get_xscale() == 'log': self.axes.set_xscale('linear') else: self.axes.set_xscale('log') #self.axes.autoscale_view() #self.canvas.draw_idle() #self.axes.autoscale_view() self.canvas.draw() #self.canvas.Refresh(eraseBackground=False) def OnYAxisClick(self, event): if self.axes.get_yscale() == 'log': self.axes.set_yscale('linear') else: self.axes.set_yscale('log') #self.axes.autoscale_view() self.canvas.draw() # ---------------------------------------------------------- def OnCheckListBox(self, event): index = event.GetSelection() label = self.cl_x2_features.GetString(index) #print label #print index self.cl_x2_features.SetSelection( index) # so that (un)checking also selects (moves the highlight) #print self.cl_x2_features.GetCount() selected_array = [] for x in range(0, self.cl_x2_features.GetCount()): if self.cl_x2_features.IsChecked(x) == True: selected_array.append(x) print selected_array if len(selected_array) >= 1: #print 'fofofofof' self.figure.clear() self.MakeScatt(selected_array) self.build_graph() self.build_collection() self.canvas.draw() # ---------------------------------------------------------- # ---------------------------------------------------------- def MakeScatt(self, selected_array): pre_data_array, self.song_array, self.color_array, use_std = GetResultsArray( selected_array) #print pre_data_array pca1, pca2, pca3 = pca_module.PCA_svd(pre_data_array, use_std) #print self.data_array #print pca1 #self.data = pca1 #print pca2 #grab the first 2 components self.data_array = np.array_split(pca1, [ 2, ], axis=1)[0] #print self.data_array #self.axes.set_xlabel(r'$\Delta_i$', fontsize=20) #self.axes.set_ylabel(r'$\Delta_{i+1}$', fontsize=20) #self.axes.set_title('Volume and percent change') #self.axes.grid(True) ### use zoom instead #self.xmin = self.data1.min()# - (self.data1.max() * 0.1) #self.xmax = self.data1.max()# * 1.1 #self.ymin = self.data2.min()# - (self.data2.max() * 0.1) #self.ymax = self.data2.max()# * 1.1 def build_graph(self): self.axes = self.figure.add_subplot(111, axisbg=(1, 1, 1)) self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0) #self.axes.frame_on(False) #subplot(111, axisbg='darkslategray') #ax = fig.add_subplot(111) #self.axes.scatter(self.data2, self.data1, c=[0.5,0.5,1.0], s=200, alpha=0.5) def build_collection(self): self.point_size = self.sl_x2_pointsize.GetValue( ) + 50 # range 50 to 300 self.collection = RegularPolyCollection( #self.axes.figure.dpi, numsides=80, sizes=(self.point_size, ), facecolors=self.color_array, offsets=self.data_array, transOffset=self.axes.transData) self.collection.set_alpha(0.7) self.axes.add_collection(self.collection) #self.axes.axis([self.xmin, self.xmax, self.ymin, self.ymax]) self.axes.autoscale_view() x = self.axes.get_xaxis() y = self.axes.get_yaxis() x.zoom(-1) y.zoom(-1) #self.axes.axis('tight') ##self.axes.axis('off') def callback(self, verts): facecolors = self.collection.get_facecolors() ind = nonzero(points_inside_poly(self.data_array, verts))[0] for i in range(len(self.data_array)): if i in ind: facecolors[i] = (1, 1, 0, .5) #print facecolors[i] #pass else: facecolors[i] = self.color_array[i] #pass #print facecolors[i] self.canvas.draw_idle() self.canvas.widgetlock.release(self.lasso) del self.lasso #self.ind = ind self.pass_data(ind) def onpress(self, event): #print event.button if self.canvas.widgetlock.locked(): #print 'foo' self.canvas.widgetlock.release(self.lasso) #return if event.inaxes is None: return self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback) # acquire a lock on the widget drawing self.canvas.widgetlock(self.lasso) def pass_data(self, ind): #populate parents list control self.lc_x2_plist.DeleteAllItems() for x in ind: self.lc_x2_plist.InsertStringItem(0, self.song_array[x][0]) self.lc_x2_plist.SetStringItem(0, 1, self.song_array[x][1]) #pass def update_data(self): pass #self.figure.clf() #build_graph(self) #self.MakeScatt() #self.build_collection() def OnAutoGenerateX2Playist(self, event): # copy the sifted list to the playlist self.parent.CheckClear() insert_at = self.parent.lc_playlist.GetItemCount() for x in range(self.lc_x2_plist.GetItemCount(), 0, -1): artist = self.lc_x2_plist.GetItem(x - 1, 0).GetText() song = self.lc_x2_plist.GetItem(x - 1, 1).GetText() self.parent.SetPlaylistItem(insert_at, artist, song, '', '') #save the playlist self.parent.SavePlaylist() # switch tabs self.parent.nb_main.SetSelection(self.nb_playlist)
class PlotImage(FigureCanvas): def __init__(self, model, parent, main_window): self.figure = Figure(dpi=main_window.logicalDpiX()) super().__init__(self.figure) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) self.model = model self.main_window = main_window self.parent = parent self.rubber_band = QRubberBand(QRubberBand.Rectangle, self) self.band_origin = QtCore.QPoint() self.x_plot_origin = None self.y_plot_origin = None self.colorbar = None self.data_indicator = None self.tally_data_indicator = None self.image = None self.menu = QMenu(self) def enterEvent(self, event): self.setCursor(QtCore.Qt.CrossCursor) self.main_window.coord_label.show() def leaveEvent(self, event): self.main_window.coord_label.hide() self.main_window.statusBar().showMessage("") def mousePressEvent(self, event): self.main_window.coord_label.hide() position = event.pos() # Set rubber band absolute and relative position self.band_origin = position self.x_plot_origin, self.y_plot_origin = self.getPlotCoords(position) # Create rubber band self.rubber_band.setGeometry(QtCore.QRect(self.band_origin, QtCore.QSize())) def getPlotCoords(self, pos): x, y = self.mouseEventCoords(pos) # get the normalized axis coordinates from the event display units transform = self.ax.transAxes.inverted() xPlotCoord, yPlotCoord = transform.transform((x, y)) # flip the y-axis (its zero is in the upper left) # scale axes using the plot extents xPlotCoord = self.ax.dataLim.x0 + xPlotCoord * self.ax.dataLim.width yPlotCoord = self.ax.dataLim.y0 + yPlotCoord * self.ax.dataLim.height # set coordinate label if pointer is in the axes if self.parent.underMouse(): self.main_window.coord_label.show() self.main_window.showCoords(xPlotCoord, yPlotCoord) else: self.main_window.coord_label.hide() return (xPlotCoord, yPlotCoord) def _resize(self): z = self.main_window.zoom / 100.0 # manage scroll bars if z <= 1.0: self.parent.verticalScrollBar().hide() self.parent.horizontalScrollBar().hide() self.parent.cornerWidget().hide() self.parent.verticalScrollBar().setEnabled(False) self.parent.horizontalScrollBar().setEnabled(False) else: self.parent.verticalScrollBar().show() self.parent.horizontalScrollBar().show() self.parent.cornerWidget().show() self.parent.verticalScrollBar().setEnabled(True) self.parent.horizontalScrollBar().setEnabled(True) # resize plot self.resize(self.parent.width() * z, self.parent.height() * z) def getDataIndices(self, event): cv = self.model.currentView x, y = self.mouseEventCoords(event.pos()) # get origin in axes coordinates x0, y0 = self.ax.transAxes.transform((0.0, 0.0)) # get the extents of the axes box in axes coordinates bbox = self.ax.get_window_extent().transformed( self.figure.dpi_scale_trans.inverted()) # get dimensions and scale using dpi width, height = bbox.width, bbox.height width *= self.figure.dpi height *= self.figure.dpi # use factor to get proper x,y position in pixels factor = (width/cv.h_res, height/cv.v_res) xPos = int((x - x0 + 0.01) / factor[0]) # flip y-axis yPos = cv.v_res - int((y - y0 + 0.01) / factor[1]) return xPos, yPos def getTallyIndices(self, event): xPos, yPos = self.getPlotCoords(event.pos()) ext = self.model.tally_extents x0 = ext[0] y0 = ext[2] v_res, h_res = self.model.tally_data.shape dx = (ext[1] - ext[0]) / h_res dy = (ext[3] - ext[2]) / v_res i = int((xPos - x0) // dx) j = v_res - int((yPos - y0) // dy) - 1 return i, j def getTallyInfo(self, event): cv = self.model. currentView xPos, yPos = self.getTallyIndices(event) if self.model.tally_data is None: return -1, None if not cv.selectedTally or not cv.tallyDataVisible: return -1, None # don't look up mesh filter data (for now) tally = self.model.statepoint.tallies[cv.selectedTally] # check that the position is in the axes view v_res, h_res = self.model.tally_data.shape if 0 <= yPos < v_res and 0 <= xPos < h_res: value = self.model.tally_data[yPos][xPos] else: value = None return cv.selectedTally, value def getIDinfo(self, event): xPos, yPos = self.getDataIndices(event) # check that the position is in the axes view if 0 <= yPos < self.model.currentView.v_res \ and 0 <= xPos and xPos < self.model.currentView.h_res: id = self.model.ids[yPos][xPos] temp = "{:g}".format(self.model.properties[yPos][xPos][0]) density = "{:g}".format(self.model.properties[yPos][xPos][1]) else: id = _NOT_FOUND density = str(_NOT_FOUND) temp = str(_NOT_FOUND) if self.model.currentView.colorby == 'cell': domain = self.model.activeView.cells domain_kind = 'Cell' elif self.model.currentView.colorby == 'temperature': domain = self.model.activeView.materials domain_kind = 'Temperature' elif self.model.currentView.colorby == 'density': domain = self.model.activeView.materials domain_kind = 'Density' else: domain = self.model.activeView.materials domain_kind = 'Material' properties = {'density': density, 'temperature': temp} return id, properties, domain, domain_kind def mouseDoubleClickEvent(self, event): xCenter, yCenter = self.getPlotCoords(event.pos()) self.main_window.editPlotOrigin(xCenter, yCenter, apply=True) def mouseMoveEvent(self, event): cv = self.model.currentView # Show Cursor position relative to plot in status bar xPlotPos, yPlotPos = self.getPlotCoords(event.pos()) # Show Cell/Material ID, Name in status bar id, properties, domain, domain_kind = self.getIDinfo(event) domainInfo = "" tallyInfo = "" if self.parent.underMouse(): if domain_kind.lower() in _MODEL_PROPERTIES: line_val = float(properties[domain_kind.lower()]) line_val = max(line_val, 0.0) self.updateDataIndicatorValue(line_val) domain_kind = 'Material' temperature = properties['temperature'] density = properties['density'] if id == _VOID_REGION: domainInfo = ("VOID") elif id == _OVERLAP: domainInfo = ("OVERLAP") elif id != _NOT_FOUND and domain[id].name: domainInfo = ("{} {}: \"{}\"\t Density: {} g/cc\t" "Temperature: {} K".format(domain_kind, id, domain[id].name, density, temperature)) elif id != _NOT_FOUND: domainInfo = ("{} {}\t Density: {} g/cc\t" "Temperature: {} K".format(domain_kind, id, density, temperature)) else: domainInfo = "" if self.model.tally_data is not None: tid, value = self.getTallyInfo(event) if value is not None and value != np.nan: self.updateTallyDataIndicatorValue(value) tallyInfo = "Tally {} {}: {:.5E}".format(tid, cv.tallyValue, value) else: self.updateTallyDataIndicatorValue(0.0) else: self.updateTallyDataIndicatorValue(0.0) self.updateDataIndicatorValue(0.0) if domainInfo: self.main_window.statusBar().showMessage( " " + domainInfo + " " + tallyInfo) else: self.main_window.statusBar().showMessage(" " + tallyInfo) # Update rubber band and values if mouse button held down if event.buttons() == QtCore.Qt.LeftButton: self.rubber_band.setGeometry( QtCore.QRect(self.band_origin, event.pos()).normalized()) # Show rubber band if both dimensions > 10 pixels if self.rubber_band.width() > 10 and self.rubber_band.height() > 10: self.rubber_band.show() else: self.rubber_band.hide() # Update plot X Origin xCenter = (self.x_plot_origin + xPlotPos) / 2 yCenter = (self.y_plot_origin + yPlotPos) / 2 self.main_window.editPlotOrigin(xCenter, yCenter) modifiers = event.modifiers() # Zoom out if Shift held if modifiers == QtCore.Qt.ShiftModifier: cv = self.model.currentView bandwidth = abs(self.band_origin.x() - event.pos().x()) width = cv.width * (cv.h_res / max(bandwidth, .001)) bandheight = abs(self.band_origin.y() - event.pos().y()) height = cv.height * (cv.v_res / max(bandheight, .001)) # Zoom in else: width = max(abs(self.x_plot_origin - xPlotPos), 0.1) height = max(abs(self.y_plot_origin - yPlotPos), 0.1) self.main_window.editWidth(width) self.main_window.editHeight(height) def mouseReleaseEvent(self, event): if self.rubber_band.isVisible(): self.rubber_band.hide() self.main_window.applyChanges() else: self.main_window.revertDockControls() def wheelEvent(self, event): if event.delta() and event.modifiers() == QtCore.Qt.ShiftModifier: numDegrees = event.delta() / 8 if 24 < self.main_window.zoom + numDegrees < 5001: self.main_window.editZoom(self.main_window.zoom + numDegrees) def contextMenuEvent(self, event): self.menu.clear() self.main_window.undoAction.setText('&Undo ({})'.format(len(self.model.previousViews))) self.main_window.redoAction.setText('&Redo ({})'.format(len(self.model.subsequentViews))) id, properties, domain, domain_kind = self.getIDinfo(event) cv = self.model.currentView # always provide undo option self.menu.addSeparator() self.menu.addAction(self.main_window.undoAction) self.menu.addAction(self.main_window.redoAction) self.menu.addSeparator() if int(id) not in (_NOT_FOUND, _OVERLAP) and \ cv.colorby not in _MODEL_PROPERTIES: # Domain ID if domain[id].name: domainID = self.menu.addAction("{} {}: \"{}\"".format(domain_kind, id, domain[id].name)) else: domainID = self.menu.addAction("{} {}".format(domain_kind, id)) self.menu.addSeparator() colorAction = self.menu.addAction('Edit {} Color...'.format(domain_kind)) colorAction.setDisabled(cv.highlighting) colorAction.setToolTip('Edit {} color'.format(domain_kind)) colorAction.setStatusTip('Edit {} color'.format(domain_kind)) domain_color_connector = partial(self.main_window.editDomainColor, domain_kind, id) colorAction.triggered.connect(domain_color_connector) maskAction = self.menu.addAction('Mask {}'.format(domain_kind)) maskAction.setCheckable(True) maskAction.setChecked(domain[id].masked) maskAction.setDisabled(not cv.masking) maskAction.setToolTip('Toggle {} mask'.format(domain_kind)) maskAction.setStatusTip('Toggle {} mask'.format(domain_kind)) mask_connector = partial(self.main_window.toggleDomainMask, kind=domain_kind, id=id) maskAction.toggled.connect(mask_connector) highlightAction = self.menu.addAction('Highlight {}'.format(domain_kind)) highlightAction.setCheckable(True) highlightAction.setChecked(domain[id].highlight) highlightAction.setDisabled(not cv.highlighting) highlightAction.setToolTip('Toggle {} highlight'.format(domain_kind)) highlightAction.setStatusTip('Toggle {} highlight'.format(domain_kind)) highlight_connector = partial(self.main_window.toggleDomainHighlight, kind=domain_kind, id=id) highlightAction.toggled.connect(highlight_connector) else: self.menu.addAction(self.main_window.undoAction) self.menu.addAction(self.main_window.redoAction) if cv.colorby not in _MODEL_PROPERTIES: self.menu.addSeparator() if int(id) == _NOT_FOUND: bgColorAction = self.menu.addAction('Edit Background Color...') bgColorAction.setToolTip('Edit background color') bgColorAction.setStatusTip('Edit plot background color') connector = partial(self.main_window.editBackgroundColor, apply=True) bgColorAction.triggered.connect(connector) elif int(id) == _OVERLAP: olapColorAction = self.menu.addAction('Edit Overlap Color...') olapColorAction.setToolTip('Edit overlap color') olapColorAction.setStatusTip('Edit plot overlap color') connector = partial(self.main_window.editOverlapColor, apply=True) olapColorAction.triggered.connect(connector) self.menu.addSeparator() self.menu.addAction(self.main_window.saveImageAction) self.menu.addAction(self.main_window.saveViewAction) self.menu.addAction(self.main_window.openAction) self.menu.addSeparator() self.menu.addMenu(self.main_window.basisMenu) self.menu.addMenu(self.main_window.colorbyMenu) self.menu.addSeparator() if domain_kind.lower() not in ('density', 'temperature'): self.menu.addAction(self.main_window.maskingAction) self.menu.addAction(self.main_window.highlightingAct) self.menu.addAction(self.main_window.overlapAct) self.menu.addSeparator() self.menu.addAction(self.main_window.dockAction) self.main_window.maskingAction.setChecked(cv.masking) self.main_window.highlightingAct.setChecked(cv.highlighting) self.main_window.overlapAct.setChecked(cv.color_overlaps) if self.main_window.dock.isVisible(): self.main_window.dockAction.setText('Hide &Dock') else: self.main_window.dockAction.setText('Show &Dock') self.menu.exec_(event.globalPos()) def generatePixmap(self, update=False): self.model.generatePlot() if update: self.updatePixmap() def updatePixmap(self): # clear out figure self.figure.clear() cv = self.model.currentView # set figure bg color to match window window_bg = self.parent.palette().color(QtGui.QPalette.Background) self.figure.patch.set_facecolor(rgb_normalize(window_bg.getRgb())) # set data extents for automatic reporting of pointer location # in model units data_bounds = [cv.origin[self.main_window.xBasis] - cv.width/2., cv.origin[self.main_window.xBasis] + cv.width/2., cv.origin[self.main_window.yBasis] - cv.height/2., cv.origin[self.main_window.yBasis] + cv.height/2.] # make sure we have a domain image to load if not hasattr(self.model, 'image'): self.model.generatePlot() ### DRAW DOMAIN IMAGE ### # still generate the domain image if the geometric # plot isn't visible so mouse-over info can still # be shown alpha = cv.domainAlpha if cv.domainVisible else 0.0 if cv.colorby in ('material', 'cell'): self.image = self.figure.subplots().imshow(self.model.image, extent=data_bounds, alpha=alpha) else: cmap = cv.colormaps[cv.colorby] if cv.colorby == 'temperature': idx = 0 cmap_label = "Temperature (K)" else: idx = 1 cmap_label = "Density (g/cc)" norm = SymLogNorm(1E-10) if cv.color_scale_log[cv.colorby] else None data = self.model.properties[:, :, idx] self.image = self.figure.subplots().imshow(data, cmap=cmap, norm=norm, extent=data_bounds, alpha=cv.domainAlpha) # add colorbar self.colorbar = self.figure.colorbar(self.image, anchor=(1.0, 0.0)) self.colorbar.set_label(cmap_label, rotation=-90, labelpad=15) # draw line on colorbar dl = self.colorbar.ax.dataLim.get_points() self.data_indicator = mlines.Line2D(dl[:][0], [0.0, 0.0], linewidth=3., color='blue', clip_on=True) self.colorbar.ax.add_line(self.data_indicator) self.colorbar.ax.margins(0.0 ,0.0) self.updateDataIndicatorVisibility() self.updateColorMinMax(cv.colorby) self.ax = self.figure.axes[0] self.ax.margins(0.0, 0.0) # set axis labels axis_label_str = "{} (cm)" self.ax.set_xlabel(axis_label_str.format(cv.basis[0])) self.ax.set_ylabel(axis_label_str.format(cv.basis[1])) # generate tally image image_data, extents, data_min, data_max, units = self.model.create_tally_image() ### DRAW TALLY IMAGE ### # draw tally image if image_data is not None: if not cv.tallyDataUserMinMax: cv.tallyDataMin = data_min cv.tallyDataMax = data_max else: data_min = cv.tallyDataMin data_max = cv.tallyDataMax # always mask out negative values image_mask = image_data < 0.0 if cv.clipTallyData: image_mask |= image_data < data_min image_mask |= image_data > data_max if cv.tallyMaskZeroValues: image_mask |= image_data == 0.0 # mask out invalid values image_data = np.ma.masked_where(image_mask, image_data) if extents is None: extents = data_bounds self.model.tally_data = image_data self.model.tally_extents = extents if extents is not None else data_bounds norm = SymLogNorm(1E-30) if cv.tallyDataLogScale else None if cv.tallyContours: # parse the levels line levels = self.parseContoursLine(cv.tallyContourLevels) self.tally_image = self.ax.contour(image_data, origin='image', levels=levels, alpha=cv.tallyDataAlpha, cmap=cv.tallyDataColormap, norm=norm, extent=extents) else: self.tally_image = self.ax.imshow(image_data, alpha=cv.tallyDataAlpha, cmap=cv.tallyDataColormap, norm=norm, extent=extents) # add colorbar self.tally_colorbar = self.figure.colorbar(self.tally_image, anchor=(1.0, 0.0)) if cv.tallyContours: fmt = "%.2E" self.ax.clabel(self.tally_image, self.tally_image.levels, inline=True, fmt=fmt) # draw line on colorbar self.tally_data_indicator = mlines.Line2D([0.0, 1.0], [0.0, 0.0], linewidth=3., color='blue', clip_on=True) self.tally_colorbar.ax.add_line(self.tally_data_indicator) self.tally_colorbar.ax.margins(0.0, 0.0) self.tally_data_indicator.set_visible(cv.tallyDataIndicator) self.main_window.updateTallyMinMax() self.tally_colorbar.mappable.set_clim(data_min, data_max) self.tally_colorbar.set_label(units, rotation=-90, labelpad=15) # annotate outlines self.add_outlines() # always make sure the data bounds are set correctly self.ax.set_xbound(data_bounds[0], data_bounds[1]) self.ax.set_ybound(data_bounds[2], data_bounds[3]) self.ax.dataLim.x0 = data_bounds[0] self.ax.dataLim.x1 = data_bounds[1] self.ax.dataLim.y0 = data_bounds[2] self.ax.dataLim.y1 = data_bounds[3] self.draw() return "Done" def add_outlines(self): cv = self.model.currentView # draw outlines as isocontours if cv.outlines: # set data extents for automatic reporting of pointer location data_bounds = [cv.origin[self.main_window.xBasis] - cv.width/2., cv.origin[self.main_window.xBasis] + cv.width/2., cv.origin[self.main_window.yBasis] - cv.height/2., cv.origin[self.main_window.yBasis] + cv.height/2.] levels = np.unique(self.model.ids) self.contours = self.ax.contour(self.model.ids, origin='upper', colors='k', linestyles='solid', levels=levels, extent=data_bounds) @staticmethod def parseContoursLine(line): # if there are any commas in the line, treat as level values line = line.strip() if ',' in line: return [float(val) for val in line.split(",") if val != ''] else: return int(line) def updateColorbarScale(self): self.updatePixmap() def updateTallyDataIndicatorValue(self, y_val): cv = self.model.currentView if not cv.tallyDataVisible or not cv.tallyDataIndicator: return if self.tally_data_indicator is not None: data = self.tally_data_indicator.get_data() # use norm to get axis value if log scale if cv.tallyDataLogScale: y_val = self.tally_image.norm(y_val) self.tally_data_indicator.set_data([data[0], [y_val, y_val]]) dl_color = invert_rgb(self.tally_image.get_cmap()(y_val), True) self.tally_data_indicator.set_c(dl_color) self.draw() def updateDataIndicatorValue(self, y_val): cv = self.model.currentView if cv.colorby not in _MODEL_PROPERTIES or \ not cv.data_indicator_enabled[cv.colorby]: return if self.data_indicator: data = self.data_indicator.get_data() # use norm to get axis value if log scale if cv.color_scale_log[cv.colorby]: y_val = self.image.norm(y_val) self.data_indicator.set_data([data[0], [y_val, y_val]]) dl_color = invert_rgb(self.image.get_cmap()(y_val), True) self.data_indicator.set_c(dl_color) self.draw() def updateDataIndicatorVisibility(self): cv = self.model.currentView if self.data_indicator and cv.colorby in _MODEL_PROPERTIES: val = cv.data_indicator_enabled[cv.colorby] self.data_indicator.set_visible(val) self.draw() def updateColorMap(self, colormap_name, property_type): if self.colorbar and property_type == self.model.activeView.colorby: self.image.set_cmap(colormap_name) self.colorbar.draw_all() self.draw() def updateColorMinMax(self, property_type): av = self.model.activeView if self.colorbar and property_type == av.colorby: clim = av.getColorLimits(property_type) self.colorbar.mappable.set_clim(*clim) self.data_indicator.set_data(clim[:2], (0.0, 0.0)) self.colorbar.draw_all() self.draw()
class MyMplCanvas(FigureCanvas): """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.).""" def __init__(self, parent=None, subplotNb=1, width=5, height=4, dpi=100): self.fig = Figure(figsize=(width, height), dpi=dpi) super(MyMplCanvas, self).__init__(self.fig) self.yAxe = numpy.array([0]) self.xAxe = numpy.array([0]) self.axes = [] if subplotNb == 1: self.axes.append(self.fig.add_subplot(111)) elif subplotNb == 2: self.axes.append(self.fig.add_subplot(211)) self.axes.append(self.fig.add_subplot(212)) elif subplotNb == 3: self.axes.append(self.fig.add_subplot(221)) self.axes.append(self.fig.add_subplot(222)) self.axes.append(self.fig.add_subplot(223)) elif subplotNb == 4: self.axes.append(self.fig.add_subplot(221)) self.axes.append(self.fig.add_subplot(222)) self.axes.append(self.fig.add_subplot(223)) self.axes.append(self.fig.add_subplot(224)) #self.axes.autoscale(False) # We want the axes cleared every time plot() is called #self.axes.hold(False) self.compute_initial_figure() # FigureCanvas.__init__(self, self.fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) def compute_initial_figure(self): pass def update_figure(self, name, data, nb_probes, lstProbes): self.xAxe = data[0].tolist() for j in range(nb_probes - 1): if (lstProbes[j].status == "on"): self.yAxe = data[j + 1].tolist() lbl = name + "_s" + str(j) self.axes[lstProbes[j].subplot_id - 1].plot(self.xAxe, self.yAxe, label=lbl) self.axes[lstProbes[j].subplot_id - 1].legend( loc="upper left", bbox_to_anchor=(1.02, 1.0), borderaxespad=0.0, ncol=1, fancybox=True, shadow=True, prop={ 'size': 'medium', 'style': 'italic' }) def update_figure_listing(self, name, data, nb_probes, lstProbes): self.xAxe = data[0].tolist() for j in range(nb_probes - 1): if (lstProbes[j].status == "on"): self.yAxe = data[j + 1].tolist() lbl = "t res. " + name[j] self.axes[lstProbes[j].subplot_id - 1].plot(self.xAxe, self.yAxe, label=lbl) self.axes[lstProbes[j].subplot_id - 1].legend( loc="upper left", bbox_to_anchor=(1.02, 1.0), borderaxespad=0.0, ncol=1, fancybox=True, shadow=True, prop={ 'size': 'medium', 'style': 'italic' }) def drawFigure(self): for it in range(len(self.axes)): self.axes[it].grid(True) self.axes[it].set_xlabel("time (s)") self.axes[0].set_yscale('log') self.fig.canvas.draw() def clear(self): for plt in range(len(self.axes)): self.axes[plt].clear() def setSubplotNumber(self, subplotNb): self.fig.clear() for it in range(len(self.axes)): self.axes.remove(self.axes[0]) if subplotNb == 1: self.axes.append(self.fig.add_subplot(111)) elif subplotNb == 2: self.axes.append(self.fig.add_subplot(211)) self.axes.append(self.fig.add_subplot(212)) elif subplotNb == 3: self.axes.append(self.fig.add_subplot(221)) self.axes.append(self.fig.add_subplot(222)) self.axes.append(self.fig.add_subplot(223)) elif subplotNb == 4: self.axes.append(self.fig.add_subplot(221)) self.axes.append(self.fig.add_subplot(222)) self.axes.append(self.fig.add_subplot(223)) self.axes.append(self.fig.add_subplot(224))
class ScatterView(BaseHierarchicalView): """ A view widget for visualizing scatterplots of data utilizing matplotlib. """ def __init__(self, mainWindow=None): """ Constructor for the Scatter plot view @ In, mainWindow, MainWindow, the main window associated to this dependent view """ BaseHierarchicalView.__init__(self, mainWindow) self.setLayout(qtw.QVBoxLayout()) layout = self.layout() self.clearLayout(layout) mySplitter = qtw.QSplitter() mySplitter.setOrientation(qtc.Qt.Vertical) layout.addWidget(mySplitter) self.fig = Figure(facecolor='white') self.mplCanvas = FigureCanvas(self.fig) self.mplCanvas.axes = self.fig.add_subplot(111) # We want the axes cleared every time plot() is called self.mplCanvas.axes.hold(False) self.colorbar = None mySplitter.addWidget(self.mplCanvas) controls = qtw.QGroupBox() controls.setLayout(qtw.QGridLayout()) subLayout = controls.layout() row = 0 col = 0 self.rightClickMenu = qtw.QMenu() self.axesLabelAction = self.rightClickMenu.addAction( 'Show Axis Labels') self.axesLabelAction.setCheckable(True) self.axesLabelAction.setChecked(True) self.axesLabelAction.triggered.connect(self.updateScene) self.cmbVars = {} for i, name in enumerate(['X', 'Y', 'Z', 'Color']): varLabel = name + ' variable:' self.cmbVars[name] = qtw.QComboBox() if name == 'Z': self.cmbVars[name].addItem('Off') elif name == 'Color': self.cmbVars[name].addItem('Cluster') dimNames = self.mainWindow.getDimensions() self.cmbVars[name].addItems(dimNames) if i < len(dimNames): self.cmbVars[name].setCurrentIndex(i) else: self.cmbVars[name].setCurrentIndex(len(dimNames) - 1) self.cmbVars[name].currentIndexChanged.connect(self.updateScene) subLayout.addWidget(qtw.QLabel(varLabel), row, col) col += 1 subLayout.addWidget(self.cmbVars[name], row, col) row += 1 col = 0 self.lblColorMaps = qtw.QLabel('Colormap') self.cmbColorMaps = qtw.QComboBox() self.cmbColorMaps.addItems(matplotlib.pyplot.colormaps()) self.cmbColorMaps.setCurrentIndex( self.cmbColorMaps.findText('coolwarm')) self.cmbColorMaps.currentIndexChanged.connect(self.updateScene) subLayout.addWidget(self.lblColorMaps, row, col) col += 1 subLayout.addWidget(self.cmbColorMaps, row, col) mySplitter.addWidget(controls) self.cmbVars['Z'].setCurrentIndex(0) self.updateScene() def sizeHint(self): """ This property holds the recommended size for the widget. If the value of this property is an invalid size, no size is recommended. The default implementation of PySide.QtGui.QWidget.sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise. (Copied from base class text) @ In, None @ Out, QSize, the recommended size of this widget """ return qtc.QSize(300, 600) def selectionChanged(self): """ An event handler triggered when the user changes the selection of the data. @ In, None @ Out, None """ self.updateScene() def updateScene(self): """ A method for drawing the scene of this view. @ In, None @ Out, None """ fontSize = 16 smallFontSize = 12 rows = self.mainWindow.getSelectedIndices() names = self.mainWindow.getDimensions() data = self.mainWindow.getData() # self.fig = Figure(facecolor='white') # self.mplCanvas = FigureCanvas(self.fig) self.fig.clear() if self.cmbVars['Z'].currentIndex() == 0: dimensionality = 2 self.mplCanvas.axes = self.fig.add_subplot(111) else: dimensionality = 3 self.mplCanvas.axes = self.fig.add_subplot(111, projection='3d') # We want the axes cleared every time plot() is called self.mplCanvas.axes.hold(False) myColormap = colors.cm.get_cmap(self.cmbColorMaps.currentText()) if len(rows) == 0: rows = list(range(data.shape[0])) allValues = {} values = {} mins = {} maxs = {} specialColorKeywords = ['Cluster'] for key, cmb in self.cmbVars.items(): if dimensionality == 2 and key == 'Z': continue if cmb.currentText() == 'Cluster': labels = self.mainWindow.getLabels() allValues[key] = np.array([ self.mainWindow.getColor(label).name() for label in labels ], dtype='|S7') values[key] = allValues[key][rows] self.lblColorMaps.setEnabled(False) self.cmbColorMaps.setEnabled(False) self.lblColorMaps.setVisible(False) self.cmbColorMaps.setVisible(False) else: col = names.index(cmb.currentText()) allValues[key] = data[:, col] mins[key] = min(allValues[key]) maxs[key] = max(allValues[key]) values[key] = allValues[key][rows] self.lblColorMaps.setEnabled(True) self.cmbColorMaps.setEnabled(True) self.lblColorMaps.setVisible(True) self.cmbColorMaps.setVisible(True) self.mplCanvas.axes.hold(True) kwargs = {'edgecolors': 'none', 'c': values['Color']} if dimensionality == 2: kwargs['x'] = values['X'] kwargs['y'] = values['Y'] else: kwargs['xs'] = values['X'] kwargs['ys'] = values['Y'] kwargs['zs'] = values['Z'] if self.cmbVars['Color'].currentText() not in specialColorKeywords: kwargs['c'] = values['Color'] kwargs['cmap'] = myColormap kwargs['vmin'] = mins['Color'] kwargs['vmax'] = maxs['Color'] myPlot = self.mplCanvas.axes.scatter(**kwargs) self.mplCanvas.axes.hold(True) if self.axesLabelAction.isChecked(): self.mplCanvas.axes.set_xlabel(self.cmbVars['X'].currentText(), size=fontSize, labelpad=10) self.mplCanvas.axes.set_ylabel(self.cmbVars['Y'].currentText(), size=fontSize, labelpad=10) if dimensionality == 3: self.mplCanvas.axes.set_zlabel(self.cmbVars['Z'].currentText(), size=fontSize, labelpad=10) ticks = np.linspace(mins['X'], maxs['X'], 5) self.mplCanvas.axes.set_xticks(ticks) self.mplCanvas.axes.set_xlim([ticks[0], ticks[-1]]) self.mplCanvas.axes.xaxis.set_ticklabels([]) self.mplCanvas.axes.yaxis.set_ticklabels([]) self.mplCanvas.axes.xaxis.set_major_formatter( matplotlib.ticker.FormatStrFormatter('%.2g')) ticks = np.linspace(mins['Y'], maxs['Y'], 5) self.mplCanvas.axes.set_yticks(ticks) self.mplCanvas.axes.set_ylim([ticks[0], ticks[-1]]) self.mplCanvas.axes.yaxis.set_major_formatter( matplotlib.ticker.FormatStrFormatter('%.2g')) if dimensionality == 3: ticks = np.linspace(mins['Z'], maxs['Z'], 3) self.mplCanvas.axes.set_zticks(ticks) self.mplCanvas.axes.set_zlim([ticks[0], ticks[-1]]) self.mplCanvas.axes.zaxis.set_major_formatter( matplotlib.ticker.FormatStrFormatter('%.2g')) for label in (self.mplCanvas.axes.get_xticklabels() + self.mplCanvas.axes.get_yticklabels()): label.set_fontsize(smallFontSize) self.mplCanvas.axes.hold(False) self.mplCanvas.draw() def test(self): """ A test function for performing operations on this class that need to be automatically tested such as simulating mouse and keyboard events, and other internal operations. For this class in particular, we will test: - Switching from 2D to a 3D projection - Changing from a color map to the cluster colors. - Toggling the axes labels on and off and displaying both. @ In, None @ Out, None """ self.cmbVars['Z'].setCurrentIndex(self.cmbVars['Z'].count() - 1) self.cmbVars['Color'].setCurrentIndex(0) self.updateScene() self.axesLabelAction.setChecked(True) self.updateScene() self.axesLabelAction.setChecked(False) self.updateScene() super(ScatterView, self).test() BaseHierarchicalView.test(self)
class MainWindow(QMainWindow): """ Главное окно """ sphere = None inspectionWindow = None additionalProjectionWindow = None clusterPointsAdjustmentsWindow = None clusters = [] selectedClusterIndexes = [] def __init__(self): super().__init__() self.circle = None self.current_data_file_name = None self.temp_data_file_name = "tempdatafile.xlsx" self.menubar = self.menuBar() self.fileMenu = self.menubar.addMenu("Файл") self.openFile = QAction('Открыть', self) self.openFile.triggered.connect(self.openFilePressed) self.fileMenu.addAction(self.openFile) self.optionsMenu = self.menubar.addMenu("Опции") self.additionalProjection = QAction("Доп. проекция", self) self.additionalProjection.triggered.connect(self.createAdditionalProjection) self.optionsMenu.addAction(self.additionalProjection) self.algorithmsMenu = self.menubar.addMenu("Алгоритмы") self.dbscanoption = QAction("Алгоритм DBScan", self) self.tsneoption = QAction("Алгоритм t-SNE", self) self.dbscanoption.triggered.connect(self.dbscanoptionChosen) self.tsneoption.triggered.connect(self.tsneoptionChosen) self.algorithmsMenu.addAction(self.dbscanoption) self.algorithmsMenu.addAction(self.tsneoption) self.algorithmsMenu.setEnabled(False) self.clopeoption = QAction("Алгоритм CLOPE", self) self.clopeoption.triggered.connect(self.clopeoptionChosen) self.algorithmsMenu.addAction(self.clopeoption) self.mainTabs = QTabWidget() self.mainTabs.setStyleSheet("QTabWidget { border: 0px solid black }; ") self.setCentralWidget(self.mainTabs) self.figure = Figure() self.additional_figure = Figure() self.matrixWidget = FigureCanvas(self.figure) self.matrixWidget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.matrixWidget.setMinimumSize(640, 480) self.matrixWidget.resize(640, 480) self.matrixScrollArea = QScrollArea() self.matrixScrollArea.setWidget(self.matrixWidget) self.matrixScrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.matrixScrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.mainTabs.addTab(self.matrixScrollArea, "Графики") self.dataWidget = QWidget() self.dataLayout = QVBoxLayout(self.dataWidget) self.dataTable = QTableWidget() self.dataLayout.addWidget(self.dataTable) self.mainTabs.addTab(self.dataWidget, "Данные") self.clustersWidget = QWidget() self.clustersLayout = QVBoxLayout(self.clustersWidget) self.clustersTable = QTableWidget() self.clustersTable.setColumnCount(6) self.clustersTable.setHorizontalHeaderLabels( ["Имя кластера", "Количество", "Маркер", "Скрыт", ""]) #self.applyToSelectedButton = QPushButton("Действия") self.clustersTable.setHorizontalHeaderItem(5, QTableWidgetItem("Действия")) self.clustersLayout.addWidget(self.clustersTable) self.mainTabs.addTab(self.clustersWidget, "Кластеры") self.setWindowTitle('Cluster Analysis 2.2') self.setWindowIcon(QIcon('icon\\app_icon.png')) self.setGeometry(100, 100, 640, 480) self.showMaximized() # self.solver = TSNESolver(self) self.temp_tsne_size = 2 # self.globalData = GlobalData() def get_additional_figure(self): return self.additional_figure def set_tsne_params_pressed(self, p, d, i): """ :param p: :param d: :param i: :return: None """ if len(self.filename) > 0: d_data = GlobalData(Utils.readExcelData(self.filename)) # d_d_data # number of cols in file initial_len = len((list(d_data).__getitem__(0))) # here we'll try to process data # get tsne columns # from initial size to new dim # reducing # print("t-SNE с параметрами") temp = TsneSolver(p, i, d, initial_len) self.temp_tsne_data = temp.reduce_dim(d_data) self.temp_tsne_size = len((list(self.temp_tsne_data).__getitem__(0))) # print("initial data", list(d_data).__getitem__(0)) # Добавление переменных t-SNE # TODO: change for i in range(0, self.temp_tsne_size): d_data.addColumns(Column("tsne_var" + str(i), self.get_temp_tsne_column(i), i + initial_len), "tsne_var" + str(i)) # print("final data", list(d_data).__getitem__(0)) newData = DataPreviewWindow.preprocessData(d_data) # вызываем диалог предобработки данных self.current_data_file_name = self.filename # put into c_d_f_n filename shutil.copy(self.current_data_file_name, self.temp_data_file_name) # copied data to temp file if newData is not None: self.startWorkingWithData(newData) def openFilePressed(self): """ Действия, выполняемые при нажатии кнопки открытия файла """ self.filename = QFileDialog.getOpenFileName(self, 'Open file', 'data')[0] d_data = GlobalData(Utils.readExcelData(self.filename)) # TODO: file opens 2 times # initial_len = len((list(d_data).__getitem__(0))) # param_win = SetTsneParams(self, initial_len) self.set_tsne_params_pressed(50.0, 2, 500) def startWorkingWithData(self, data): """ Инициализация данных в программе :param data: инициализируемые данные - это объект типа Data """ self.globalData = data self.cleanupAppData() Utils.fillTableWithData(self.dataTable, self.globalData) self.initCanvas() self.algorithmsMenu.setEnabled(True) def add_tsne_to_temp_excel(self, num): book = xlwt.Workbook(self.temp_data_file_name) sh = book.add_sheet("tsne") def canvasClicked(self, event): """ Обработчик кликов мышью по области с графиками :param event: событие-клик """ if event.inaxes is not None: ax = event.inaxes if (len(ax.lines)) != 0: self.inspectionWindow = GraphInspection.GraphInspectionWindow(self, ax) def addCluster(self, cluster): """ Добавление кластера и прочие связанные с этим действия. Для добавления нового кластера необходимо использовать эту функцию. :param cluster: добавляемый кластер - это объект типа Cluster """ self.clusters.append(cluster) self.addClusterToTable(cluster) self.refreshCanvas() # TODO: doc-string def addClusters(self, clusters): """ :param clusters: :return: """ self.clusters.extend(clusters) for cluster in clusters: self.addClusterToTable(cluster) self.refreshCanvas() def addClusterToTable(self, cluster): """ Функция, добавляющая кластер в таблицу с кластерами. Вызывается функцией addCluster :param cluster: добавляемый кластер - это объект типа Cluster """ self.clustersTable.setRowCount(self.clustersTable.rowCount() + 1) currentRowIndex = self.clustersTable.rowCount() - 1 self.clustersTable.setItem(currentRowIndex, 0, QTableWidgetItem(cluster.getName())) self.clustersTable.setItem(currentRowIndex, 1, QTableWidgetItem(str(cluster.getSize()))) figure = Figure() markerShapeCell = FigureCanvas(figure) markerShapeCell.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) axes = figure.add_subplot(111) axes.axis("off") markerSize = 8 axes.plot([1], [1], linestyle="None", marker=cluster.getShape(), color=cluster.getColor(), markersize=markerSize) markerShapeCell.draw() self.clustersTable.setCellWidget(currentRowIndex, 2, markerShapeCell) if cluster.isHidden(): self.clustersTable.setItem(currentRowIndex, 3, QTableWidgetItem("Да")) else: self.clustersTable.setItem(currentRowIndex, 3, QTableWidgetItem("Нет")) clusterOptionsButton = QPushButton("Опции") clusterOptionsMenu = QMenu() self.clustersTable.setCellWidget(currentRowIndex, 4, clusterOptionsButton) index = QPersistentModelIndex(self.clustersTable.model().index(currentRowIndex, 4)) adjustClusterPointsAction = QAction("Просмотр точек", self) adjustClusterPointsAction.triggered.connect( lambda *args, index=index: self.adjustClusterPoints(index.row())) clusterOptionsMenu.addAction(adjustClusterPointsAction) adjustClusterAction = QAction("Визуализация кластера", self) adjustClusterAction.triggered.connect( lambda *args, index=index: self.adjustCluster(index.row())) clusterOptionsMenu.addAction(adjustClusterAction) hideorshowClusterAction = QAction("Скрыть/показать кластер", self) hideorshowClusterAction.triggered.connect( lambda *args, index=index: self.hideorshowCluster(index.row())) clusterOptionsMenu.addAction(hideorshowClusterAction) removeClusterAction = QAction("Удалить кластер", self) removeClusterAction.triggered.connect( lambda *args, index=index: self.removeCluster(index.row())) clusterOptionsMenu.addAction(removeClusterAction) clusterOptionsButton.setMenu(clusterOptionsMenu) checkboxcontainer = QWidget() checkboxcontainer.setStyleSheet("background-color:#cccccc;") containerlayout = QVBoxLayout(checkboxcontainer) containerlayout.setAlignment(Qt.AlignCenter) clusterSelectCheckBox = QCheckBox() containerlayout.addWidget(clusterSelectCheckBox) clusterSelectCheckBox.stateChanged.connect( lambda *args, index=index, state=clusterSelectCheckBox.isChecked(): self.clusterSelect(index, state) ) self.clustersTable.setCellWidget(currentRowIndex, 5, checkboxcontainer) def clusterSelect(self, index, state): if not state: self.selectedClusterIndexes.append(index) else: self.selectedClusterIndexes.remove(index) def adjustCluster(self, index): """ Вызывает диалог, измеяющий косметические параметры кластера :param index: индекс изменяемого кластера в массиве кластеров :return: """ cluster = ClusterDialog.adjustCluster(self.clusters[index]) if cluster is not None: self.clusters[index] = cluster # TODO: вместо обновления всей таблицы, обновлять только строку этого кластера refreshRow self.refreshClusterTable() # TODO: и перерисовывать только его точки self.refreshCanvas() def hideorshowCluster(self, index): """ Изменяет свойство видимости кластера и рендерит изменения. :param index: индекс изменяемого кластера в массиве кластеров """ self.clusters[index].setHidden(not self.clusters[index].isHidden()) self.refreshCanvas() self.refreshClusterTable() def removeCluster(self, index): """ Удаляет кластер из программы и рендерит изменения :param index: индекс удаляемого кластера в массиве кластеров """ del self.clusters[index] self.clustersTable.removeRow(index) self.refreshCanvas() def adjustClusterPoints(self, index): """ Вызывает окно, позволяющее детально рассмотреть список точек в кластере. :param index: """ self.clusterPointsAdjustmentsWindow = ClusterPointsView(self, self.clusters[index]) def initCanvas(self): """ Служебная (вспомогательная) функция, инициализирующая канвас с графиками. Вызывается функцией startWorkingWithData """ columns = self.globalData.getSignificantColumns() # globalData.addRow() columnCount = self.globalData.significantColumnCount() self.matrixWidget.resize((columnCount+self.temp_tsne_size+1) * 200, (columnCount+self.temp_tsne_size)* 200) for j in range(0, columnCount): for i in range(0, columnCount): columnForAbscissas = columns[i] columnForOrdinates = columns[j] axes = self.figure.add_subplot(columnCount, columnCount, j * columnCount + i + 1) axes.scatterMatrixXIndex = columnForAbscissas.getIndex() axes.scatterMatrixYIndex = columnForOrdinates.getIndex() if columnForAbscissas == columnForOrdinates: axes.hist(columnForAbscissas, facecolor=Constants.DEFAULT_HISTOGRAM_COLOR) axes.set_title("гистограмма " + columnForOrdinates.getName()) else: axes.plot(columnForAbscissas, columnForOrdinates, marker=Constants.DEFAULT_POINT_SHAPE, linestyle="None", markersize=Constants.DEFAULT_MARKER_SIZE_SMALL, color=Constants.DEFAULT_POINT_COLOR) axes.set_title(columnForOrdinates.getName() + "_" + columnForAbscissas.getName()) self.matrixWidget.mpl_connect('button_press_event', self.canvasClicked) self.figure.tight_layout() self.matrixWidget.draw() self.matrixScrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.matrixScrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) def get_temp_tsne_column(self, column_number): temp_list = list() for i in range(0,len(self.temp_tsne_data)): temp_list.append(list(self.temp_tsne_data).__getitem__(i).__getitem__(column_number)) return temp_list def drop_nan_values(self, array): result = copy.deepcopy(array) for i in range(0,list(result).__len__()): result[i] = float(result[i]) if math.isnan(result[i]): del result[i] def refreshCanvas(self): """ Полное обновление изображения. Очищает канвас и отрисовывает все заново. """ columnCount = self.globalData.significantColumnCount() columns = self.globalData.getSignificantColumns() for i in range(0, columnCount): for j in range(0, columnCount): if i != j: columnForAbscissas = columns[i] columnForOrdinates = columns[j] axes = self.figure.add_subplot(columnCount, columnCount, j * columnCount + i + 1) while len(axes.lines) > 0: del axes.lines[-1] axes.cla() axes.add_line(Utils.getSupportiveLine(self.globalData.getSignificantColumns(), i, j)) for cluster in self.clusters: cluster.draw2DProjection(axes, columns[i].getIndex(), columns[j].getIndex(), Constants.DEFAULT_MARKER_SIZE_BIG) dummyCluster = self.globalData.getDummyCluster(self.clusters) dummyCluster.draw2DProjection(axes, columns[i].getIndex(), columns[j].getIndex(), Constants.DEFAULT_MARKER_SIZE_SMALL) # dAnGeR ZoNe axes.set_title(columnForOrdinates.getName() + "_" + columnForAbscissas.getName()) if self.sphere is not None: point = self.sphere[0].getProjection(i, j) self.circle = plt.Circle((point.getX(), point.getY()), self.sphere[1], color='green', fill=False) axes.add_artist(self.circle) self.matrixWidget.draw() def refreshClusterTable(self): """ Полное обновление таблицы кластеров. Удаляет все строки и создает их заново. """ self.clustersTable.setRowCount(0) for cluster in self.clusters: self.addClusterToTable(cluster) def cleanupAppData(self): """ Полностью удаляет все данные из программы. Используется функцией startWorkingWithData перед загрузкой нового файла с данными. """ self.clustersTable.setRowCount(0) self.clusters.clear() self.figure.clear() def createAdditionalProjection(self): self.additionalProjectionWindow = AdditionalProjectionWindow(self) def dbscanoptionChosen(self): """ Вызывает окно алгоритма DBScan """ self.dbscanwindow = DBScanWindow(self) def tsneoptionChosen(self): """ Вызов окна алгоритма t-SNE """ self.tsnewindow = TSNEWindow(self) def clopeoptionChosen(self): """ Вызов окна алгоритма CLOPE """ self.clopewindow = CLOPEWindow(self)
class GUI(QDialog): """GUI class.""" def __init__(self): """GUI definition.""" super(GUI, self).__init__() self.setWindowTitle("Haar Editor - " + args.create) # self.setGeometry(200, 200, 800, 700) self.haarPath = os.getcwd() + '/' + args.create self.scalePercent = 50 self.objets() self.layout() def objets(self): """Define visual objets to place in GUI.""" # Création de la zone de texte fichier self.filePath = QLineEdit('/home/fabouzz/Cours/Projet_CMI_bille/mesuresBille/test_cam6') # Crétion du bouton chargement self.load = QPushButton("Load video") self.load.clicked.connect(self.Load) # Création du bouton addNeg self.addNeg = QPushButton('Add neg frames') self.addNeg.clicked.connect(self.addNegSample) self.negSlice = QLineEdit('Start:End') # Création du bouton addPos self.addPos = QPushButton('Add pos frames') self.addPos.clicked.connect(self.addPosSample) self.posSlice = QLineEdit('Start:End') # Création du bouton Anotate vec file self.anotateVec = QPushButton('Anotate Vec file') self.anotateVec.clicked.connect(self.anotateVecFile) # Création du bouton train cascade self.trainButton = QPushButton('Train cascade') self.trainButton.clicked.connect(self.trainCascade) # Figure contenant l'image de la vidéo self.figVid = Figure(dpi=100, tight_layout=True) self.Canvas = FigureCanvas(self.figVid) # Crétion du slider self.Slider = QSlider(Qt.Horizontal) self.Slider.setMinimum(1) self.Slider.setMaximum(100) self.Slider.setTickInterval(1) self.Slider.setValue(0) self.Slider.valueChanged.connect(self.sliderUpdate) # Création du label self.statusLabel = QLabel(self) self.statusLabel.setText('Wilkommen, please load a video file before adding samples') def layout(self): """GUI layout using previous objets.""" MainLayout = QVBoxLayout() LoadLayout = QHBoxLayout() LoadLayout.addWidget(self.load) LoadLayout.addWidget(self.filePath) AddLayout = QHBoxLayout() AddLayout.addWidget(self.addPos) AddLayout.addWidget(self.posSlice) AddLayout.addWidget(self.addNeg) AddLayout.addWidget(self.negSlice) VidLayout = QHBoxLayout() VidLayout.addWidget(self.Canvas) BottomLayout = QHBoxLayout() BottomLayout.addWidget(self.statusLabel) BottomLayout.addWidget(self.anotateVec) BottomLayout.addWidget(self.trainButton) MainLayout.addLayout(LoadLayout) # MainLayout.addLayout(NegLayout) MainLayout.addLayout(AddLayout) MainLayout.addLayout(VidLayout) MainLayout.addWidget(self.Slider) MainLayout.addLayout(BottomLayout) self.setLayout(MainLayout) def sliderUpdate(self): """Update the bottom screen slider. Updates data.""" self.plot(pos=self.Slider.value()) # print(self.Slider.value()) def keyPressEvent(self, event): """Keyboard navigation.""" if event.key() == Qt.Key_Right: self.slider.setValue(self.slider.value() + 1) elif event.key() == Qt.Key_Left: self.slider.setValue(self.slider.value() - 1) else: # Eviter le crash de l'interface dans le cas d'un spam de touche try: self.keyPressEvent(self, event) except TypeError: pass def Load(self): """.""" fileName = self.filePath.text() self.cvVideo = cv2.VideoCapture(fileName + '.avi') # Chargement video with open(fileName + '.cih') as file: lines = file.readlines() for line in lines: if line.startswith('Total Frame :'): self.nFrames = int(line.split(' : ')[1]) if line.startswith('Image Width : '): self.imWidth = int(line.split(' : ')[1]) if line.startswith('Image Height :'): self.imHeight = int(line.split(': ')[1]) self.Slider.setMaximum(self.nFrames) self.plot() self.statusLabel.clear() self.statusLabel.setText('Loaded video {}.avi'.format(fileName.split('/')[-1])) def plot(self, pos=0): """.""" self.cvVideo.set(cv2.CAP_PROP_POS_FRAMES, self.Slider.value()) ret, self.frame = self.cvVideo.read() self.figVid.clear() ax = self.figVid.add_subplot(111) ax.set_title('Frame n° : ' + str(self.Slider.value())) ax.imshow(self.frame) ax.set_xticks([]) ax.set_yticks([]) self.Canvas.draw() def addNegSample(self): """.""" slice = self.negSlice.text() path = self.filePath.text() fileName = path.split('/')[-1] cap = cv2.VideoCapture(path + '.avi') # fgbg = cv2.createBackgroundSubtractorKNN() count = int(slice.split(':')[0]) with open(self.haarPath + '/bg.txt', "a") as writer: while count <= int(slice.split(':')[-1]): cap.set(cv2.CAP_PROP_POS_FRAMES, count) ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # fgmask = fgbg.apply(gray) # thresh = cv2.threshold(fgmask, 17, 255, cv2.THRESH_BINARY_INV)[-1] # width = int(gray.shape[1] * self.scalePercent / 100) # height = int(gray.shape[0] * self.scalePercent / 100) # dim = (width, height) # # resize image # resized = cv2.resize(gray, dim, interpolation=cv2.INTER_AREA) cv2.imwrite(self.haarPath + '/neg/{}_{}.png'.format(fileName, count), gray) count += 1 writer.write('{}/neg/{}_{}.png\n'.format(self.haarPath, fileName, count - 1)) self.statusLabel.clear() self.statusLabel.setText('Added {} neg frames'.format(int(slice.split(':')[-1]) - int(slice.split(':')[0]) + 1)) def addPosSample(self): """.""" slice = self.posSlice.text() path = self.filePath.text() fileName = path.split('/')[-1] cap = cv2.VideoCapture(path + '.avi') # fgbg = cv2.createBackgroundSubtractorKNN() count = int(slice.split(':')[0]) while count <= int(slice.split(':')[-1]): cap.set(cv2.CAP_PROP_POS_FRAMES, count) ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # fgmask = fgbg.apply(gray) # thresh = cv2.threshold(fgmask, 17, 255, cv2.THRESH_BINARY_INV)[-1] # width = int(gray.shape[1] * self.scalePercent / 100) # height = int(gray.shape[0] * self.scalePercent / 100) # dim = (width, height) # # resize image # resized = cv2.resize(gray, dim, interpolation=cv2.INTER_AREA) cv2.imwrite(self.haarPath + '/pos/{}_{}.png'.format(fileName, count), gray) count += 1 self.statusLabel.clear() self.statusLabel.setText('Added {} pos frames'.format(int(slice.split(':')[-1]) - int(slice.split(':')[0]) + 1)) def anotateVecFile(self): """.""" os.system('opencv_annotation -a={0}/annotations.vec -i={0}/pos/ ----maxWindowHeight=300 --resizeFactor=0.25'.format(self.haarPath)) def trainCascade(self): """.""" data = self.haarPath vecFile = data + '/annotations.vec' bgFile = data + '/bg.txt' numPos = len(os.listdir(data + '/pos/')) numNeg = len(os.listdir(data + '/neg/')) numStages = '10' minHitRate = '0.999' maxFalseAlarmRate = '0.5' width = self.imWidth height = self.imHeight os.system('opencv_traincascade -data {} -vec {} -bg {} -numPos {} -numNeg {} -numStages {} -minHitRate {} -maxFalseAlarmRate {} -featureType HAAR -w {} -h {}'.format(data, vecFile, bgFile, numPos, numNeg, numStages, minHitRate, maxFalseAlarmRate, width, height))
def hopfield(): read = read_data(url) finaldata = preprocessing(read) matrix_size = len(finaldata[0]) column_amount = int(matrix_size / row_amount) matrix_sum = np.zeros((matrix_size, matrix_size)) testno = int(entry_test_no.get()) - 1 fig_train = Figure(figsize=(5, 5)) fig_train.clear() reshape_train_data = finaldata[testno].reshape(row_amount, column_amount) axes = fig_train.add_subplot(2, 1, 1) axes.set_title("train_figure_original", pad=20) caxes = axes.matshow(reshape_train_data) fig_train.colorbar(caxes) if filename == "Basic_Training": for i in range(data_amount): randomlist = [] for j in range(0, 10): n = random.randint(0, matrix_size - 1) randomlist.append(n) for randno in randomlist: if finaldata[i][randno] == -1: finaldata[i][randno] = 1 else: finaldata[i][randno] = -1 reshape_train_data = finaldata[testno].reshape(row_amount, column_amount) axes = fig_train.add_subplot(2, 1, 2) axes.set_title("train_figure_noise", pad=20) caxes = axes.matshow(reshape_train_data) fig_train.colorbar(caxes) fig_train.tight_layout() canvas = FigureCanvasTkAgg(fig_train, window) canvas.get_tk_widget().place(x=550, y=100) canvas.draw() for i in range(data_amount): expand_dim_matrix = np.expand_dims(finaldata[i], axis=0) matrix_dot = (expand_dim_matrix.T).dot(expand_dim_matrix) matrix_sum = np.add(matrix_sum, matrix_dot) I = np.identity(matrix_size) I = I * (data_amount / matrix_size) matrix_sum = matrix_sum * (1 / matrix_size) W = np.subtract(matrix_sum, I) theta = np.sum(W, axis=0) read = read_data(url_test) test_data = preprocessing(read) test_data = np.expand_dims(test_data[testno], axis=0) fig = Figure(figsize=(7, 7)) for count in range(1): subplot_no = 1 fig.clear() bonus_list = [] for i in range(matrix_size): output = (W[i].dot(test_data.T)) - theta[i] if filename == "Basic_Training": if output > 0: test_data[0][i] = 1 elif output < 0: test_data[0][i] = -1 else: if output > 0: bonus_list.append(1) elif output < 0: bonus_list.append(-1) if filename == "Basic_Training": if i % 14 == 0 or i == 107: reshape_test_data = test_data.reshape( row_amount, column_amount) axes = fig.add_subplot(3, 3, subplot_no) axes.set_title("iteration" + str(i + 1), pad=20) caxes = axes.matshow(reshape_test_data) fig.colorbar(caxes) subplot_no += 1 if filename == "Bonus_Training": bonus_list = np.array(bonus_list) bonus_list = np.expand_dims(bonus_list, axis=0) test_data = bonus_list reshape_test_data = bonus_list.reshape(row_amount, column_amount) axes = fig.add_subplot(1, 1, 1) caxes = axes.matshow(reshape_test_data) fig.colorbar(caxes) fig.tight_layout() canvas = FigureCanvasTkAgg(fig, window) canvas.get_tk_widget().place(x=0, y=100) canvas.draw()
class QPyMcaMatplotlibSave(FigureCanvas): def __init__(self, parent=None, size=(7, 3.5), dpi=100, logx=False, logy=False, legends=True, bw=False): self.fig = Figure(figsize=size, dpi=dpi) #in inches FigureCanvas.__init__(self, self.fig) FigureCanvas.setSizePolicy(self, qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.curveTable = None self.dpi = dpi ddict = {'logx': logx, 'logy': logy, 'legends': legends, 'bw': bw} self.ax = None self.curveList = [] self.curveDict = {} self.setParameters(ddict) #self.setBlackAndWhiteEnabled(bw) #self.setLogXEnabled(logx) #self.setLogYEnabled(logy) #self.setLegendsEnabled(legends) self.xmin = None self.xmax = None self.ymin = None self.ymax = None self.limitsSet = False def setCurveTable(self, table): self.curveTable = table self.curveTable.sigCurveTableSignal.connect(self.updateFromTable) def setParameters(self, kw): if 'bw' in kw: self.setBlackAndWhiteEnabled(kw['bw']) if 'logx' in kw: self.setLogXEnabled(kw['logx']) if 'logy' in kw: self.setLogYEnabled(kw['logy']) if 'legends' in kw: self.setLegendsEnabled(kw['legends']) self._dataCounter = 0 self.createAxes() def setBlackAndWhiteEnabled(self, flag): self._bw = flag if self._bw: self.colorList = ['k'] #only black self.styleList = ['-', ':', '-.', '--'] self.nColors = 1 else: self.colorList = colorlist self.styleList = ['-', '-.', ':'] self.nColors = len(colorlist) self._dataCounter = 0 self.nStyles = len(self.styleList) self.colorIndex = 0 self.styleIndex = 0 def setLogXEnabled(self, flag): self._logX = flag def setLogYEnabled(self, flag): self._logY = flag def setLegendsEnabled(self, flag): self._legend = flag self._legendList = [] def createAxes(self): self.fig.clear() if self.ax is not None: self.ax.cla() if not self._legend: if self._logY: ax = self.fig.add_axes([.15, .15, .75, .8]) else: ax = self.fig.add_axes([.15, .15, .75, .75]) else: if self._logY: ax = self.fig.add_axes([.15, .15, .7, .8]) else: ax = self.fig.add_axes([.15, .15, .7, .8]) ax.set_axisbelow(True) self.ax = ax if self._logY: self._axFunction = ax.semilogy else: self._axFunction = ax.plot self._legendList = [] self.curveList = [] self.curveDict = {} def setLimits(self, xmin, xmax, ymin, ymax): self.xmin = xmin self.xmax = xmax self.ymin = ymin self.ymax = ymax self.limitsSet = True def _filterData(self, x, y): index = numpy.flatnonzero((self.xmin <= x) & (x <= self.xmax)&\ (self.ymin <= y) & (y <= self.ymax)) return index def _getColorAndStyle(self): color = self.colorList[self.colorIndex] style = self.styleList[self.styleIndex] self.colorIndex += 1 if self.colorIndex >= self.nColors: self.colorIndex = 0 self.styleIndex += 1 if self.styleIndex >= self.nStyles: self.styleIndex = 0 return color, style def addDataToPlot(self, x, y, legend=None, color=None, linewidth=None, linestyle=None, marker=None, alias=None, **kw): if self.limitsSet is not None: n = self._filterData(x, y) if not len(n): return #x = x[n] #y = y[n] n = max(x.shape) if n == 0: #nothing to plot _logger.debug("nothing to plot") return style = None if color is None: color, style = self._getColorAndStyle() if linestyle is None: if style is None: style = '-' else: style = linestyle if marker is None: marker = '' if linewidth is None: linewidth = 1.0 self._axFunction(x, y, linestyle=style, color=color, linewidth=linewidth, **kw) self._dataCounter += 1 if legend is None: #legend = "%02d" % self._dataCounter #01, 02, 03, ... legend = "%c" % (96 + self._dataCounter) #a, b, c, .. self._legendList.append(legend) if legend not in self.curveList: self.curveList.append(legend) self.curveDict[legend] = {} self.curveDict[legend]['x'] = x self.curveDict[legend]['y'] = y self.curveDict[legend]['linestyle'] = style self.curveDict[legend]['color'] = color self.curveDict[legend]['linewidth'] = linewidth self.curveDict[legend]['linemarker'] = marker if alias is not None: self.curveDict[legend]['alias'] = alias self._legendList[-1] = alias if self.curveTable is not None: self.curveTable.setCurveListAndDict(self.curveList, self.curveDict) def setXLabel(self, label): self.ax.set_xlabel(label) def setYLabel(self, label): self.ax.set_ylabel(label) def setTitle(self, title): self.ax.set_title(title) def plotLegends(self, legendlist=None): if not self._legend: return if legendlist is None: legendlist = self._legendList if not len(legendlist): return loc = (1.01, 0.0) labelsep = 0.015 drawframe = True fontproperties = FontProperties(size=10) if len(legendlist) > 14: drawframe = False if matplotlib_version < '0.99.0': fontproperties = FontProperties(size=8) loc = (1.05, -0.2) else: if len(legendlist) < 18: #drawframe = True loc = (1.01, 0.0) elif len(legendlist) < 25: loc = (1.05, 0.0) fontproperties = FontProperties(size=8) elif len(legendlist) < 28: loc = (1.05, 0.0) fontproperties = FontProperties(size=6) else: loc = (1.05, -0.1) fontproperties = FontProperties(size=6) if matplotlib_version < '0.99.0': legend = self.ax.legend(legendlist, loc=loc, prop=fontproperties, labelsep=labelsep, pad=0.15) else: legend = self.ax.legend(legendlist, loc=loc, prop=fontproperties, labelspacing=labelsep, borderpad=0.15) legend.draw_frame(drawframe) def draw(self): if self.limitsSet: self.ax.set_xlim(self.xmin, self.xmax) self.ax.set_ylim(self.ymin, self.ymax) FigureCanvas.draw(self) def updateFromTable(self, ddict): #for line2D in self.ax.lines: # #label = line2D.get_label() # #if label == legend: # line2D.remove() xlabel = self.ax.get_xlabel() ylabel = self.ax.get_ylabel() if self.limitsSet: xlim = self.ax.get_xlim() ylim = self.ax.get_ylim() self.ax.cla() self.ax.set_xlabel(xlabel) self.ax.set_ylabel(ylabel) if self.limitsSet: self.ax.set_xlim(xlim) self.ax.set_ylim(ylim) legendList = [] curvelist = ddict['curvelist'] for legend in curvelist: if not ddict['curvedict'][legend]['plot']: continue x = self.curveDict[legend]['x'] y = self.curveDict[legend]['y'] alias = ddict['curvedict'][legend]['alias'] linestyle = self.curveDict[legend]['linestyle'] if 0: color = self.curveDict[legend]['color'] else: color = ddict['curvedict'][legend]['color'] linewidth = self.curveDict[legend]['linewidth'] linestyle = ddict['curvedict'][legend]['linestyle'] linemarker = ddict['curvedict'][legend]['linemarker'] if linestyle in ['None', '']: linestyle = '' if linemarker in ['None', '']: linemarker = '' self._axFunction(x, y, linestyle=linestyle, marker=linemarker, color=color, linewidth=linewidth) legendList.append(alias) if self._legend: self.plotLegends(legendList) self.draw() def saveFile(self, filename, format=None): if format is None: format = filename[-3:] if format.upper() not in ['EPS', 'PNG', 'SVG']: raise "Unknown format %s" % format if os.path.exists(filename): os.remove(filename) if self.limitsSet: self.ax.set_ylim(self.ymin, self.ymax) self.ax.set_xlim(self.xmin, self.xmax) #self.plotLegends() self.print_figure(filename, dpi=self.dpi) return
class MinimalPlotControl(OutputControlBase): """Represents a vector output in one line - double clicking on graph opens a large static graph window - opening a canvas and dragging into window set up dynamic plot window""" def __init__(self, parent, fgs, port, aui_notebook, manager, app): super().__init__(port, "PlotControl(%s)" % port.name) self.port = port self.aui_notebook = aui_notebook self.manager = manager self.app = app self.parent = parent self.fig = Figure((5, 0.8), 75) self.canvas = FigureCanvas(parent, -1, self.fig) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.canvas, 7, wx.ALIGN_CENTRE | wx.LEFT) fgs.Add(sizer, 0, wx.TOP | wx.EXPAND) # handlers self.canvas.mpl_connect("axes_enter_event", self.enter_axes) self.canvas.mpl_connect("axes_leave_event", self.leave_axes) self.canvas.mpl_connect("button_press_event", self.OnDrag) self.canvas.mpl_connect("button_release_event", self.OnDrag) self.evaluate() def enter_axes(self, event): event.inaxes.patch.set_facecolor("lightgrey") event.canvas.draw() def leave_axes(self, event): event.inaxes.patch.set_facecolor("white") event.canvas.draw() def OnDrag(self, e): if e.dblclick: self.plot_stack = FigureStack(self.port) else: self.dragged = self.port my_data = wx.TextDataObject(str(self.port.get_path())) dragsource = wx.DropSource(self.canvas) dragsource.SetData(my_data) result = dragsource.DoDragDrop(True) def OnDropInit(self, event): for key, item in self.app.canvas_dict.items(): self.app.canvas_dict[key].DisplayData(self.dragged) def evaluate(self): self.fig.clear() a = self.fig.add_subplot(111) colors = [ "blue", "black", "brown", "red", "green", "orange", "turquoise", "pink", "blue", "black", "red", "green", "orange", "pink", "purple", "black", "red", "blue", "blue", "black", "brown", "red", "yellow", "green", "orange", "blue", "black", "brown", "red", "yellow", "green", "orange", "turquoise", "pink", "blue", "black", "red", "green", "orange", "pink", "purple", "black", "red", "blue", "blue", "black", "brown", "red", "yellow", "green", "orange", "blue", "black", "brown", "red", "yellow", "green", "orange", "turquoise", "pink", "blue", "black", "red", "green", "orange", "pink", "purple", "black", "red", "blue", "blue", "black", "brown", "red", "yellow", "green", "orange", ] x = np.array(self.port.read()["data"][0]) y = np.array(self.port.read()["data"][1]) lines = np.array(self.port.read()["data"][2]) lbl = list(self.port.read()["label"]) if x.ndim and y.ndim == 1: try: for line in lines: if line: self.canvas.lines = a.axvline(line, 0, 1) except: pass self.canvas.lines = a.plot(x, y, color=colors[0], label=lbl) if x.ndim and y.ndim == 2: count = 0 for xi, yi, label in zip(x, y, lbl): count = count + 1 if lines.any(): for line in lines: if line: self.canvas.lines = a.axvline(line, 0, 1) else: pass self.canvas.lines = a.plot(xi, yi, color=colors[count], label=label) if x.ndim == 3: print("3d") # else: # if x.ndim == 1: # self.canvas.lines = a.plot(x, y, color=colors[0], label=lbl) # elif x.ndim == 2: # print("2d") # if y is not None and len(y.shape) >= 1: # print("plot") # count = 0 # # for x_axis, y_axis, label in zip(x, y, lbl): # try: # for line in lines: # self.canvas.lines = a.axvline(line, 0, 1) # except: # pass # self.canvas.lines = a.plot( # x_axis, y_axis, color=colors[count], label=label # ) # count = count + 1 # else: # self.lines = a.plot(x, y, "k", label=lbl) # self.lines = None # a.legend() self.fig.canvas.draw() a.legend() for key, item in self.app.canvas_dict.items(): self.app.canvas_dict[key].evaluate()
button2.grid(row=7, column=1, padx=10, pady=10) button3 = tk.Button(left_frame, text='Analyze', width=30, command=b3CallBack, highlightbackground='#3E4149') button3.grid(row=9, column=1, padx=10, pady=10) button4 = tk.Button(left_frame, text='Map', width=30, command=b4CallBack, highlightbackground='#3E4149') button4.grid(row=11, column=1, padx=10, pady=10) fig = Figure(figsize=(7, 7)) fig.clear() a = fig.add_subplot(111) canvas = FigureCanvasTkAgg(fig, master=c) canvas.get_tk_widget().pack() scrollable_frame = ScrollableFrame(c) label = tk.Label(left_frame, text='Status:', fg='white', bg='grey') label.grid(row=14, column=1, padx=10, pady=10) label2 = tk.Label(left_frame, text='Pending...', bg='yellow', width=30, height=3) label2.grid(row=15, column=1, pady=5)
class SpecViewer(ttk.Frame): """Display a spectrum corresponding to some spatial region. This uses Matplotlib, and the actual plotting is controlled by the `plot_spectrum` method. Args: parent: The parent tkinter widget. wave: The array of wavelengths. data: The data cube -- a dictionary of them! figsize: The size of the Matplotlib figure to produce.""" def __init__(self, parent, wave, data_cube, pixels, figsize=(12,4)): super().__init__(parent) self.wave = wave self.data_cube = data_cube # TO DO: fix underlying data in pixels and remove correct function #self.pixels = correct_pixels(pixels) self.pixels = pixels self.fig = Figure(figsize=figsize) self.canvas = FigureCanvasTkAgg(self.fig, master=self) self.canvas.draw() self.canvas.get_tk_widget().grid(row=0, column=0) toolbarFrame = ttk.Frame(master=self) toolbarFrame.grid(row=0,column=0, sticky='sw') self.toolbar = NavigationToolbar2Tk(self.canvas, toolbarFrame) self.toolbar.update() #self.toolbar.grid(row=0, column=0) self.status = tk.StringVar() self.statusbar = ttk.Label(self, textvariable=self.status, relief=tk.SUNKEN, anchor=tk.E) self.statusbar.grid(row=1,column=0, sticky='we') self.clearbutton = tk.Button(parent, text='Clear Plot', command=self.clear_plot) self.clearbutton.grid(row=1, column=1, sticky='nw') self.savebutton = tk.Button(parent, text='Save Plot', command=self.save_plot) self.savebutton.grid(row=1, column=1, sticky='nw', pady=40) # Widget to scale the intensity w1 = tk.Entry(parent, text="Lambda 1: ") w2 = tk.Entry(parent, text="Lambda 2: ") w1.grid(row=0, column=1, sticky='nw', pady=40) w2.grid(row=0, column=1, sticky='nw', pady=80) self.scaleintbutton = tk.Button(parent, text='Scale Spectra', command = lambda: self.scale_pixels(w1.get(), w2.get())) self.scaleintbutton.grid(row=0, column=1, sticky='nw', pady=120) def clear_plot(self): self.fig.clear() self.canvas.draw() def save_plot(self): t = time.time() filenm = str(data_dir)+'/plots/plot_'+str(t)+'.png' self.fig.savefig(filenm) def match_pixels(self, coords): matches = [] for p in self.pixels: if coords.within_region(p.lons[0], p.lats[0]) and coords.within_region(p.lons[1], p.lats[1]): matches.append(p) if not matches: print("No matches found :(") return matches def scale_pixels(self, wave1, wave2): """ Scale pixel values.""" wave1, wave2 = float(wave1), float(wave2) print(wave1, wave2) if wave1 is None: for p in self.pixels: p.scaled_intensity = copy(p.intensity) else: #scale based on wave values waves = copy(self.pixels[0].wave) idx1 = np.argmin(np.abs(waves - wave1)) idx2 = np.argmin(np.abs(waves - wave2)) w1val = np.mean([p.intensity[idx1] for p in pixels]) w2val = np.mean([p.intensity[idx2] for p in pixels]) for p in self.pixels: scale = (w2val-w1val)/(p.intensity[idx2]-p.intensity[idx1]) p.scaled_intensity = p.intensity*(scale) sub = w1val - p.scaled_intensity[idx1] p.scaled_intensity = p.scaled_intensity + sub def plot_spectrum(self, coords): """Plot the spectrum associated to a specified lat/lon region. This assumes that the region is rectangular (in the projection), and that we are provided the upper left and lower right coordinates of the rectangle. Args: lat1: The latitude of the upper-left corner. lon1: The longitude of the upper-left corner. lat2: The latitude of the lower-right corner. lon2: The longitude of the lower-right corner. """ ax = self.fig.add_subplot() ax.set_ylabel("Albedo", fontsize=16) ax.set_xlabel("Wavelength (microns)", fontsize=16) #Plot relevant spectra! matches = self.match_pixels(coords) if len(matches) == 1: ax.plot(self.wave[100:-80], matches[0].intensity[100:-80], label=f'{coords.lon1W:.2f}:{coords.lon2W:.2f}$^\circ W$, {coords.lat1:.2f}:{coords.lat2:.2f}$^\circ$ N') elif len(matches) > 1: # Median combine if multiple data pixels pixdata = [m.scaled_intensity[100:-80] for m in matches] #np.set_printoptions(threshold=np.inf) #print([m.count() for m in pixdata]) # TO DO: actually bin spatial pixels binned = np.nanmedian(pixdata, axis=0) ax.plot(self.wave[100:-80], binned, label=f'{coords.lon1W:.2f}:{coords.lon2W:.2f}$^\circ W$, {coords.lat1:.2f}:{coords.lat2:.2f}$^\circ$ N') self.fig.subplots_adjust(bottom=0.15, right=0.7) ax.legend(bbox_to_anchor=(1.5, 1), fontsize=10) if ax.get_ylim()[0] < 0: ax.set_ylim(0, ax.get_ylim()[1]) if ax.get_ylim()[1] > 0.6: ax.set_ylim(ax.get_ylim()[0], 0.6) #ax.set_ylim(0, 0.6) # helpful: print the region in the statusbar self.status.set(f"selection ({coords.lat1:.3f},{coords.lon1W:.3f}) to ({coords.lat2:.3f},{coords.lon2W:.3f})") self.canvas.draw()
class Qt4MplCanvas(FigureCanvas): """ A customized Qt widget for matplotlib figure. It can be used to replace GraphicsView of QtGui """ def __init__(self, parent): """ Initialization """ # from mpl_toolkits.axes_grid1 import host_subplot # import mpl_toolkits.axisartist as AA # import matplotlib.pyplot as plt # Instantiating matplotlib Figure self.fig = Figure() self.fig.patch.set_facecolor('white') if True: self.axes = self.fig.add_subplot(111) # return: matplotlib.axes.AxesSubplot self.axes2 = None else: self.axes = self.fig.add_host_subplot(111) # Initialize parent class and set parent FigureCanvas.__init__(self, self.fig) self.setParent(parent) # Set size policy to be able to expanding and resizable with frame FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # Variables to manage all lines/subplot self._lineDict = {} self._lineIndex = 0 # legend and color bar self._colorBar = None return def add_plot_1d(self, vec_x, vec_y, y_err=None, color=None, label="", x_label=None, y_label=None, marker=None, line_style=None, line_width=1): """ :param vec_x: numpy array X :param vec_y: numpy array Y :param y_err: :param color: :param label: :param x_label: :param y_label: :param marker: :param line_style: :param line_width: :return: new key """ # Check input if isinstance(vec_x, np.ndarray) is False or isinstance(vec_y, np.ndarray) is False: raise NotImplementedError('Input vec_x or vec_y for addPlot() must be numpy.array.') plot_error = y_err is not None if plot_error is True: if isinstance(y_err, np.ndarray) is False: raise NotImplementedError('Input y_err must be either None or numpy.array.') if len(vec_x) != len(vec_y): raise NotImplementedError('Input vec_x and vec_y must have same size.') if plot_error is True and len(y_err) != len(vec_x): raise NotImplementedError('Input vec_x, vec_y and y_error must have same size.') # Hold previous data self.axes.hold(True) # process inputs and defaults if color is None: color = (0,1,0,1) if marker is None: marker = 'o' if line_style is None: line_style = '-' # color must be RGBA (4-tuple) if plot_error is False: print "[DB] line_style = ", line_style, "line_width = ", line_width, "marker = ", marker, "color = ", color r = self.axes.plot(vec_x, vec_y, color=color, marker=marker, linestyle=line_style, label=label, linewidth=line_width) # return: list of matplotlib.lines.Line2D object else: r = self.axes.errorbar(vec_x, vec_y, yerr=y_err, color=color, marker=marker, linestyle=line_style, label=label, linewidth=line_width) self.axes.set_aspect('auto') # set x-axis and y-axis label if x_label is not None: self.axes.set_xlabel(x_label, fontsize=20) if y_label is not None: self.axes.set_ylabel(y_label, fontsize=20) # set/update legend self._setupLegend() # Register line_key = self._lineIndex if len(r) == 1: self._lineDict[line_key] = r[0] self._lineIndex += 1 else: print "Impoooooooooooooooosible! Return from plot is a %d-tuple. " % (len(r)) # Flush/commit self.draw() return line_key def add_1d_plot_right(self, x, y, color=None, label="", x_label=None, ylabel=None, marker=None, linestyle=None, linewidth=1): """ Add a line (1-d plot) at right axis """ if self.axes2 is None: self.axes2 = self.axes.twinx() # print self.par1, type(self.par1) # Hold previous data self.axes2.hold(True) # Default if color is None: color = (0, 1, 0, 1) if marker is None: marker = 'o' if linestyle is None: linestyle = '-' # Special default if len(label) == 0: label = 'right' color = 'red' # color must be RGBA (4-tuple) r = self.axes2.plot(x, y, color=color, marker=marker, linestyle=linestyle, label=label, linewidth=linewidth) # return: list of matplotlib.lines.Line2D object self.axes2.set_aspect('auto') # set x-axis and y-axis label if x_label is not None: self.axes2.set_xlabel(x_label, fontsize=20) if ylabel is not None: self.axes2.set_ylabel(ylabel, fontsize=20) # set/update legend self._setupLegend() # Register line_key = -1 if len(r) == 1: line_key = self._lineIndex self._lineDict[line_key] = r[0] self._lineIndex += 1 else: print "Impoooooooooooooooosible!" # Flush/commit self.draw() return line_key def addPlot2D(self, array2d, xmin, xmax, ymin, ymax, holdprev, yticklabels=None): """ Add a 2D plot Arguments: - yticklabels :: list of string for y ticks """ # Release the current image self.axes.hold(holdprev) # Do plot # y ticks will be shown on line 1, 4, 23, 24 and 30 # yticks = [1, 4, 23, 24, 30] # self.axes.set_yticks(yticks) # show image imgplot = self.axes.imshow(array2d, extent=[xmin,xmax,ymin,ymax], interpolation='none') # set y ticks as an option: if yticklabels is not None: # it will always label the first N ticks even image is zoomed in print "--------> [FixMe]: Set up the Y-axis ticks is erroreous" #self.axes.set_yticklabels(yticklabels) # explicitly set aspect ratio of the image self.axes.set_aspect('auto') # Set color bar. plt.colorbar() does not work! if self._colorBar is None: # set color map type imgplot.set_cmap('spectral') self._colorBar = self.fig.colorbar(imgplot) else: self._colorBar.update_bruteforce(imgplot) # Flush... self._flush() return def addImage(self, imagefilename): """ Add an image by file """ #import matplotlib.image as mpimg # set aspect to auto mode self.axes.set_aspect('auto') img = matplotlib.image.imread(str(imagefilename)) # lum_img = img[:,:,0] # FUTURE : refactor for image size, interpolation and origin imgplot = self.axes.imshow(img, extent=[0, 1000, 800, 0], interpolation='none', origin='lower') # Set color bar. plt.colorbar() does not work! if self._colorBar is None: # set color map type imgplot.set_cmap('spectral') self._colorBar = self.fig.colorbar(imgplot) else: self._colorBar.update_bruteforce(imgplot) self._flush() return def clear_all_1d_plots(self): """ Remove all lines from the canvas """ for ikey in self._lineDict.keys(): plot = self._lineDict[ikey] if plot is None: continue if isinstance(plot, tuple) is False: try: self.axes.lines.remove(plot) except ValueError as e: print "[Error] Plot %s is not in axes.lines which has %d lines. Error mesage: %s" % ( str(plot), len(self.axes.lines), str(e)) self._lineDict[ikey] = None else: # error bar plot[0].remove() for line in plot[1]: line.remove() for line in plot[2]: line.remove() self._lineDict[ikey] = None # ENDIF(plot) # ENDFOR self._setupLegend() self.draw() return def clear_canvas(self): """ Clear data including lines and image from canvas """ # clear the image for next operation self.axes.hold(False) # Clear all lines self.clear_all_1d_plots() # clear image self.axes.cla() # Try to clear the color bar if len(self.fig.axes) > 1: self.fig.delaxes(self.fig.axes[1]) self._colorBar = None # This clears the space claimed by color bar but destroys sub_plot too. self.fig.clear() # Re-create subplot self.axes = self.fig.add_subplot(111) # flush/commit self._flush() return def getLastPlotIndexKey(self): """ Get the index/key of the last added line """ return self._lineIndex-1 def getPlot(self): """ reture figure's axes to expose the matplotlib figure to PyQt client """ return self.axes def getXLimit(self): """ Get limit of Y-axis """ return self.axes.get_xlim() def getYLimit(self): """ Get limit of Y-axis """ return self.axes.get_ylim() def setXYLimit(self, xmin, xmax, ymin, ymax): """ """ # for X xlims = self.axes.get_xlim() xlims = list(xlims) if xmin is not None: xlims[0] = xmin if xmax is not None: xlims[1] = xmax self.axes.set_xlim(xlims) # for Y ylims = self.axes.get_ylim() ylims = list(ylims) if ymin is not None: ylims[0] = ymin if ymax is not None: ylims[1] = ymax self.axes.set_ylim(ylims) # try draw self.draw() return def remove_plot_1d(self, plot_key): """ Remove the line with its index as key :param plot_key: :return: """ # self._lineDict[ikey].remove() print 'Remove line... ', # Get all lines in list lines = self.axes.lines assert isinstance(lines, list) print 'Number of lines = %d, List: %s' % (len(lines), str(lines)) print 'Line to remove: key = %s, Line Dict has key = %s' % (str(plot_key), str(self._lineDict.has_key(plot_key))) if plot_key in self._lineDict: self.axes.lines.remove(self._lineDict[plot_key]) self._lineDict[plot_key] = None else: raise RuntimeError('Line with ID %s is not recorded.' % plot_key) # Draw self.draw() return def updateLine(self, ikey, vecx, vecy, linestyle=None, linecolor=None, marker=None, markercolor=None): """ """ line = self._lineDict[ikey] if vecx is not None and vecy is not None: line.set_xdata(vecx) line.set_ydata(vecy) if linecolor is not None: line.set_color(linecolor) if linestyle is not None: line.set_linestyle(linestyle) if marker is not None: line.set_marker(marker) if markercolor is not None: line.set_markerfacecolor(markercolor) oldlabel = line.get_label() line.set_label(oldlabel) self.axes.legend() # commit self.draw() return def getLineStyleList(self): """ """ return MplLineStyles def getLineMarkerList(self): """ """ return MplLineMarkers def getLineBasicColorList(self): """ """ return MplBasicColors def getDefaultColorMarkerComboList(self): """ Get a list of line/marker color and marker style combination as default to add more and more line to plot """ combolist = [] nummarkers = len(MplLineMarkers) numcolors = len(MplBasicColors) for i in xrange(nummarkers): marker = MplLineMarkers[i] for j in xrange(numcolors): color = MplBasicColors[j] combolist.append( (marker, color) ) # ENDFOR (j) # ENDFOR(i) return combolist def _flush(self): """ A dirty hack to flush the image """ w, h = self.get_width_height() self.resize(w+1,h) self.resize(w,h) return def _setupLegend(self, location='best'): """ Set up legend self.axes.legend() Handler is a Line2D object. Lable maps to the line object """ loclist = [ "best", "upper right", "upper left", "lower left", "lower right", "right", "center left", "center right", "lower center", "upper center", "center"] # Check legend location valid or not if location not in loclist: location = 'best' handles, labels = self.axes.get_legend_handles_labels() self.axes.legend(handles, labels, loc=location) # print handles # print labels #self.axes.legend(self._myLegendHandlers, self._myLegentLabels) return
class MainGUI(QWidget): waveforms_generated = pyqtSignal(object, object, list, int) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) os.chdir('./') # Set directory to current folder. self.setFont(QFont("Arial")) # self.setMinimumSize(900, 1020) self.setWindowTitle("Screening Analysis") self.layout = QGridLayout(self) self.popnexttopimgcounter = 0 self.Tag_round_infor = [] self.Lib_round_infor = [] #************************************************************************************************************************************** #-----------------------------------------------------------GUI for Billboard display------------------------------------------------------ #************************************************************************************************************************************** ImageDisplayContainer = QGroupBox("Billboard") ImageDisplayContainerLayout = QGridLayout() self.GraphyDisplayTab = QTabWidget() #---------------------------------------------------------------------- MatDsiplayPart = QWidget() MatDsiplayPart.layout = QGridLayout() # a figure instance to plot on self.Matdisplay_Figure = Figure() self.Matdisplay_Canvas = FigureCanvas(self.Matdisplay_Figure) self.Matdisplay_toolbar = NavigationToolbar(self.Matdisplay_Canvas, self) MatDsiplayPart.layout.addWidget(self.Matdisplay_toolbar, 0, 0) MatDsiplayPart.layout.addWidget(self.Matdisplay_Canvas, 1, 0) MatDsiplayPart.setLayout(MatDsiplayPart.layout) self.OriginalImgWidget = pg.ImageView() self.OriginalImg_item = self.OriginalImgWidget.getImageItem( ) #setLevels self.OriginalImg_view = self.OriginalImgWidget.getView() self.OriginalImg_item.setAutoDownsample(True) self.OriginalImgWidget.ui.roiBtn.hide() self.OriginalImgWidget.ui.menuBtn.hide() self.OriginalImgWidget.ui.normGroup.hide() self.OriginalImgWidget.ui.roiPlot.hide() self.GraphyDisplayTab.addTab(self.OriginalImgWidget, "Image loaded") self.GraphyDisplayTab.addTab(MatDsiplayPart, "Scatter") ImageDisplayContainerLayout.addWidget(self.GraphyDisplayTab, 1, 1) #---------------------------------------------------------------------- ImageButtonContainer = QGroupBox() ImageButtonContainerLayout = QGridLayout() ButtonRankResetCoordImg = QPushButton('Reset coord', self) ButtonRankResetCoordImg.clicked.connect(self.ResetRankCoord) ImageButtonContainerLayout.addWidget(ButtonRankResetCoordImg, 0, 6) ButtonRankPreviousCoordImg = QPushButton('Previous', self) ButtonRankPreviousCoordImg.setShortcut('a') ButtonRankPreviousCoordImg.clicked.connect( lambda: self.GoThroughTopCells('previous')) ImageButtonContainerLayout.addWidget(ButtonRankPreviousCoordImg, 1, 6) self.ButtonShowInScatter = QPushButton('Show in scatter', self) self.ButtonShowInScatter.setShortcut('s') self.ButtonShowInScatter.setCheckable(True) self.ButtonShowInScatter.clicked.connect(self.ShowScatterPos) ImageButtonContainerLayout.addWidget(self.ButtonShowInScatter, 2, 6) ButtonRankNextCoordImg = QPushButton('Next', self) ButtonRankNextCoordImg.setShortcut('d') ButtonRankNextCoordImg.clicked.connect( lambda: self.GoThroughTopCells('next')) ImageButtonContainerLayout.addWidget(ButtonRankNextCoordImg, 1, 7) GoSeqButton = QPushButton('Go to IDNumber: ', self) GoSeqButton.clicked.connect(self.GotoSequence) ImageButtonContainerLayout.addWidget(GoSeqButton, 3, 6) self.ShowSequenceScatterButton = QPushButton('Show this in scatter', self) self.ShowSequenceScatterButton.setCheckable(True) self.ShowSequenceScatterButton.clicked.connect( self.ShowSequenceScatter) ImageButtonContainerLayout.addWidget(self.ShowSequenceScatterButton, 3, 8) self.CellSequenceBox = QSpinBox(self) self.CellSequenceBox.setMaximum(9000) self.CellSequenceBox.setValue(0) self.CellSequenceBox.setSingleStep(1) ImageButtonContainerLayout.addWidget(self.CellSequenceBox, 3, 7) ButtonRankDeleteFromList = QPushButton('Delete', self) ButtonRankDeleteFromList.clicked.connect(self.DeleteFromTopCells) ImageButtonContainerLayout.addWidget(ButtonRankDeleteFromList, 2, 7) ButtonRankSaveList = QPushButton('Save array', self) ButtonRankSaveList.clicked.connect(self.SaveCellsProArray) ImageButtonContainerLayout.addWidget(ButtonRankSaveList, 4, 6) self.ConsoleTextDisplay = QTextEdit() self.ConsoleTextDisplay.setFontItalic(True) self.ConsoleTextDisplay.setPlaceholderText( 'Notice board from console.') self.ConsoleTextDisplay.setMaximumHeight(300) ImageButtonContainerLayout.addWidget(self.ConsoleTextDisplay, 5, 6, 3, 2) ImageButtonContainer.setLayout(ImageButtonContainerLayout) ImageDisplayContainer.setLayout(ImageDisplayContainerLayout) ImageDisplayContainer.setMinimumHeight(700) ImageDisplayContainer.setMinimumWidth(700) self.layout.addWidget(ImageDisplayContainer, 0, 0, 2, 2) self.layout.addWidget(ImageButtonContainer, 0, 2) #************************************************************************************************************************************** #-----------------------------------------------------------GUI for Image processing settings------------------------------------------ #************************************************************************************************************************************** self.PostProcessTab = QTabWidget() self.PostProcessTab.setMaximumWidth(400) self.PostProcessTab.setFixedHeight(250) ImageProcessingContainer = QGroupBox() IPLayout = QGridLayout() self.IPsizetextbox = QSpinBox(self) self.IPsizetextbox.setMaximum(2000) self.IPsizetextbox.setValue(800) self.IPsizetextbox.setSingleStep(1) IPLayout.addWidget(self.IPsizetextbox, 1, 7) IPLayout.addWidget(QLabel("Cell smallest size:"), 1, 6) self.opening_factorBox = QSpinBox(self) self.opening_factorBox.setMaximum(2000) self.opening_factorBox.setValue(2) self.opening_factorBox.setSingleStep(1) IPLayout.addWidget(self.opening_factorBox, 2, 5) IPLayout.addWidget(QLabel("Mask opening factor:"), 2, 4) self.closing_factorBox = QSpinBox(self) self.closing_factorBox.setMaximum(2000) self.closing_factorBox.setValue(3) self.closing_factorBox.setSingleStep(1) IPLayout.addWidget(self.closing_factorBox, 2, 7) IPLayout.addWidget(QLabel("Mask closing factor:"), 2, 6) self.binary_adaptive_block_sizeBox = QSpinBox(self) self.binary_adaptive_block_sizeBox.setMaximum(2000) self.binary_adaptive_block_sizeBox.setValue(335) self.binary_adaptive_block_sizeBox.setSingleStep(50) IPLayout.addWidget(self.binary_adaptive_block_sizeBox, 1, 1) IPLayout.addWidget(QLabel("Adaptive mask size:"), 1, 0) self.contour_dilation_box = QSpinBox(self) self.contour_dilation_box.setMaximum(2000) self.contour_dilation_box.setValue(11) self.contour_dilation_box.setSingleStep(1) IPLayout.addWidget(self.contour_dilation_box, 1, 3) IPLayout.addWidget(QLabel("Contour thickness:"), 1, 2) IPLayout.addWidget(QLabel("Threshold-contour:"), 1, 4) self.find_contour_thres_box = QDoubleSpinBox(self) self.find_contour_thres_box.setDecimals(4) self.find_contour_thres_box.setMinimum(-10) self.find_contour_thres_box.setMaximum(10) self.find_contour_thres_box.setValue(0.001) self.find_contour_thres_box.setSingleStep(0.0001) IPLayout.addWidget(self.find_contour_thres_box, 1, 5) self.cellopening_factorBox = QSpinBox(self) self.cellopening_factorBox.setMaximum(2000) self.cellopening_factorBox.setValue(1) self.cellopening_factorBox.setSingleStep(1) IPLayout.addWidget(self.cellopening_factorBox, 2, 1) IPLayout.addWidget(QLabel("Cell opening factor:"), 2, 0) self.cellclosing_factorBox = QSpinBox(self) self.cellclosing_factorBox.setMaximum(20000) self.cellclosing_factorBox.setValue(2) self.cellclosing_factorBox.setSingleStep(1) IPLayout.addWidget(self.cellclosing_factorBox, 2, 3) IPLayout.addWidget(QLabel("Cell closing factor:"), 2, 2) ImageProcessingContainer.setLayout(IPLayout) #---------------------------Loading------------------------------------ LoadSettingContainer = QGroupBox() LoadSettingLayout = QGridLayout() self.FilepathSwitchBox = QComboBox() self.FilepathSwitchBox.addItems(['Tag', 'Lib', 'All']) LoadSettingLayout.addWidget(self.FilepathSwitchBox, 0, 0) self.AnalysisRoundBox = QSpinBox(self) self.AnalysisRoundBox.setMaximum(2000) self.AnalysisRoundBox.setValue(1) self.AnalysisRoundBox.setSingleStep(1) LoadSettingLayout.addWidget(self.AnalysisRoundBox, 0, 2) self.AddAnalysisRoundButton = QtWidgets.QPushButton('Add Round:') self.AddAnalysisRoundButton.clicked.connect(self.SetAnalysisRound) LoadSettingLayout.addWidget(self.AddAnalysisRoundButton, 0, 1) self.datasavedirectorytextbox = QLineEdit(self) self.datasavedirectorytextbox.setPlaceholderText('Data directory') LoadSettingLayout.addWidget(self.datasavedirectorytextbox, 1, 0, 1, 2) self.toolButtonOpenDialog = QtWidgets.QPushButton('Set path') self.toolButtonOpenDialog.clicked.connect(self.SetAnalysisPath) LoadSettingLayout.addWidget(self.toolButtonOpenDialog, 1, 2) ExecuteAnalysisButton = QPushButton('Load images', self) # ExecuteAnalysisButton.setObjectName('Startbutton') ExecuteAnalysisButton.clicked.connect( lambda: self.StartScreeningAnalysisThread()) LoadSettingLayout.addWidget(ExecuteAnalysisButton, 2, 1) self.ClearAnalysisInforButton = QtWidgets.QPushButton('Clear infor') self.ClearAnalysisInforButton.clicked.connect(self.ClearAnalysisInfor) LoadSettingLayout.addWidget(self.ClearAnalysisInforButton, 2, 2) LoadSettingContainer.setLayout(LoadSettingLayout) #************************************************************************************************************************************** #-----------------------------------------------------------GUI for Selection settings Container--------------------------------------- #************************************************************************************************************************************** SelectionsettingTab = QWidget() SelectionsettingTab.layout = QGridLayout() self.SeleParaBox = QComboBox() self.SeleParaBox.addItems( ['Mean intensity divided by tag/Contour soma ratio']) SelectionsettingTab.layout.addWidget(self.SeleParaBox, 0, 2) SelectionsettingTab.layout.addWidget(QLabel('Scatter axes'), 0, 1) self.AnalysisTypeSwitchBox = QComboBox() self.AnalysisTypeSwitchBox.addItems(['Brightness screening', 'Lib']) SelectionsettingTab.layout.addWidget(self.AnalysisTypeSwitchBox, 0, 0) UpdateProcessTab = QTabWidget() UpdateProcessTab.layout = QGridLayout() UpdateProcessTab_1 = QWidget() UpdateProcessTab_1.layout = QGridLayout() UpdateProcessTab_1.layout.addWidget(QLabel("Selection boundary:"), 0, 0) self.Selection_boundaryBox = QComboBox() self.Selection_boundaryBox.addItems(['Circular radius', 'Rank']) UpdateProcessTab_1.layout.addWidget(self.Selection_boundaryBox, 0, 1) UpdateScattersButton = QtWidgets.QPushButton('Update scatters') UpdateScattersButton.clicked.connect(self.UpdateSelectionScatter) UpdateProcessTab_1.layout.addWidget(UpdateScattersButton, 0, 4) UpdateProcessTab_2 = QWidget() UpdateProcessTab_2.layout = QGridLayout() self.WeightBoxSelectionFactor_1 = QDoubleSpinBox(self) self.WeightBoxSelectionFactor_1.setDecimals(2) self.WeightBoxSelectionFactor_1.setMinimum(0) self.WeightBoxSelectionFactor_1.setMaximum(1) self.WeightBoxSelectionFactor_1.setValue(1) self.WeightBoxSelectionFactor_1.setSingleStep(0.1) UpdateProcessTab_2.layout.addWidget(self.WeightBoxSelectionFactor_1, 0, 1) UpdateProcessTab_2.layout.addWidget(QLabel("Axis 1:"), 0, 0) self.WeightBoxSelectionFactor_2 = QDoubleSpinBox(self) self.WeightBoxSelectionFactor_2.setDecimals(2) self.WeightBoxSelectionFactor_2.setMinimum(0) self.WeightBoxSelectionFactor_2.setMaximum(1) self.WeightBoxSelectionFactor_2.setValue(0.5) self.WeightBoxSelectionFactor_2.setSingleStep(0.1) UpdateProcessTab_2.layout.addWidget(self.WeightBoxSelectionFactor_2, 0, 3) UpdateProcessTab_2.layout.addWidget(QLabel("Axis 2:"), 0, 2) self.WeightBoxSelectionFactor_3 = QDoubleSpinBox(self) self.WeightBoxSelectionFactor_3.setDecimals(2) self.WeightBoxSelectionFactor_3.setMinimum(0) self.WeightBoxSelectionFactor_3.setMaximum(1) self.WeightBoxSelectionFactor_3.setValue(1) self.WeightBoxSelectionFactor_3.setSingleStep(0.1) UpdateProcessTab_2.layout.addWidget(self.WeightBoxSelectionFactor_3, 0, 5) UpdateProcessTab_2.layout.addWidget(QLabel("Axis 3:"), 0, 4) SelectionthresholdsettingTab = QWidget() SelectionthresholdsettingTab.layout = QGridLayout() SelectionthresholdsettingTab.layout.addWidget( QLabel("Intensity threshold:"), 0, 0) self.SelectionMeanInten_thres_box = QDoubleSpinBox(self) self.SelectionMeanInten_thres_box.setDecimals(4) self.SelectionMeanInten_thres_box.setMinimum(0) self.SelectionMeanInten_thres_box.setMaximum(10) self.SelectionMeanInten_thres_box.setValue(0.150) self.SelectionMeanInten_thres_box.setSingleStep(0.0001) SelectionthresholdsettingTab.layout.addWidget( self.SelectionMeanInten_thres_box, 0, 1) SelectionthresholdsettingTab.layout.addWidget( QLabel("Contour/Soma threshold:"), 1, 0) self.SelectionCSratio_thres_box = QDoubleSpinBox(self) self.SelectionCSratio_thres_box.setDecimals(3) self.SelectionCSratio_thres_box.setMinimum(0) self.SelectionCSratio_thres_box.setMaximum(10) self.SelectionCSratio_thres_box.setValue(0.80) self.SelectionCSratio_thres_box.setSingleStep(0.0001) SelectionthresholdsettingTab.layout.addWidget( self.SelectionCSratio_thres_box, 1, 1) SelectionthresholdsettingTab.layout.addWidget( QLabel("Roundness threshold:"), 0, 2) self.SelectionRoundness_thres_box = QDoubleSpinBox(self) self.SelectionRoundness_thres_box.setDecimals(3) self.SelectionRoundness_thres_box.setMinimum(0) self.SelectionRoundness_thres_box.setMaximum(10) self.SelectionRoundness_thres_box.setValue(1.10) self.SelectionRoundness_thres_box.setSingleStep(0.0001) SelectionthresholdsettingTab.layout.addWidget( self.SelectionRoundness_thres_box, 0, 3) SelectionthresholdsettingTab.setLayout( SelectionthresholdsettingTab.layout) UpdateProcessTab_2.layout.addWidget(SelectionthresholdsettingTab, 1, 0, 1, 6) UpdateProcessTab_1.setLayout(UpdateProcessTab_1.layout) UpdateProcessTab_2.setLayout(UpdateProcessTab_2.layout) UpdateProcessTab.addTab(UpdateProcessTab_1, "Normalized distance") UpdateProcessTab.addTab(UpdateProcessTab_2, "Axes weights") SelectionsettingTab.layout.addWidget(UpdateProcessTab, 1, 0, 4, 3) SelectionsettingTab.setLayout(SelectionsettingTab.layout) #************************************************************************************************************************************** #-----------------------------------------------------------GUI for Selection threshold settings--------------------------------------- #************************************************************************************************************************************** self.PostProcessTab.addTab(LoadSettingContainer, "Loading settings") self.PostProcessTab.addTab(SelectionsettingTab, "Analysis selection") self.PostProcessTab.addTab(ImageProcessingContainer, "Image analysis settings") self.layout.addWidget(self.PostProcessTab, 1, 2) self.setLayout(self.layout) #---------------------------------------------------------------functions for console display------------------------------------------------------------ def normalOutputWritten(self, text): """Append text to the QTextEdit.""" # Maybe QTextEdit.append() works as well, but this is how I do it: cursor = self.ConsoleTextDisplay.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.ConsoleTextDisplay.setTextCursor(cursor) self.ConsoleTextDisplay.ensureCursorVisible() """ # ============================================================================= # FUNCTIONS FOR DATA ANALYSIS AND DISPLAY # ============================================================================= """ def SetAnalysisPath(self): self.Analysissavedirectory = str( QtWidgets.QFileDialog.getExistingDirectory()) self.datasavedirectorytextbox.setText(self.Analysissavedirectory) if self.FilepathSwitchBox.currentText() == 'Tag': self.Tag_folder = self.Analysissavedirectory elif self.FilepathSwitchBox.currentText() == 'Lib': self.Lib_folder = self.Analysissavedirectory elif self.FilepathSwitchBox.currentText() == 'All': self.Tag_folder = self.Analysissavedirectory self.Lib_folder = self.Analysissavedirectory def SetAnalysisRound(self): if self.FilepathSwitchBox.currentText() == 'Tag': self.Tag_round_infor.append(self.AnalysisRoundBox.value()) elif self.FilepathSwitchBox.currentText() == 'Lib': self.Lib_round_infor.append(self.AnalysisRoundBox.value()) self.normalOutputWritten( 'Tag_round_infor: {}\nLib_round_infor: {}\n'.format( str(self.Tag_round_infor), str(self.Lib_round_infor))) def ClearAnalysisInfor(self): self.Tag_folder = None self.Lib_folder = None self.Tag_round_infor = [] self.Lib_round_infor = [] def StartScreeningAnalysisThread(self): self.ScreeningAnalysis_thread = threading.Thread( target=self.ScreeningAnalysis, daemon=True) self.ScreeningAnalysis_thread.start() def ScreeningAnalysis(self): # For the brightness screening if self.AnalysisTypeSwitchBox.currentText() == 'Brightness screening': self.normalOutputWritten('Start loading images...\n') tag_folder = self.Tag_folder lib_folder = self.Lib_folder tag_round = 'Round{}'.format(self.Tag_round_infor[0]) lib_round = 'Round{}'.format(self.Lib_round_infor[0]) tagprotein_cell_properties_dict = ProcessImage.TagFluorescenceAnalysis( tag_folder, tag_round, Roundness_threshold=self.SelectionRoundness_thres_box.value()) self.normalOutputWritten('tag done...\n') lib_cell_properties_dict = ProcessImage.LibFluorescenceAnalysis( lib_folder, tag_round, lib_round, tagprotein_cell_properties_dict) self.normalOutputWritten('lib done...\n') # Devided by fusion protein brightness. self.lib_cell_properties_dict = ProcessImage.CorrectForFusionProtein( tagprotein_cell_properties_dict, lib_cell_properties_dict, tagprotein_laserpower=1, lib_laserpower=30) self.UpdateSelectionScatter() def UpdateSelectionScatter(self): lib_cell_properties_dict = self.lib_cell_properties_dict IntensityThreshold = self.SelectionMeanInten_thres_box.value() CSratioThreshold = self.SelectionCSratio_thres_box.value() self.EvaluatingPara_list = str( self.SeleParaBox.currentText()).split("/") self.Matdisplay_Figure.clear() if self.Selection_boundaryBox.currentText() == 'Circular radius': # selectionRadiusPercent = 100 - self.AnalysisCirclePercentBox.value() selectionRadiusPercent = 100 if len(self.EvaluatingPara_list) == 2: # Organize and add 'ranking' and 'boundingbox' fields to the structured array. axis_1_weight = self.WeightBoxSelectionFactor_1.value() axis_2_weight = self.WeightBoxSelectionFactor_2.value() self.Overview_LookupBook = ProcessImage.OrganizeOverview( lib_cell_properties_dict, [ 'Mean intensity in contour', IntensityThreshold, 'Contour soma ratio', CSratioThreshold ], self.EvaluatingPara_list[0], axis_1_weight, self.EvaluatingPara_list[1], axis_2_weight) # Sort the original array according to distance from origin. self.Overview_LookupBook = ProcessImage.DistanceSelecting( self.Overview_LookupBook, 100) self.Overview_LookupBook_filtered = ProcessImage.DistanceSelecting( self.Overview_LookupBook, selectionRadiusPercent) ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.scatter( self.Overview_LookupBook[self.EvaluatingPara_list[0]], self.Overview_LookupBook[self.EvaluatingPara_list[1]], s=np.pi * 3, c='blue', alpha=0.5) ax1.scatter(self.Overview_LookupBook_filtered[ self.EvaluatingPara_list[0]], self.Overview_LookupBook_filtered[ self.EvaluatingPara_list[1]], s=np.pi * 3, c='red', alpha=0.5) ax1.set_xlabel(self.EvaluatingPara_list[0]) ax1.set_ylabel(self.EvaluatingPara_list[1]) self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() # Some numbers ready for tracing back self.TotaNumofCellSelected = len( self.Overview_LookupBook_filtered) self.TotalCellNum = len(self.Overview_LookupBook) self.normalOutputWritten( '---- Total cells selected: {}; Total cells: {}----\n'. format(self.TotaNumofCellSelected, self.TotalCellNum)) fig = px.scatter(self.Overview_LookupBook, x=self.EvaluatingPara_list[0], y=self.EvaluatingPara_list[1], hover_name='ID', color='Normalized distance', hover_data=['IDNumber', 'Mean intensity'], width=1050, height=950) fig.write_html('Screening scatters.html', auto_open=True) def GoThroughTopCells(self, direction): if direction == 'next': if self.popnexttopimgcounter > ( self.TotaNumofCellSelected - 1): #Make sure it doesn't go beyond the last coords. self.popnexttopimgcounter -= 1 self.CurrentRankCellpProperties = self.Overview_LookupBook[ self.popnexttopimgcounter] #--------------------Show image with cell in box---------------------- spec = self.CurrentRankCellpProperties['ID'] print(spec) # #-------------- readin image--------------- tag_imagefilename = os.path.join(self.Tag_folder, spec + '_PMT_0Zmax.tif') print(tag_imagefilename) loaded_tag_image_display = imread(tag_imagefilename, as_gray=True) # Retrieve boundingbox information Each_bounding_box = self.CurrentRankCellpProperties['BoundingBox'] minr = int(Each_bounding_box[Each_bounding_box.index('minr') + 4:Each_bounding_box.index('_minc')]) maxr = int( Each_bounding_box[Each_bounding_box.index('maxr') + 4:Each_bounding_box.index('_maxc')]) - 1 minc = int(Each_bounding_box[Each_bounding_box.index('minc') + 4:Each_bounding_box.index('_maxr')]) maxc = int(Each_bounding_box[Each_bounding_box.index('maxc') + 4:len(Each_bounding_box)]) - 1 loaded_tag_image_display[minr, minc:maxc] = 4 loaded_tag_image_display[maxr, minc:maxc] = 4 loaded_tag_image_display[minr:maxr, minc] = 4 loaded_tag_image_display[minr:maxr, maxc] = 4 # -------Show image in imageview------------- self.OriginalImg_item.setImage(np.fliplr( np.rot90(loaded_tag_image_display)), autoLevels=True) self.OriginalImg_item.setLevels((0, 1)) self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.imshow(loaded_tag_image_display) #Show the first image #--------------------------------------------------Add red boundingbox to axis---------------------------------------------- rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='cyan', linewidth=2) ax1.add_patch(rect) ax1.text(maxc, minr, 'NO_{}'.format(self.popnexttopimgcounter), fontsize=10, color='orange', style='italic') self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() #-------------------Print details of cell of interest---------------- self.normalOutputWritten( '------------------No.{} out of {}----------------\n'.format( self.popnexttopimgcounter + 1, self.TotaNumofCellSelected)) self.normalOutputWritten('ID: {}\n{}: {}\n{}: {}\n{}: {}\n'.format(spec, self.EvaluatingPara_list[0], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[0]], 4), \ self.EvaluatingPara_list[1], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[1]], 4), 'IDNumber', self.CurrentRankCellpProperties['IDNumber'])) #------------------Stage move---------------------------------------- # self.CurrentPos = spec[spec.index('_R')+2:len(spec)].split('C') # self.ludlStage.moveAbs(int(self.CurrentPos[0]),int(self.CurrentPos[1])) self.popnexttopimgcounter += 1 # Alwasy plus 1 to get it ready for next move. elif direction == 'previous': self.popnexttopimgcounter -= 2 if self.popnexttopimgcounter >= 0: self.CurrentRankCellpProperties = self.Overview_LookupBook[ self.popnexttopimgcounter] #--------------------Show image with cell in box---------------------- spec = self.CurrentRankCellpProperties['ID'] # #-------------- readin image--------------- tag_imagefilename = os.path.join(self.Tag_folder, spec + '_PMT_0Zmax.tif') loaded_tag_image_display = imread(tag_imagefilename, as_gray=True) # Retrieve boundingbox information Each_bounding_box = self.CurrentRankCellpProperties[ 'BoundingBox'] minr = int( Each_bounding_box[Each_bounding_box.index('minr') + 4:Each_bounding_box.index('_minc')]) maxr = int( Each_bounding_box[Each_bounding_box.index('maxr') + 4:Each_bounding_box.index('_maxc')]) - 1 minc = int( Each_bounding_box[Each_bounding_box.index('minc') + 4:Each_bounding_box.index('_maxr')]) maxc = int(Each_bounding_box[Each_bounding_box.index('maxc') + 4:len(Each_bounding_box)]) - 1 loaded_tag_image_display[minr, minc:maxc] = 4 loaded_tag_image_display[maxr, minc:maxc] = 4 loaded_tag_image_display[minr:maxr, minc] = 4 loaded_tag_image_display[minr:maxr, maxc] = 4 # -------Show image in imageview------------- self.OriginalImg_item.setImage(np.fliplr( np.rot90(loaded_tag_image_display)), autoLevels=True) self.OriginalImg_item.setLevels((0, 1)) self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.imshow(loaded_tag_image_display) #Show the first image #--------------------------------------------------Add red boundingbox to axis---------------------------------------------- rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='cyan', linewidth=2) ax1.add_patch(rect) ax1.text(maxc, minr, 'NO_{}'.format(self.popnexttopimgcounter), fontsize=10, color='orange', style='italic') self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() #-------------------Print details of cell of interest---------------- self.normalOutputWritten( '------------------No.{} out of {}----------------\n'. format(self.popnexttopimgcounter + 1, self.TotaNumofCellSelected)) self.normalOutputWritten('ID: {}\n{}: {}\n{}: {}\n{}: {}\n'.format(spec, self.EvaluatingPara_list[0], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[0]], 4), \ self.EvaluatingPara_list[1], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[1]], 4), 'IDNumber', self.CurrentRankCellpProperties['IDNumber'])) #------------------Stage move---------------------------------------- # self.CurrentPos = spec[spec.index('_R')+2:len(spec)].split('C') # self.ludlStage.moveAbs(int(self.CurrentPos[0]),int(self.CurrentPos[1])) if self.popnexttopimgcounter < (self.TotaNumofCellSelected - 1): self.popnexttopimgcounter += 1 else: self.popnexttopimgcounter = 0 elif direction == 'null': self.popnexttopimgcounter -= 1 self.CurrentRankCellpProperties = self.Overview_LookupBook[ self.popnexttopimgcounter] #--------------------Show image with cell in box---------------------- spec = self.CurrentRankCellpProperties['ID'] # #-------------- readin image--------------- tag_imagefilename = os.path.join(self.Tag_folder, spec + '_PMT_0Zmax.tif') loaded_tag_image_display = imread(tag_imagefilename, as_gray=True) # Retrieve boundingbox information Each_bounding_box = self.CurrentRankCellpProperties['BoundingBox'] minr = int(Each_bounding_box[Each_bounding_box.index('minr') + 4:Each_bounding_box.index('_minc')]) maxr = int( Each_bounding_box[Each_bounding_box.index('maxr') + 4:Each_bounding_box.index('_maxc')]) - 1 minc = int(Each_bounding_box[Each_bounding_box.index('minc') + 4:Each_bounding_box.index('_maxr')]) maxc = int(Each_bounding_box[Each_bounding_box.index('maxc') + 4:len(Each_bounding_box)]) - 1 loaded_tag_image_display[minr, minc:maxc] = 4 loaded_tag_image_display[maxr, minc:maxc] = 4 loaded_tag_image_display[minr:maxr, minc] = 4 loaded_tag_image_display[minr:maxr, maxc] = 4 # -------Show image in imageview------------- self.OriginalImg_item.setImage(np.fliplr( np.rot90(loaded_tag_image_display)), autoLevels=True) self.OriginalImg_item.setLevels((0, 1)) self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.imshow(loaded_tag_image_display) #Show the first image #--------------------------------------------------Add red boundingbox to axis---------------------------------------------- rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='cyan', linewidth=2) ax1.add_patch(rect) ax1.text(maxc, minr, 'NO_{}'.format(self.popnexttopimgcounter), fontsize=10, color='orange', style='italic') self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() self.popnexttopimgcounter += 1 elif direction == 'IDNumber': self.GotoSequence() def GotoSequence(self): """ Go to a specific cell """ self.SpecificIndexInArray = np.where( self.Overview_LookupBook['IDNumber'] == self.CellSequenceBox.value())[0][0] self.CurrentRankCellpProperties = self.Overview_LookupBook[ self.SpecificIndexInArray] #--------------------Show image with cell in box---------------------- spec = self.CurrentRankCellpProperties['ID'] print(spec) # #-------------- readin image--------------- tag_imagefilename = os.path.join(self.Tag_folder, spec + '_PMT_0Zmax.tif') print(tag_imagefilename) loaded_tag_image_display = imread(tag_imagefilename, as_gray=True) # Retrieve boundingbox information Each_bounding_box = self.CurrentRankCellpProperties['BoundingBox'] minr = int(Each_bounding_box[Each_bounding_box.index('minr') + 4:Each_bounding_box.index('_minc')]) maxr = int(Each_bounding_box[Each_bounding_box.index('maxr') + 4:Each_bounding_box.index('_maxc')]) - 1 minc = int(Each_bounding_box[Each_bounding_box.index('minc') + 4:Each_bounding_box.index('_maxr')]) maxc = int(Each_bounding_box[Each_bounding_box.index('maxc') + 4:len(Each_bounding_box)]) - 1 loaded_tag_image_display[minr, minc:maxc] = 4 loaded_tag_image_display[maxr, minc:maxc] = 4 loaded_tag_image_display[minr:maxr, minc] = 4 loaded_tag_image_display[minr:maxr, maxc] = 4 # -------Show image in imageview------------- self.OriginalImg_item.setImage(np.fliplr( np.rot90(loaded_tag_image_display)), autoLevels=True) self.OriginalImg_item.setLevels((0, 1)) self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.imshow(loaded_tag_image_display) #Show the first image #--------------------------------------------------Add red boundingbox to axis---------------------------------------------- rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='cyan', linewidth=2) ax1.add_patch(rect) ax1.text(maxc, minr, 'Seq_{}'.format(self.CurrentRankCellpProperties['IDNumber']), fontsize=10, color='orange', style='italic') self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() #-------------------Print details of cell of interest---------------- self.normalOutputWritten( '------------------IDNumber {}----------------\n'.format( self.CurrentRankCellpProperties['IDNumber'])) self.normalOutputWritten('ID: {}\n{}: {}\n{}: {}\n'.format(spec, self.EvaluatingPara_list[0], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[0]], 4), \ self.EvaluatingPara_list[1], round(self.CurrentRankCellpProperties[self.EvaluatingPara_list[1]], 4))) def ShowScatterPos(self): if self.ButtonShowInScatter.isChecked(): self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.scatter(self.Overview_LookupBook[self.EvaluatingPara_list[0]], self.Overview_LookupBook[self.EvaluatingPara_list[1]], s=np.pi * 3, c='blue', alpha=0.5) ax1.scatter( self.Overview_LookupBook_filtered[self.EvaluatingPara_list[0]], self.Overview_LookupBook_filtered[self.EvaluatingPara_list[1]], s=np.pi * 3, c='blue', alpha=0.5) ax1.scatter(self.Overview_LookupBook_filtered[ self.popnexttopimgcounter - 1][self.EvaluatingPara_list[0]], self.Overview_LookupBook_filtered[ self.popnexttopimgcounter - 1][self.EvaluatingPara_list[1]], s=np.pi * 6, c='yellow', alpha=0.5) ax1.set_xlabel(self.EvaluatingPara_list[0]) ax1.set_ylabel(self.EvaluatingPara_list[1]) self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() else: self.GoThroughTopCells('null') def ShowSequenceScatter(self): if self.ShowSequenceScatterButton.isChecked(): self.Matdisplay_Figure.clear() ax1 = self.Matdisplay_Figure.add_subplot(111) ax1.scatter(self.Overview_LookupBook[self.EvaluatingPara_list[0]], self.Overview_LookupBook[self.EvaluatingPara_list[1]], s=np.pi * 3, c='blue', alpha=0.5) ax1.scatter( self.Overview_LookupBook_filtered[self.EvaluatingPara_list[0]], self.Overview_LookupBook_filtered[self.EvaluatingPara_list[1]], s=np.pi * 3, c='blue', alpha=0.5) ax1.scatter( self.Overview_LookupBook_filtered[self.SpecificIndexInArray][ self.EvaluatingPara_list[0]], self.Overview_LookupBook_filtered[self.SpecificIndexInArray][ self.EvaluatingPara_list[1]], s=np.pi * 6, c='yellow', alpha=0.5) ax1.set_xlabel(self.EvaluatingPara_list[0]) ax1.set_ylabel(self.EvaluatingPara_list[1]) self.Matdisplay_Figure.tight_layout() self.Matdisplay_Canvas.draw() else: self.GoThroughTopCells('sequence') def DeleteFromTopCells(self): self.popnexttopimgcounter -= 1 self.Overview_LookupBook_filtered = np.delete( self.Overview_LookupBook_filtered, self.popnexttopimgcounter, 0) # self.Overview_LookupBook = np.delete(self.Overview_LookupBook, self.popnexttopimgcounter, 0) # Overview_LookupBook is also sorted according to distance, # # that's why delete the same index as above. self.TotaNumofCellSelected -= 1 def SaveCellsProArray(self): np.save( os.path.join( self.Tag_folder, datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + '_CellsProperties'), self.Overview_LookupBook) def ResetRankCoord(self): self.popnexttopimgcounter = 0
class AppForm(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) # Read data from source or leakage fraction file self.get_file_data() self.main_frame = QWidget() self.setCentralWidget(self.main_frame) # Create the Figure, Canvas, and Axes self.dpi = 100 self.fig = Figure((5.0, 15.0), dpi=self.dpi) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) self.axes = self.fig.add_subplot(111) # Create the navigation toolbar, tied to the canvas self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) # Grid layout at bottom self.grid = QGridLayout() # Overall layout self.vbox = QVBoxLayout() self.vbox.addWidget(self.canvas) self.vbox.addWidget(self.mpl_toolbar) self.vbox.addLayout(self.grid) self.main_frame.setLayout(self.vbox) # Tally selections label_tally = QLabel("Tally:") self.tally = QComboBox() self.tally.addItems([(str(i + 1)) for i in range(self.n_tallies)]) self.connect(self.tally, SIGNAL('activated(int)'), self._update) self.connect(self.tally, SIGNAL('activated(int)'), self.populate_boxes) self.connect(self.tally, SIGNAL('activated(int)'), self.on_draw) # Planar basis label_basis = QLabel("Basis:") self.basis = QComboBox() self.basis.addItems(['xy', 'yz', 'xz']) # Update window when 'Basis' selection is changed self.connect(self.basis, SIGNAL('activated(int)'), self._update) self.connect(self.basis, SIGNAL('activated(int)'), self.populate_boxes) self.connect(self.basis, SIGNAL('activated(int)'), self.on_draw) # Axial level within selected basis label_axial_level = QLabel("Axial Level:") self.axial_level = QComboBox() self.connect(self.axial_level, SIGNAL('activated(int)'), self.on_draw) # Add Option to plot mean or uncertainty label_mean = QLabel("Mean or Uncertainty:") self.mean = QComboBox() self.mean.addItems(['Mean','Absolute Uncertainty', 'Relative Uncertainty']) # Update window when mean selection is changed self.connect(self.mean, SIGNAL('activated(int)'), self.on_draw) self.label_filters = QLabel("Filter options:") # Labels for all possible filters self.labels = {'cell': 'Cell: ', 'cellborn': 'Cell born: ', 'surface': 'Surface: ', 'material': 'Material', 'universe': 'Universe: ', 'energyin': 'Energy in: ', 'energyout': 'Energy out: '} # Empty reusable labels self.qlabels = {} for j in range(8): self.nextLabel = QLabel self.qlabels[j] = self.nextLabel # Reusable comboboxes labelled with filter names self.boxes = {} for key in self.labels.keys(): self.nextBox = QComboBox() self.connect(self.nextBox, SIGNAL('activated(int)'), self.on_draw) self.boxes[key] = self.nextBox # Combobox to select among scores self.score_label = QLabel("Score:") self.scoreBox = QComboBox() for item in self.tally_scores[0]: self.scoreBox.addItems(str(item)) self.connect(self.scoreBox, SIGNAL('activated(int)'), self.on_draw) # Fill layout self.grid.addWidget(label_tally, 0, 0) self.grid.addWidget(self.tally, 0, 1) self.grid.addWidget(label_basis, 1, 0) self.grid.addWidget(self.basis, 1, 1) self.grid.addWidget(label_axial_level, 2, 0) self.grid.addWidget(self.axial_level, 2, 1) self.grid.addWidget(label_mean, 3, 0) self.grid.addWidget(self.mean, 3, 1) self.grid.addWidget(self.label_filters, 4, 0) self._update() self.populate_boxes() self.on_draw() def get_file_data(self): # Get data file name from "open file" browser filename = QFileDialog.getOpenFileName(self, 'Select statepoint file', '.') # Create StatePoint object and read in data self.datafile = StatePoint(str(filename)) self.datafile.read_results() self.datafile.generate_stdev() self.setWindowTitle('Core Map Tool : ' + str(self.datafile.path)) # Set maximum colorbar value by maximum tally data value self.maxvalue = self.datafile.tallies[0].results.max() self.labelList = [] # Read mesh dimensions # for mesh in self.datafile.meshes: # self.nx, self.ny, self.nz = mesh.dimension # Read filter types from statepoint file self.n_tallies = len(self.datafile.tallies) self.tally_list = [] for tally in self.datafile.tallies: self.filter_types = [] for f in tally.filters: self.filter_types.append(f) self.tally_list.append(self.filter_types) # Read score types from statepoint file self.tally_scores = [] for tally in self.datafile.tallies: self.score_types = [] for s in tally.scores: self.score_types.append(s) self.tally_scores.append(self.score_types) # print 'self.tally_scores = ', self.tally_scores def on_draw(self): """ Redraws the figure """ # print 'Calling on_draw...' # Get selected basis, axial_level and stage basis = self.basis.currentIndex() + 1 axial_level = self.axial_level.currentIndex() + 1 is_mean = self.mean.currentIndex() # Create spec_list spec_list = [] for tally in self.datafile.tallies[self.tally.currentIndex()].filters.values(): if tally.type == 'mesh': continue index = self.boxes[tally.type].currentIndex() spec_list.append((tally.type, index)) # Take is_mean and convert it to an index of the score score_loc = is_mean if score_loc > 1: score_loc = 1 if self.basis.currentText() == 'xy': matrix = np.zeros((self.nx, self.ny)) for i in range(self.nx): for j in range(self.ny): matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, j, axial_level))], self.scoreBox.currentIndex())[score_loc] # Calculate relative uncertainty from absolute, if # requested if is_mean == 2: # Take care to handle zero means when normalizing mean_val = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, j, axial_level))], self.scoreBox.currentIndex())[0] if mean_val > 0.0: matrix[i,j] = matrix[i,j] / mean_val else: matrix[i,j] = 0.0 elif self.basis.currentText() == 'yz': matrix = np.zeros((self.ny, self.nz)) for i in range(self.ny): for j in range(self.nz): matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (axial_level, i, j))], self.scoreBox.currentIndex())[score_loc] # Calculate relative uncertainty from absolute, if # requested if is_mean == 2: # Take care to handle zero means when normalizing mean_val = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (axial_level, i, j))], self.scoreBox.currentIndex())[0] if mean_val > 0.0: matrix[i,j] = matrix[i,j] / mean_val else: matrix[i,j] = 0.0 else: matrix = np.zeros((self.nx, self.nz)) for i in range(self.nx): for j in range(self.nz): matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, axial_level, j))], self.scoreBox.currentIndex())[score_loc] # Calculate relative uncertainty from absolute, if # requested if is_mean == 2: # Take care to handle zero means when normalizing mean_val = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, axial_level, j))], self.scoreBox.currentIndex())[0] if mean_val > 0.0: matrix[i,j] = matrix[i,j] / mean_val else: matrix[i,j] = 0.0 # print spec_list # Clear the figure self.fig.clear() # Make figure, set up color bar self.axes = self.fig.add_subplot(111) cax = self.axes.imshow(matrix, vmin=0.0, vmax=matrix.max(), interpolation="nearest") self.fig.colorbar(cax) self.axes.set_xticks([]) self.axes.set_yticks([]) self.axes.set_aspect('equal') # Draw canvas self.canvas.draw() def _update(self): '''Updates widget to display new relevant comboboxes and figure data ''' # print 'Calling _update...' self.mesh = self.datafile.meshes[ self.datafile.tallies[ self.tally.currentIndex()].filters['mesh'].bins[0] - 1] self.nx, self.ny, self.nz = self.mesh.dimension # Clear axial level combobox self.axial_level.clear() # Repopulate axial level combobox based on current basis selection if (self.basis.currentText() == 'xy'): self.axial_level.addItems([str(i+1) for i in range(self.nz)]) elif (self.basis.currentText() == 'yz'): self.axial_level.addItems([str(i+1) for i in range(self.nx)]) else: self.axial_level.addItems([str(i+1) for i in range(self.ny)]) # Determine maximum value from current tally data set self.maxvalue = self.datafile.tallies[ self.tally.currentIndex()].results.max() # print self.maxvalue # Clear and hide old filter labels for item in self.labelList: item.clear() # Clear and hide old filter boxes for j in self.labels: self.boxes[j].clear() self.boxes[j].setParent(None) self.update() def populate_boxes(self): # print 'Calling populate_boxes...' n = 5 labels = {'cell': 'Cell : ', 'cellborn': 'Cell born: ', 'surface': 'Surface: ', 'material': 'Material: ', 'universe': 'Universe: '} # For each filter in newly-selected tally, name a label and fill the # relevant combobox with options for element in self.tally_list[self.tally.currentIndex()]: nextFilter = self.datafile.tallies[ self.tally.currentIndex()].filters[element] if element == 'mesh': continue label = QLabel(self.labels[element]) self.labelList.append(label) combobox = self.boxes[element] self.grid.addWidget(label, n, 0) self.grid.addWidget(combobox, n, 1) n += 1 # print element if element in ['cell', 'cellborn', 'surface', 'material', 'universe']: combobox.addItems([str(i) for i in nextFilter.bins]) # for i in nextFilter.bins: # print i elif element == 'energyin' or element == 'energyout': for i in range(nextFilter.length): text = (str(nextFilter.bins[i]) + ' to ' + str(nextFilter.bins[i+1])) combobox.addItem(text) self.scoreBox.clear() for item in self.tally_scores[self.tally.currentIndex()]: self.scoreBox.addItem(str(item)) self.grid.addWidget(self.score_label, n, 0) self.grid.addWidget(self.scoreBox, n, 1)
class ProjectFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title='Tensorflow Project', pos=(50, 50), size=(900, 500)) self.Bind(wx.EVT_CLOSE, self.OnClose) # create menu menu_bar = wx.MenuBar() menu = wx.Menu() m_open = menu.Append(-1, "&Open\tCtrl+O", "Open project directory") self.Bind(wx.EVT_MENU, self.OnOpen, m_open) m_exit = menu.Append(-1, "&Quit\tCtrl+Q", "Close window and exit program") self.Bind(wx.EVT_MENU, self.OnClose, m_exit) menu_bar.Append(menu, "&File") self.SetMenuBar(menu_bar) # create status bar self.CreateStatusBar() # create basic layout project_panel = wx.Panel(self) project_sizer = wx.BoxSizer(wx.VERTICAL) project_panel.SetSizer(project_sizer) root_sizer = wx.BoxSizer(wx.HORIZONTAL) root_sizer.Add(project_panel, 1, wx.EXPAND) # create project tree self.project_tree = wx.TreeCtrl(project_panel, style=wx.TR_MULTIPLE | wx.TR_HAS_BUTTONS) self.project_tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectChanged) # n = project_tree.AddRoot("Root Node") # project_tree.AppendItem(n, "hello") project_sizer.Add(self.project_tree, 1, wx.EXPAND) # fill out remaining space for now self.figure = Figure(figsize=(5, 4), dpi=100) self.canvas = FigureCanvas(self, -1, self.figure) root_sizer.Add(self.canvas, 2, wx.EXPAND) # axes = self.figure.add_subplot(111) # t = np.linspace(0.0, 3.0, 0.01) # s = np.sin(2 * np.pi * t) # axes.plot(t, s) self.Bind(wx.EVT_PAINT, self.OnPaint) # layout self.SetAutoLayout(True) self.SetSizer(root_sizer) self.Layout() def OnSelectChanged(self, event): selected = self.project_tree.GetSelections() selected_scalars = [] print('SelectChanged:', selected) for s in selected: data = self.project_tree.GetItemData(s) if 'type' in data: if data['type'] == 'scalar': scalars = self.em.Scalars('train', data['tag']) selected_scalars.append((data['tag'], scalars)) if len(selected_scalars) > 0: self.PlotScalars(selected_scalars) def OnPaint(self, event): self.canvas.draw() event.Skip() def OnClose(self, event): self.Destroy() def OnOpen(self, event): dialog = wx.DirDialog(self, "Open Project", style=wx.DD_DEFAULT_STYLE) if dialog.ShowModal() == wx.ID_CANCEL: return self.project_path = dialog.GetPath() self.LoadProject(self.project_path) def PlotScalars(self, scalars): self.figure.clear() for s in scalars: tag = s[0] data = s[1] axes = self.figure.add_subplot(111) xs = [s[2] for s in data] ys = [s[1] for s in data] axes.plot(ys, xs) self.canvas.draw() def LoadProject(self, path): self.project_tree.DeleteAllItems() project_name = path.split('/')[-1] root_node = self.project_tree.AddRoot(project_name) checkpoint_files = [] event_files = [] graph_file = None options_file = None model_node = None for root, dirs, files in os.walk(path): new_path = root.split(os.sep) # print(os.path.basename(root)) if 'options.config' in files or 'graph.pbtxt' in files: model_node = self.project_tree.AppendItem( root_node, new_path[-1]) graph_node = self.project_tree.AppendItem(model_node, "Graph") options_node = self.project_tree.AppendItem( model_node, "Options") events_node = self.project_tree.AppendItem( model_node, "Events") checkpoints_node = self.project_tree.AppendItem( model_node, "Checkpoints") for file in files: r = re.match('(checkpoint-[0-9]+).meta', file) if r: checkpoint_files.append(r.group(1)) self.project_tree.AppendItem(checkpoints_node, r.group(1)) elif file == 'graph.pbtxt': graph_file = os.path.join(root, file) self.project_tree.AppendItem(graph_node, file) elif file == 'options.config': options_file = os.path.join(root, file) self.project_tree.AppendItem(options_node, file) elif re.match('events.out.*', file): event_files.append(os.path.join(root, file)) self.project_tree.AppendItem(events_node, file) unique_subdirs = set([os.path.dirname(fn) for fn in event_files]) self.em = EventMultiplexer() for d in unique_subdirs: self.em.AddRunsFromDirectory(d)
class QPyMcaMatplotlibImage(FigureCanvas): def __init__(self, parent, imageData=None, dpi=100, size=(5, 5), xaxis='off', yaxis='off', xlabel='', ylabel='', nxlabels=0, nylabels=0, colorbar=None, title='', interpolation='nearest', colormap=None, linlogcolormap='linear', origin='lower', contour='off', contourlabels='on', contourlabelformat='%.3f', contourlevels=2, contourlinewidth=10, extent=None, xpixelsize=1.0, ypixelsize=1.0, xorigin=0.0, yorigin=0.0, xlimits=None, ylimits=None, vlimits=None): self.figure = Figure(figsize=size, dpi=dpi) #in inches #How to set this color equal to the other widgets color? #self.figure.set_facecolor('1.0') #self.figure.set_edgecolor('1.0') FigureCanvas.__init__(self, self.figure) FigureCanvas.setSizePolicy(self, qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.imageData = imageData self.pixmapImage = None self.config={'xaxis':xaxis, 'yaxis':yaxis, 'title':title, 'xlabel':xlabel, 'ylabel':ylabel, 'nxlabels':nxlabels, 'nylabels':nylabels, 'colorbar':colorbar, 'colormap':colormap, 'linlogcolormap':linlogcolormap, 'interpolation':interpolation, 'origin':origin, 'contour':contour, 'contourlabels':contourlabels, 'contourlabelformat':contourlabelformat, 'contourlevels':contourlevels, 'contourlinewidth':contourlinewidth, 'extent':extent, 'imagebackground':'black', 'xorigin':xorigin, 'yorigin':yorigin, 'xpixelsize':xpixelsize, 'ypixelsize':ypixelsize, 'zoomxmin':None, 'zoomxmax':None, 'zoomymin':None, 'zoomymax':None, 'valuemin':None, 'valuemax':None, 'xlimits':xlimits, 'ylimits':ylimits, 'vlimits':vlimits, 'outputdpi':dpi} #generate own colormaps cdict = {'red': ((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)), 'green': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0))} self.__redCmap = LinearSegmentedColormap('red',cdict,256) cdict = {'red': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'green': ((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)), 'blue': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0))} self.__greenCmap = LinearSegmentedColormap('green',cdict,256) cdict = {'red': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'green': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 0.0, 0.0), (1.0, 1.0, 1.0))} self.__blueCmap = LinearSegmentedColormap('blue',cdict,256) # Temperature as defined in spslut cdict = {'red': ((0.0, 0.0, 0.0), (0.5, 0.0, 0.0), (0.75, 1.0, 1.0), (1.0, 1.0, 1.0)), 'green': ((0.0, 0.0, 0.0), (0.25, 1.0, 1.0), (0.75, 1.0, 1.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 1.0, 1.0), (0.25, 1.0, 1.0), (0.5, 0.0, 0.0), (1.0, 0.0, 0.0))} #but limited to 256 colors for a faster display (of the colorbar) self.__temperatureCmap = LinearSegmentedColormap('temperature', cdict, 256) #reversed gray cdict = {'red': ((0.0, 1.0, 1.0), (1.0, 0.0, 0.0)), 'green': ((0.0, 1.0, 1.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 1.0, 1.0), (1.0, 0.0, 0.0))} self.__reversedGrayCmap = LinearSegmentedColormap('yerg', cdict, 256) self.updateFigure() def updateFigure(self): self.figure.clear() if (self.imageData is None) and \ (self.pixmapImage is None): return # The axes self.axes = self.figure.add_axes([.15, .15, .75, .8]) if self.config['xaxis'] == 'off': self.axes.xaxis.set_visible(False) else: self.axes.xaxis.set_visible(True) nLabels = self.config['nxlabels'] if nLabels not in ['Auto', 'auto', '0', 0]: self.axes.xaxis.set_major_locator(MaxNLocator(nLabels)) else: self.axes.xaxis.set_major_locator(AutoLocator()) if self.config['yaxis'] == 'off': self.axes.yaxis.set_visible(False) else: self.axes.yaxis.set_visible(True) nLabels = self.config['nylabels'] if nLabels not in ['Auto', 'auto', '0', 0]: self.axes.yaxis.set_major_locator(MaxNLocator(nLabels)) else: self.axes.yaxis.set_major_locator(AutoLocator()) if self.pixmapImage is not None: self._updatePixmapFigure() return interpolation = self.config['interpolation'] origin = self.config['origin'] cmap = self.__temperatureCmap ccmap = cm.gray if self.config['colormap'] in ['grey','gray']: cmap = cm.gray ccmap = self.__temperatureCmap elif self.config['colormap'] in ['yarg','yerg']: cmap = self.__reversedGrayCmap ccmap = self.__temperatureCmap elif self.config['colormap']=='jet': cmap = cm.jet elif self.config['colormap']=='hot': cmap = cm.hot elif self.config['colormap']=='cool': cmap = cm.cool elif self.config['colormap']=='copper': cmap = cm.copper elif self.config['colormap']=='spectral': cmap = cm.spectral elif self.config['colormap']=='hsv': cmap = cm.hsv elif self.config['colormap']=='rainbow': cmap = cm.gist_rainbow elif self.config['colormap']=='red': cmap = self.__redCmap elif self.config['colormap']=='green': cmap = self.__greenCmap elif self.config['colormap']=='blue': cmap = self.__blueCmap elif self.config['colormap']=='temperature': cmap = self.__temperatureCmap elif self.config['colormap'] == 'paired': cmap = cm.Paired elif self.config['colormap'] == 'paired_r': cmap = cm.Paired_r elif self.config['colormap'] == 'pubu': cmap = cm.PuBu elif self.config['colormap'] == 'pubu_r': cmap = cm.PuBu_r elif self.config['colormap'] == 'rdbu': cmap = cm.RdBu elif self.config['colormap'] == 'rdbu_r': cmap = cm.RdBu_r elif self.config['colormap'] == 'gist_earth': cmap = cm.gist_earth elif self.config['colormap'] == 'gist_earth_r': cmap = cm.gist_earth_r elif self.config['colormap'] == 'blues': cmap = cm.Blues elif self.config['colormap'] == 'blues_r': cmap = cm.Blues_r elif self.config['colormap'] == 'ylgnbu': cmap = cm.YlGnBu elif self.config['colormap'] == 'ylgnbu_r': cmap = cm.YlGnBu_r else: print("Unsupported colormap %s" % self.config['colormap']) if self.config['extent'] is None: h, w = self.imageData.shape x0 = self.config['xorigin'] y0 = self.config['yorigin'] w = w * self.config['xpixelsize'] h = h * self.config['ypixelsize'] if origin == 'upper': extent = (x0, w+x0, h+y0, y0) else: extent = (x0, w+x0, y0, h+y0) else: extent = self.config['extent'] vlimits = self.__getValueLimits() if vlimits is None: imageData = self.imageData vmin = self.imageData.min() vmax = self.imageData.max() else: vmin = min(vlimits[0], vlimits[1]) vmax = max(vlimits[0], vlimits[1]) imageData = self.imageData.clip(vmin,vmax) if self.config['linlogcolormap'] != 'linear': if vmin <= 0: if vmax > 0: vmin = min(imageData[imageData>0]) else: vmin = 0.0 vmax = 1.0 self._image = self.axes.imshow(imageData.clip(vmin,vmax), interpolation=interpolation, origin=origin, cmap=cmap, extent=extent, norm=LogNorm(vmin, vmax)) else: self._image = self.axes.imshow(imageData, interpolation=interpolation, origin=origin, cmap=cmap, extent=extent, norm=Normalize(vmin, vmax)) ylim = self.axes.get_ylim() if self.config['colorbar'] is not None: barorientation = self.config['colorbar'] self._colorbar = self.figure.colorbar(self._image, orientation=barorientation) #contour plot if self.config['contour'] != 'off': dataMin = imageData.min() dataMax = imageData.max() ncontours = int(self.config['contourlevels']) levels = (numpy.arange(ncontours)) *\ (dataMax - dataMin)/float(ncontours) contourlinewidth = int(self.config['contourlinewidth'])/10. if self.config['contour'] == 'filled': self._contour = self.axes.contourf(imageData, levels, origin=origin, cmap=ccmap, extent=extent) else: self._contour = self.axes.contour(imageData, levels, origin=origin, cmap=ccmap, linewidths=contourlinewidth, extent=extent) if self.config['contourlabels'] != 'off': self.axes.clabel(self._contour, fontsize=9, inline=1, fmt=self.config['contourlabelformat']) if 0 and self.config['colorbar'] is not None: if barorientation == 'horizontal': barorientation = 'vertical' else: barorientation = 'horizontal' self._ccolorbar=self.figure.colorbar(self._contour, orientation=barorientation, extend='both') self.__postImage(ylim) def getParameters(self): return self.config def setParameters(self, ddict): self.config.update(ddict) self.updateFigure() def setPixmapImage(self, image=None, bgr=False): if image is None: self.pixmapImage = None self.updateFigure() return if bgr: self.pixmapImage = image * 1 self.pixmapImage[:,:,0] = image[:,:,2] self.pixmapImage[:,:,2] = image[:,:,0] else: self.pixmapImage = image shape = self.pixmapImage.shape self.pixmapMask = numpy.ones(shape, numpy.uint8) shape = self.pixmapImage.shape if 0: # This is slow, but I do not expect huge images for i in range(shape[0]): for j in range(shape[1]): if (self.pixmapImage[i,j,0] == 0): if (self.pixmapImage[i,j,1] == 0): if (self.pixmapImage[i,j,2] == 0): self.pixmapMask[i,j,0:3] = [0, 0, 0] else: #the image is RGBA, so the sum when there is nothing is 255 s = self.pixmapImage.sum(axis=-1) self.pixmapMask[s==255, 0:3] = 0 self.updateFigure() def _updatePixmapFigure(self): interpolation = self.config['interpolation'] origin = self.config['origin'] if self.config['extent'] is None: h= self.pixmapImage.shape[0] w= self.pixmapImage.shape[1] x0 = self.config['xorigin'] y0 = self.config['yorigin'] w = w * self.config['xpixelsize'] h = h * self.config['ypixelsize'] if origin == 'upper': extent = (x0, w+x0, h+y0, y0) else: extent = (x0, w+x0, y0, h+y0) else: extent = self.config['extent'] if self.config['imagebackground'].lower() == 'white': if 0: self.pixmapImage[:] = (self.pixmapImage * self.pixmapMask) +\ (self.pixmapMask == 0) * 255 else: self.pixmapImage[self.pixmapMask == 0] = 255 elif self.config['imagebackground'].lower() == 'grey': if 0: self.pixmapImage[:] = (self.pixmapImage * self.pixmapMask) +\ (self.pixmapMask == 0) * 128 else: self.pixmapImage[self.pixmapMask == 0] = 128 else: if 0: self.pixmapImage[:] = (self.pixmapImage * self.pixmapMask) else: self.pixmapImage[self.pixmapMask == 0]= 0 self._image = self.axes.imshow(self.pixmapImage, interpolation=interpolation, origin=origin, extent=extent) ylim = self.axes.get_ylim() self.__postImage(ylim) def __getValueLimits(self): if (self.config['valuemin'] is not None) and\ (self.config['valuemax'] is not None) and\ (self.config['valuemin'] != self.config['valuemax']): vlimits = (self.config['valuemin'], self.config['valuemax']) elif self.config['vlimits'] is not None: vlimits = self.config['vlimits'] else: vlimits = None return vlimits def __postImage(self, ylim): self.axes.set_title(self.config['title']) self.axes.set_xlabel(self.config['xlabel']) self.axes.set_ylabel(self.config['ylabel']) origin = self.config['origin'] if (self.config['zoomxmin'] is not None) and\ (self.config['zoomxmax'] is not None)and\ (self.config['zoomxmax'] != self.config['zoomxmin']): xlimits = (self.config['zoomxmin'], self.config['zoomxmax']) elif self.config['xlimits'] is not None: xlimits = self.config['xlimits'] else: xlimits = None if (self.config['zoomymin'] is not None) and\ (self.config['zoomymax'] is not None) and\ (self.config['zoomymax'] != self.config['zoomymin']): ylimits = (self.config['zoomymin'], self.config['zoomymax']) elif self.config['ylimits'] is not None: ylimits = self.config['ylimits'] else: ylimits = None if ylimits is None: self.axes.set_ylim(ylim[0],ylim[1]) else: ymin = min(ylimits) ymax = max(ylimits) if origin == "lower": self.axes.set_ylim(ymin, ymax) else: self.axes.set_ylim(ymax, ymin) if xlimits is not None: xmin = min(xlimits) xmax = max(xlimits) self.axes.set_xlim(xmin, xmax) self.draw()
class myCanvas(FigureCanvas): def __init__(self): self.fig = Figure() FigureCanvas.__init__(self, self.fig) def plot1(self, xarray, yarray, zarray): self.fig.clear() self.ax = self.fig.add_subplot(111, projection='3d') self.ax.mouse_init(rotate_btn=1, zoom_btn=3) self.ax.scatter(0, 0, 0, 'ok') self.ax.scatter(xarray, yarray, zarray, marker='.', c=yarray, cmap='tab20b') self.ax.set_xlabel('X ') self.ax.set_ylabel('Y ') self.ax.set_zlabel('Z ') self.ax.legend(['Set', 'Origen']) self.draw() def ImprimirOBjetos(self, DD, TN, chch, nnn, cho): self.fig.clear() #plt.ion() #figura = plt.figure() self.ax = self.fig.add_subplot(111, projection='3d') self.ax.mouse_init(rotate_btn=1, zoom_btn=3) self.ax.set_xlim(min(DD[:, 0]) - 25, max(DD[:, 0]) + 25) self.ax.set_ylim(min(DD[:, 1]) - 25, max(DD[:, 1]) + 25) self.ax.set_zlim(min(DD[:, 2]) - 25, max(DD[:, 2]) + 25) # at = TN.shape vcolores = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k', 'b', 'g', 'r', 'c', 'm', 'y', 'k', 'b', 'g', 'r', 'c', 'm', 'y', 'k', 'b', 'g', 'r', 'c', 'm' ] vformas = [ 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '+', '+', '+', '+', '+', '+', '+', 'd', 'd', 'd', 'd', 'd' ] if (nnn == 0): # Sin datos ruido for ak in range(1, len(chch)): di1 = vcolores[ak] di2 = vformas[ak] # vl = TN[ak,:] vl = TN[ak, 0:int(chch[ak]), :] [xi, yi, zi] = np.transpose(vl) self.ax.scatter(xi, yi, zi, color=di1, marker=di2) self.ax.set_xlabel('eje x') self.ax.set_ylabel('eje y') self.ax.set_zlabel('eje z') #grafica.legend() self.draw() elif (nnn == 1): # Con datos ruido for ak in range(0, len(chch)): di1 = vcolores[ak] di2 = vformas[ak] vl = TN[ak, 0:int(chch[ak]), :] [xi, yi, zi] = np.transpose(vl) self.ax.scatter(xi, yi, zi, color=di1, marker=di2) self.ax.set_xlabel('eje x') self.ax.set_ylabel('eje y') self.ax.set_zlabel('eje z') #grafica.legend() self.draw() elif (nnn == 2): # Solo un cluster # for ak in range(0,at[0]): di1 = vcolores[cho] di2 = vformas[cho] vl = TN[cho, 0:int(chch[cho]), :] [xi, yi, zi] = np.transpose(vl) self.ax.scatter(xi, yi, zi, color=di1, marker=di2) self.ax.set_xlabel('eje x') self.ax.set_ylabel('eje y') self.ax.set_zlabel('eje z') #grafica.legend() self.draw()
class BarsFrame(wx.Frame): ''' The main frame of the application ''' title = title def __init__(self): wx.Frame.__init__(self, None, -1, self.title) self.para = paraValue self.create_menu() self.create_main_panel() for i in range(len(paraName)): #print paraName[i],paraType[i],self.para[i] if paraType[i] == 'bool': self.textbox[i].SetValue(self.para[i]) else: self.textbox[i].SetValue(str(self.para[i])) self.run_and_draw() def create_menu(self): self.menubar = wx.MenuBar() menu_file = wx.Menu() m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file") self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt) menu_file.AppendSeparator() m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit") self.Bind(wx.EVT_MENU, self.on_exit, m_exit) menu_help = wx.Menu() m_about = menu_help.Append(-1, "&About\tF1", "About the demo") self.Bind(wx.EVT_MENU, self.on_about, m_about) self.menubar.Append(menu_file, "&File") self.menubar.Append(menu_help, "&Help") self.SetMenuBar(self.menubar) def create_main_panel(self): ''' Creates the main panel with all the controls on it ''' self.panel = wx.Panel(self) self.dpi = 100 self.fig = Figure((7.0, 6.0), facecolor="white", dpi=self.dpi) self.canvas = FigCanvas(self.panel, -1, self.fig) self.label = [None] * len(paraName) self.textbox = [None] * len(paraName) for i in range(len(paraName)): self.label[i] = wx.StaticText(self.panel, -1, paraName[i]) if paraType[i] == "multipleline": self.textbox[i] = wx.TextCtrl(self.panel, size=(200, 70), style=wx.TE_MULTILINE) elif paraType[i] == 'bool': self.textbox[i] = wx.CheckBox(self.panel, size=(200, -1)) else: self.textbox[i] = wx.TextCtrl(self.panel, size=(200, -1)) #self.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter, self.textbox[i]) self.drawbutton = wx.Button(self.panel, -1, "RUN") self.Bind(wx.EVT_BUTTON, self.on_draw_button, self.drawbutton) self.hbox = wx.BoxSizer(wx.HORIZONTAL) self.hbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.hbox.AddSpacer(10) self.vbox = wx.BoxSizer(wx.VERTICAL) flags = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL for i in range(len(paraName)): self.vbox.Add(self.label[i], 0, border=3, flag=flags) self.vbox.Add(self.textbox[i], 0, border=3, flag=flags) self.vbox.Add(self.drawbutton, 0, border=3, flag=flags) self.vbox.AddSpacer(30) self.hbox.Add(self.vbox, 0, flag=wx.ALIGN_LEFT | wx.TOP) self.panel.SetSizer(self.hbox) self.hbox.Fit(self) def run_and_draw(self): ''' update ''' print('---------new simulation---------') for i in range(len(paraName)): if paraType[i] == 'int': self.para[i] = int(self.textbox[i].GetValue()) elif paraType[i] == 'float': self.para[i] = float(self.textbox[i].GetValue()) else: self.para[i] = self.textbox[i].GetValue() print(paraName[i], '(', paraType[i], ')', self.para[i]) self.fig.clear() run(self.fig, self.para, model) self.canvas.draw() def on_draw_button(self, event): self.run_and_draw() def on_text_enter(self, event): self.run_and_draw() def on_save_plot(self, event): file_choices = "PNG (*.png)|*.png" dlg = wx.FileDialog(self, message="Save plot as...", defaultDir=os.getcwd(), defaultFile="plot.png", wildcard=file_choices, style=wx.SAVE) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.canvas.print_figure(path, dpi=self.dpi) def on_exit(self, event): self.Destroy() def on_about(self, event): msg = ''' Population genetics simulation Author: Xuebing Wu ([email protected]) ''' dlg = wx.MessageDialog(self, msg, "About", wx.OK) dlg.ShowModal() dlg.Destroy()
class PlotRelatorio(FigureCanvas): def __init__(self, parent=None, width=1, height=1, dpi=75): self.fig = Figure(figsize=(width, height), dpi=dpi, facecolor="#C2D5E8") FigureCanvas.__init__(self, self.fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) self.cores = [ '#003C30', '#01665E', '#35978F', '#80CDC1', '#C7EAE5', '#F5F5F5', '#F6E8C3', '#DFC27D', '#BF812D', '#8C510A', '#543005' ] def plot(self, tabela, categorias, filtro): self.fig.clear() meses = tabela.index.copy() meses = meses.strftime('%m/%y') entrada = tabela["entrada"] saida = tabela["saida"] if filtro in [0, 3]: if filtro == 3: j = 111 else: j = 313 ax_linha = self.fig.add_subplot(j) ax_linha.clear() ax_linha.yaxis.grid(True, which='major', linewidth=1) ax_linha.xaxis.grid(True, linestyle="--", linewidth=0.5) linha_entrada = ax_linha.plot(meses, entrada, 'bD-') linha_entrada[0].set_lw(2) linha_saida = ax_linha.plot(meses, saida, 'rD-') linha_saida[0].set_lw(2) for label in ax_linha.xaxis.get_ticklabels(): label.set_rotation(10) ax_linha.set_facecolor('#C2D5E8') formatter = ticker.FormatStrFormatter('R$%1.0f') ax_linha.yaxis.set_major_formatter(formatter) lista_categorias = list(categorias.index) colunas = list(tabela.columns) outros = list( set(colunas) - set(lista_categorias + ["entrada", "saida"])) lista_categorias.append("outros") tabela["outros"] = tabela[outros].sum(axis=1) tabela = tabela[lista_categorias] labels = [] stack_total = [] stack_percet = [] for categoria in lista_categorias: labels.append(categoria) valores = list(tabela[categoria]) stack_total.append(list(tabela[categoria])) for i in range(0, len(list(tabela[categoria]))): print(valores[i]) if filtro in [0, 1]: y = np.vstack(stack_total) if filtro == 1: j = 111 else: j = 311 ax_total = self.fig.add_subplot(j) ax_total.clear() ax_total.yaxis.grid(True, which='major', linewidth=0.2) ax_total.xaxis.grid(True, linestyle="--", linewidth=0.1) ax_total.stackplot(meses, y, labels=labels, colors=self.cores) # ax_total.legend(loc='upper left') formatter = ticker.FormatStrFormatter('R$%1.0f') ax_total.yaxis.set_major_formatter(formatter) if filtro == 1: handles, labels = ax_total.get_legend_handles_labels() self.fig.legend(handles, labels, loc='upper center', ncol=4) ax_total.set_facecolor('#C2D5E8') if filtro in [0, 2]: tabela = tabela.divide(tabela.sum(axis=1), axis=0) print("ABV\n", tabela) for categoria in lista_categorias: stack_percet.append(list(tabela[categoria])) y = np.vstack(stack_percet) if filtro == 2: j = 111 else: j = 312 ax_perc = self.fig.add_subplot(j) ax_perc.clear() ax_perc.yaxis.grid(True, which='major', linewidth=0.2) ax_perc.xaxis.grid(True, linestyle="--", linewidth=0.1) ax_perc.stackplot(meses, y, labels=labels, colors=self.cores) handles, labels = ax_perc.get_legend_handles_labels() self.fig.legend(handles, labels, loc='upper center', ncol=4) # self.fig.legend(loc='upper left') ax_perc.set_facecolor('#C2D5E8') self.draw() def limpar(self): self.fig.clear() self.draw()
class Qt4Mpl2dCanvas(FigureCanvas): """ A customized Qt widget for matplotlib 2D image. It can be used to replace GraphicsView """ def __init__(self, parent): """ Initialization """ # Instantiating matplotlib Figure self.fig = Figure() self.fig.patch.set_facecolor('white') self.axes = self.fig.add_subplot(111) # return: matplotlib.axes.AxesSubplot # Initialize parent class and set parent FigureCanvas.__init__(self, self.fig) self.setParent(parent) # Set size policy to be able to expanding and resizable with frame FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # legend and color bar self._colorBar = None # Buffer of data self._currentArray2D = None # image management data structure self._currIndex = 0 self._imagePlotDict = dict() # image size self._xLimit = [0., 1.] self._yLimit = [0., 1.] return @property def array2d(self): """ get the matrix plot now :return: """ return self._currentArray2D def add_2d_plot(self, array2d, x_min, x_max, y_min, y_max, hold_prev, yticklabels=None): """ Add a 2D plot Requirements: (1) a valid 2-dimensional numpy.ndarray (2) x_min, x_max, y_min, y_max are of right order Guarantees: a 2D fill-plot is made :param array2d: :param x_min: :param x_max: :param y_min: :param y_max: :param hold_prev: hold previous image. If False, all 2D image and polygon patches will be removed :param yticklabels: list of string for y ticks :return: """ # Check assert isinstance(array2d, np.ndarray), 'Input array2d must be a numpy array but not %s.' % str(type(array2d)) assert isinstance(x_min, int) and isinstance(x_max, int) and x_min < x_max, \ 'x_min = %s (of type %s) should be less than x_max = %s (of type %s).' \ '' % (str(x_min), str(type(x_min)), str(x_max), str(type(x_max))) assert isinstance(y_min, int) and isinstance(y_max, int) and y_min < y_max # Release the current image self.axes.hold(hold_prev) # show image img_plot = self.axes.imshow(array2d, extent=[x_min, x_max, y_min, y_max], interpolation='none') self._currentArray2D = array2d # set y ticks as an option: if yticklabels is not None: # it will always label the first N ticks even image is zoomed in # FUTURE-VZ : The way to set up the Y-axis ticks is wrong!" # self.axes.set_yticklabels(yticklabels) print('[Warning] The method to set up the Y-axis ticks to 2D image is wrong!') # explicitly set aspect ratio of the image self.axes.set_aspect('auto') # Set color bar. plt.colorbar() does not work! if self._colorBar is None: # set color map type img_plot.set_cmap('spectral') self._colorBar = self.fig.colorbar(img_plot) else: self._colorBar.update_bruteforce(img_plot) # Flush... self._flush() # Add the image management self._currIndex += 1 self._imagePlotDict[self._currIndex] = img_plot return self._currIndex def add_patch(self, patch): """ add an artist patch such as polygon :param patch: :return: """ self.axes.add_artist(patch) # Flush... self._flush() return def addImage(self, imagefilename): """ Add an image by file """ # set aspect to auto mode self.axes.set_aspect('auto') img = matplotlib.image.imread(str(imagefilename)) # lum_img = img[:,:,0] # FUTURE : refactor for image size, interpolation and origin imgplot = self.axes.imshow(img, extent=[0, 1000, 800, 0], interpolation='none', origin='lower') # Set color bar. plt.colorbar() does not work! if self._colorBar is None: # set color map type imgplot.set_cmap('spectral') self._colorBar = self.fig.colorbar(imgplot) else: self._colorBar.update_bruteforce(imgplot) self._flush() return def clear_canvas(self): """ Clear data including lines and image from canvas """ # clear the image for next operation self.axes.hold(False) # clear 2D image self.axes.cla() # Try to clear the color bar if len(self.fig.axes) > 1: self.fig.delaxes(self.fig.axes[1]) self._colorBar = None # This clears the space claimed by color bar but destroys sub_plot too. self.fig.clear() # Re-create subplot self.axes = self.fig.add_subplot(111) # END-FOR # flush/commit self._flush() return def plot_polygon(self, vertex_array, fill=False, color='w'): """ Plot a new polygon :param vertex_array: :param fill: :param color: :return: """ # check requirements assert isinstance(vertex_array, np.ndarray) assert isinstance(fill, bool) assert isinstance(color, str) # plot polygon p = plt.Polygon(vertex_array, fill=fill, color=color) self.axes.add_artist(p) # Flush... self._flush() return p @property def x_min(self): """ x minimum :return: """ return self._xLimit[0] @property def x_max(self): """ maximum x :return: """ return self._xLimit[1] @property def y_min(self): """ minimum y :return: """ return self._yLimit[0] @property def y_max(self): """ maximum y :return: """ return self._yLimit[1] def _flush(self): """ A dirty hack to flush the image """ w, h = self.get_width_height() self.resize(w+1, h) self.resize(w, h) return
class MultiplotWidget(Canvas): """A widget to plot all permutation of feature channels as an overview.""" #__pyqtSignals__ = ("featureRedrawRequired()") # define the signal featureRedrawRequired = Signal() def __init__(self, parent=None): self.figure = Figure() Canvas.__init__(self, self.figure) self.setParent(parent) pal = self.palette().window().color() bgcolor = (pal.red() / 255.0, pal.blue() / 255.0, pal.green() / 255.0) self.figure.clear() self.figure.set_facecolor(bgcolor) # Set up the feature axes self.figure.subplots_adjust(hspace=0.000, wspace=0.000, bottom=0.0, top=1, left=0.0, right=1) Canvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) Canvas.updateGeometry(self) self.prof_limits = {} # Properties describing how to draw the clusters self.unclustered = True self.refractory = True self.exclusive = True self.markersize = 1 self.ptype = -2 self.feature = None def setFeatureX(self, feature): self.setFeature(feature) def setFeatureY(self, feature): pass def setChanX(self, chan): pass def setChanY(self, chan): pass @Slot(bool) def setShowUnclustered(self, show): self.unclustered = show #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() @Slot(bool) def setUnclusteredExclusive(self, excl): self.exclusive = excl #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() @Slot(bool) def setRefractory(self, show): self.refractory = show #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() @Slot(int) def setMarkerSize(self, size): self.markersize = size #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() @Slot(int) def setPlotType(self, ptype): self.ptype = ptype #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() def resetLimits(self): #self.prof_limits_reference = None self.prof_limits_reference = {} ##self.emit(SIGNAL("featureRedrawRequired()")) #self.featureRedrawRequired.emit() # These are not provided as signals since there is some non trivial # logic the main form needs to perform first def setFeature(self, name): self.feature = name self.figure.clear() self.axes = {} self.resetLimits() #self.emit(SIGNAL("featureRedrawRequired()")) self.featureRedrawRequired.emit() # Given a set of spike and cluster data, create the figure def updatePlot(self, spikeset, junk): if self.feature is None: return clusters = spikeset.clusters data = spikeset.featureByName(self.feature).data chans = data.shape[1] combs = scipy.misc.comb(chans, 2) plots_x = np.ceil(np.sqrt(combs)) plots_y = np.ceil(float(combs) / plots_x) cl_list = clusters + [junk] count = 0 # Iterate over projections for proj_x in range(0, chans): for proj_y in range(proj_x + 1, chans): count += 1 tw = (proj_x, proj_y) if tw not in self.axes.keys(): self.axes[(proj_x, proj_y)] = self.figure.add_subplot( plots_y, plots_x, count) xdata = data[:, proj_x] ydata = data[:, proj_y] self.axes[tw].hold(False) if not tw in self.prof_limits_reference.keys(): w = np.array([True] * spikeset.N) if not junk._visible: w[junk.member] = False temp = ([np.min(xdata[w]), np.max(xdata[w])], [np.min(ydata[w]), np.max(ydata[w])]) w_x = (temp[0][1] - temp[0][0]) * 0.01 w_y = (temp[1][1] - temp[1][0]) * 0.01 self.prof_limits_reference[tw] = ([ temp[0][0] - w_x, temp[0][1] + w_x ], [temp[1][0] - w_y, temp[1][1] + w_y]) self.prof_limits[tw] = self.prof_limits_reference[tw] # Scatter Plot if self.ptype == -2: #Plot the unclustered spikes if self.unclustered: w = np.array([True] * spikeset.N) if self.exclusive: for cluster in clusters + [junk]: w[cluster.member] = False self.axes[tw].plot(xdata[w], ydata[w], linestyle='None', marker='o', markersize=self.markersize, markerfacecolor='k', markeredgecolor='k', alpha=1.0) self.axes[tw].hold(True) # Iterate over clusters for cluster in cl_list: if not cluster._visible: continue col = tuple(map(lambda s: s / 255.0, cluster.color)) # Plot the cluster spikes self.axes[tw].plot(xdata[cluster.member], ydata[cluster.member], marker='o', markersize=self.markersize, markerfacecolor=col, markeredgecolor=col, linestyle='None', alpha=0.99) self.axes[tw].hold(True) # Plot refractory spikes if self.refractory: self.axes[tw].plot(xdata[cluster.refractory], ydata[cluster.refractory], marker='o', markersize=5, markerfacecolor='k', markeredgecolor='k', linestyle='None') # Do a density plot else: w = np.array([False] * spikeset.N) if self.unclustered: w = np.array([True] * spikeset.N) if self.exclusive: for cluster in clusters + [junk]: w[cluster.member] = False for cluster in [ cluster for cluster in cl_list if cluster._visible ]: w[cluster.member] = True if not np.any(w): w[0] = True # Histogram routine fails with empty data bins_x = np.linspace(self.prof_limits[tw][0][0], self.prof_limits[tw][0][1], 100) bins_y = np.linspace(self.prof_limits[tw][1][0], self.prof_limits[tw][1][1], 100) self.axes[tw].cla() self.axes[tw].set_xlim(self.prof_limits[tw][0]) self.axes[tw].set_ylim(self.prof_limits[tw][1]) count = np.histogram2d(xdata[w], ydata[w], [bins_x, bins_y])[0] count = ndimage.filters.gaussian_filter(count, 0.5) if self.ptype == -3: self.axes[tw].imshow(count.T, cmap=mpl.cm.gist_earth_r, aspect='auto', extent=self.axes[tw].get_xlim() + self.axes[tw].get_ylim()[::-1]) else: self.axes[tw].imshow(np.log(count + 1).T, cmap=mpl.cm.gist_earth_r, aspect='auto', extent=self.axes[tw].get_xlim() + self.axes[tw].get_ylim()[::-1]) # Iterate over clusters for refractory spikes if self.refractory: self.axes[tw].hold(True) for cluster in cl_list: if not cluster._visible: continue # Plot refractory spikes self.axes[tw].plot(xdata[cluster.refractory], ydata[cluster.refractory], marker='o', markersize=3, markerfacecolor='k', markeredgecolor='k', linestyle='None') self.axes[tw].set_xlim(self.prof_limits[tw][0]) self.axes[tw].set_ylim(self.prof_limits[tw][1]) for tick in self.axes[tw].xaxis.get_major_ticks(): tick.set_pad(-15) for tick in self.axes[tw].yaxis.get_major_ticks(): tick.set_pad(-20) tick.label2.set_horizontalalignment('left') # Now draw the boundaries for cluster in cl_list: if not cluster._visible: continue # Limit boundaries with solid line bounds = cluster.getBoundaries(self.feature, proj_x, self.feature, proj_y) for bound in bounds: col = tuple(map(lambda s: s / 255.0, cluster.color)) bound.draw(self.axes[tw], color=col, linestyle='-') # Addition boundaries with dashed line bounds = cluster.getBoundaries(self.feature, proj_x, self.feature, proj_y, 'add') for bound in bounds: col = tuple(map(lambda s: s / 255.0, cluster.color)) bound.draw(self.axes[tw], color=col, linestyle='--')