Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
    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))
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
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
Ejemplo n.º 11
0
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])
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
Archivo: wxFix.py Proyecto: bmazin/SDR
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
Ejemplo n.º 14
0
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()
Ejemplo n.º 15
0
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()
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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()
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
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()
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
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()
Ejemplo n.º 24
0
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()
Ejemplo n.º 26
0
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)
Ejemplo n.º 27
0
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)
Ejemplo n.º 28
0
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]
Ejemplo n.º 29
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
Ejemplo n.º 30
0
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])
Ejemplo n.º 31
0
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())))
Ejemplo n.º 32
0
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





        





            
Ejemplo n.º 33
0
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
Ejemplo n.º 34
0
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)
Ejemplo n.º 35
0
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')
Ejemplo n.º 36
0
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)
Ejemplo n.º 37
0
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()
Ejemplo n.º 38
0
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
Ejemplo n.º 39
0
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()
Ejemplo n.º 40
0
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)
Ejemplo n.º 41
0
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()
Ejemplo n.º 42
0
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))
Ejemplo n.º 43
0
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)
Ejemplo n.º 44
0
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)
Ejemplo n.º 45
0
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))
Ejemplo n.º 46
0
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()
Ejemplo n.º 47
0
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
Ejemplo n.º 48
0
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()
Ejemplo n.º 49
0
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)
Ejemplo n.º 50
0
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()
Ejemplo n.º 51
0
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
Ejemplo n.º 52
0
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
Ejemplo n.º 53
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)
Ejemplo n.º 54
0
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)
Ejemplo n.º 55
0
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()
Ejemplo n.º 56
0
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()
Ejemplo n.º 57
0
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()
Ejemplo n.º 58
0
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()
Ejemplo n.º 59
0
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
Ejemplo n.º 60
0
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='--')