Пример #1
0
class CanvasFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "CanvasFrame", size=(550, 350))
        color = wx.Colour("WHITE")
        self.SetBackgroundColour(color)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)
        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.SetSizerAndFit(self.sizer)
        self.add_toolbar()

    def add_toolbar(self):
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if wx.Platform == "__WXMAC__":
            self.SetToolBar(self.toolbar)
        else:
            tw, th = self.toolbar.GetSize()
            fw, fh = self.canvas.GetSize()
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        self.toolbar.update()

    def OnPaint(self, event):
        self.canvas.draw()
Пример #2
0
class PlotPanel(wx.Panel):
	"""
	A panel on which is drawn the map with wanted data.
	"""
	def __init__(self, parent, size : tuple, dataset : nc.Dataset, map_options : dict, presets : dict, tb_option : bool = True):
		super(PlotPanel, self).__init__(parent=parent, id=wx.ID_ANY, size=size)
		self.parent = parent
		self.dataset = dataset
		self.map_options = map_options
		self.presets = presets

		self.figure = MplFig(figsize=(10.8, 6))
		self.figure.set_facecolor('xkcd:grey')
		self.axes = self.figure.add_subplot(111)
		self.canvas = FigureCanvas(self, -1, self.figure)

		self.main_sizer = wx.BoxSizer(wx.VERTICAL)
		self.main_sizer.Add(self.canvas, 0, wx.EXPAND)

		self.toolbar = None
		if tb_option:
			self.add_toolbar()
			self.main_sizer.Add(self.toolbar, 0, wx.EXPAND | wx.LEFT, 20)
			self.toolbar.update()

		self.SetSizer(self.main_sizer)

	def draw(self):
		"""
		Draw the data and the map.
		"""
		# Create figure		
		fig = Figure(figure=self.figure, ax=self.axes, dataset=self.dataset, map_options=self.map_options, presets=self.presets)
		fig.plot_data()
		self.figure.tight_layout()
		self.figure.canvas.draw()

	def add_toolbar(self):
		"""
		Add a toolbar to the Canvas.
		"""
		self.toolbar = NavigationToolbar2Wx(self.canvas)
		self.toolbar.Realize()

		tw, th = self.toolbar.GetSize()
		cw, ch = self.canvas.GetSize()

		self.toolbar.SetSize(wx.Size(cw, ch))
class ring_pattern(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self,
                          parent,
                          -1,
                          "Ring Figure - " + parent.filename,
                          size=(550, 400))

        self.parent = parent

        iconFile = os.path.join(parent.parent.iconspath,
                                "diff_profiler_ico.ico")
        icon1 = wx.Icon(iconFile, wx.BITMAP_TYPE_ICO)

        self.SetIcon(icon1)

        self.mpl_old = self.parent.mpl_old

        self.background_sub = self.parent.background_sub
        self.prosim = self.parent.prosim
        self.plot_sim = self.parent.plot_sim
        self.ring_patt = []
        self.back_patt = []

        self.dirname = self.parent.dirname

        self.statbar = self.CreateStatusBar(
        )  # A Statusbar in the bottom of the window
        self.statbar.SetFieldsCount(2)
        self.statbar.SetStatusText("None", 1)

        # Setting up the menu. filemenu is a local variable at this stage.
        figmenu = wx.Menu()
        # use ID_ for future easy reference - much better than "48", "404" etc
        # The & character indicates the short cut key
        self.Save_evt = figmenu.Append(
            wx.NewId(), "&Save Figure",
            "Save the figure as vestor or highres image")
        self.BGSub_evt = figmenu.AppendCheckItem(
            wx.NewId(), "&Background Subtract",
            "Subtract the profile fitted background from the pattern image")
        self.ProSim_evt = figmenu.AppendCheckItem(
            wx.NewId(), "&Profile Simulation",
            "Show the ring pattern from a profile simulation")
        self.PeakSim_evt = figmenu.AppendCheckItem(
            wx.NewId(), "Peak &Simulation", "Show a peak simulation as rings")

        if self.parent.background_sub:
            self.BGSub_evt.Check(True)
        else:
            self.BGSub_evt.Enable(False)

        if self.parent.prosim:
            self.ProSim_evt.Check(True)
        else:
            self.ProSim_evt.Enable(False)

        if self.parent.plot_sim:
            self.PeakSim_evt.Check(True)
        else:
            self.PeakSim_evt.Enable(False)

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(figmenu,
                       "&Figure")  # Adding the "patternmenu" to the MenuBar

        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
        # Note - previous line stores the whole of the menu into the current object

        self.SetBackgroundColour(wx.Colour("WHITE"))

        self.figure = Figure(figsize=(8, 8), dpi=76)
        self.axes = self.figure.add_axes([0, 0, 1, 1],
                                         yticks=[],
                                         xticks=[],
                                         frame_on=False)  #

        self.canvas = FigureCanvas(self, -1, self.figure)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)

        # Capture the paint message
        self.Bind(wx.EVT_PAINT, self.OnPaint)

        self.toolbar = MyNavigationToolbar2(self, self.canvas, True)
        self.toolbar.Realize()

        tw, th = self.toolbar.GetSize()
        fw, fh = self.canvas.GetSize()
        self.toolbar.SetSize(wx.Size(fw, th))
        self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)

        # update the axes menu on the toolbar
        self.toolbar.update()

        # Define the code to be run when a menu option is selected
        if self.mpl_old:
            self.Bind(wx.EVT_MENU, self.toolbar.save, self.Save_evt)
        self.Bind(wx.EVT_MENU, self.toolbar.save_figure, self.Save_evt)
        self.Bind(wx.EVT_MENU, self.OnBGSub, self.BGSub_evt)
        self.Bind(wx.EVT_MENU, self.OnProSim, self.ProSim_evt)
        self.Bind(wx.EVT_MENU, self.OnPeakSim, self.PeakSim_evt)

        self.SetSizer(self.sizer)
        self.Fit()

        self.ring_plot()

    def OnBGSub(self, event):
        #self.id = event.GetId()
        if self.BGSub_evt.IsChecked():
            self.background_sub = 1
        else:
            self.background_sub = 0
        self.ring_plot()

    def OnProSim(self, event):
        #self.id = event.GetId()
        if self.ProSim_evt.IsChecked():
            self.prosim = 1
        else:
            self.prosim = 0
        self.ring_plot()

    def OnPeakSim(self, event):
        #self.id = event.GetId()
        if self.PeakSim_evt.IsChecked():
            self.plot_sim = 1
        else:
            self.plot_sim = 0

        self.axes.cla()
        self.ring_plot()

    def OnPaint(self, event):
        self.canvas.draw()
        event.Skip()

    def ring_plot(self):

        #rc('font', size=16)

        if self.parent.latex:
            rc('text', usetex=True)
            rc('font', family='serif')
        else:
            rc('text', usetex=False)
            rc('font', family='sans-serif')
            rc('mathtext', fontset='custom')

        self.origin = [round(self.parent.C[1]), round(self.parent.C[0])]

        #self.pattern_open_crop = self.parent.pattern_open[origin[0]-(self.parent.boxs-6):origin[0]+(self.parent.boxs-3),origin[1]-(self.parent.boxs-6):origin[1]+(self.parent.boxs-3)]
        self.pattern_open_crop = self.parent.pattern_open[
            int(self.origin[0] - (self.parent.boxs)):int(self.origin[0] +
                                                         (self.parent.boxs)),
            int(self.origin[1] - (self.parent.boxs)):int(self.origin[1] +
                                                         (self.parent.boxs))]

        if self.background_sub == 1:
            self.do_background_sub()

        self.axes.imshow(
            self.pattern_open_crop,
            cmap='gray',
            interpolation='bicubic',
            extent=(-self.parent.drdf.max(), self.parent.drdf.max(),
                    -self.parent.drdf.max(), self.parent.drdf.max()))

        if self.prosim == 1:
            self.do_prosim()
        if self.plot_sim == 1:
            self.do_plot_sim()

        #self.axes.plot(0,0,'+')
        #self.axes.axis('equal')
        self.axes.set_xlim(-self.parent.limit, self.parent.limit)
        self.axes.set_ylim(-self.parent.limit, self.parent.limit)
        #self.axes.xaxis.set_ticks_position('bottom')
        #self.axes.yaxis.set_ticks_position('left')

        self.axes.figure.canvas.draw()

    def do_background_sub(self):
        if self.back_patt == []:
            self.back_patt = make_profile_rings(
                self.parent.background - self.parent.background.min(),
                self.parent.drdf, self.origin, self.parent.boxs, True)
            #figure()
            #imshow(self.back_patt, cmap = 'gray')
            #show()
            print(self.pattern_open_crop.shape, self.back_patt.shape,
                  self.origin)
            print(self.parent.rdf.max(), self.back_patt.max(),
                  self.pattern_open_crop.max(), self.parent.rdf_max)

            middle_x = self.back_patt.shape[1] / 2

            self.back_patt = self.back_patt * self.parent.rdf_max
            #figure()
            #plot(self.back_patt[:,middle_x])
            #plot(self.pattern_open_crop[:,middle_x])
            #line = self.pattern_open_crop[:,middle_x] - self.back_patt[:,middle_x]
            #plot(line)
            #line[line < 0] = 0
            #plot(line)

        self.pattern_open_crop = self.pattern_open_crop.astype(np.float32)

        self.pattern_open_crop -= self.back_patt
        #plot(self.pattern_open_crop[:,middle_x])
        self.pattern_open_crop[self.pattern_open_crop < 0] = 0
        #plot(self.pattern_open_crop[:,middle_x])
        #show()
        print(self.pattern_open_crop.min(), self.pattern_open_crop.max())

    def do_plot_sim(self):
        sim_name = []
        marks = []
        color = ['#42D151', '#2AA298', '#E7E73C']
        marker = ['o', '^', 's']
        print(len(self.parent.simulations))  #, self.srdfb
        if len(self.parent.simulations) >= 3:
            sim_len_i = 3
        else:
            sim_len_i = len(self.parent.simulations)
        print(sim_len_i)  #,self.srdfb[sim_len_i[0]],self.sdrdfb[sim_len_i[0]]
        for col_index, simulation in enumerate(
                self.parent.simulations[-sim_len_i:]):
            sim_color = simulation.sim_color if simulation.sim_color else color[
                col_index]
            sim_name += [simulation.sim_label]
            sim = simulation.srdf
            sim_norm = sim / float(max(sim))
            #print(sim, max(sim[1:]), min(sim[1:]), sim_norm)
            marks += [
                self.axes.plot(0, 0, '-', color=sim_color, zorder=-10)[0]
            ]
            rect = patches.Rectangle((-self.parent.limit, -self.parent.limit),
                                     self.parent.limit,
                                     self.parent.limit,
                                     facecolor="none",
                                     edgecolor="none")
            self.axes.add_patch(rect)
            if not simulation.peak_index_labels:
                for radius in simulation.sdrdf:
                    #print(radius)
                    circ_mark = patches.Circle((0, 0),
                                               radius,
                                               fill=0,
                                               color=sim_color,
                                               linewidth=2,
                                               alpha=.7)
                    self.axes.add_patch(circ_mark)
                    circ_mark.set_clip_path(rect)
                    self.axes.set_autoscale_on(False)
                #sim_index = nonzero(self.srdfb[i]!=0)
            else:
                j = 0
                for i, label in enumerate(simulation.peak_index_labels[::-1]):
                    #print(label)
                    if label:
                        circ_mark = patches.Circle((0, 0),
                                                   simulation.sdrdf[::-1][i],
                                                   fill=0,
                                                   color=sim_color,
                                                   linewidth=2,
                                                   alpha=.7)
                        self.axes.add_patch(circ_mark)
                        circ_mark.set_clip_path(rect)
                        self.axes.set_autoscale_on(False)

                        if label.find('-') == -1:
                            label = r'(' + label + ')'
                        else:
                            label = r'$\mathsf{(' + label.replace(
                                '-', r'\bar ') + ')}$'
                        #print(label)
                        bbox_props = dict(boxstyle="round",
                                          fc=sim_color,
                                          ec="0.5",
                                          alpha=1,
                                          lw=1.5)
                        arrowprops = dict(
                            arrowstyle="wedge,tail_width=1.",
                            fc=sim_color,
                            ec="0.5",
                            alpha=.7,
                            patchA=None,
                            patchB=circ_mark,
                            relpos=(0.5, 0.5),
                        )
                        an = self.axes.annotate(label,
                                                xy=(0, 0),
                                                xytext=(.1 + col_index / 10.0,
                                                        .1 + j / 15.0),
                                                textcoords='axes fraction',
                                                ha="center",
                                                va="center",
                                                size=20,
                                                rotation=0,
                                                zorder=90 - col_index,
                                                picker=True,
                                                bbox=bbox_props,
                                                arrowprops=arrowprops)
                        an.draggable()
                        j += 1

        print(sim_name, marks)
        leg = self.axes.legend(marks,
                               sim_name,
                               loc='upper left',
                               shadow=0,
                               fancybox=True,
                               numpoints=1,
                               prop={'size': 16})
        frame = leg.get_frame()
        frame.set_alpha(0.7)
        for handle in leg.legendHandles:
            handle.set_linewidth(3.0)

    def do_prosim(self):
        if self.ring_patt == []:
            self.ring_patt = make_profile_rings(self.parent.prosim_int,
                                                self.parent.prosim_inv_d,
                                                self.origin, self.parent.boxs)
        self.axes.imshow(self.ring_patt[:, :self.ring_patt.shape[1] // 2],
                         cmap='gray',
                         origin='lower',
                         interpolation='bicubic',
                         extent=(-self.parent.prosim_inv_d.max(), 0,
                                 -self.parent.prosim_inv_d.max(),
                                 self.parent.prosim_inv_d.max()))
        print(self.parent.prosim_inv_d.max())
Пример #4
0
class PanelGraph(wx.Panel):
    def __init__(self, panel, notify, settings, status, remoteControl):
        self.panel = panel
        self.notify = notify
        self.plot = None
        self.settings = settings
        self.status = status
        self.remoteControl = remoteControl
        self.spectrum = None
        self.isLimited = None
        self.limit = None
        self.extent = None
        self.annotate = None

        self.isDrawing = False

        self.toolTip = wx.ToolTip('')

        self.mouseSelect = None
        self.mouseZoom = None
        self.measureTable = None

        self.background = None

        self.selectStart = None
        self.selectEnd = None

        self.menuClearSelect = []

        self.measure = None
        self.show = None

        self.doDraw = False

        wx.Panel.__init__(self, panel)

        self.figure = matplotlib.figure.Figure(facecolor='white')
        self.figure.set_size_inches(0, 0)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.canvas.SetToolTip(self.toolTip)

        self.measureTable = PanelMeasure(self, settings)

        self.toolbar = NavigationToolbar(self.canvas, self, settings,
                                         self.__hide_overlay)
        self.toolbar.Realize()

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.canvas, 1, wx.EXPAND)
        vbox.Add(self.measureTable, 0, wx.EXPAND)
        vbox.Add(self.toolbar, 0, wx.EXPAND)
        self.SetSizer(vbox)
        vbox.Fit(self)

        self.create_plot()

        self.canvas.mpl_connect('button_press_event', self.__on_press)
        self.canvas.mpl_connect('figure_enter_event', self.__on_enter)
        self.canvas.mpl_connect('axes_leave_event', self.__on_leave)
        self.canvas.mpl_connect('motion_notify_event', self.__on_motion)
        self.canvas.mpl_connect('draw_event', self.__on_draw)
        self.canvas.mpl_connect('idle_event', self.__on_idle)
        self.Bind(wx.EVT_SIZE, self.__on_size)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer)

    def __set_fonts(self):
        axes = self.plot.get_axes()
        if axes is not None:
            axes.xaxis.label.set_size('small')
            axes.yaxis.label.set_size('small')
            if self.settings.display == Display.SURFACE:
                axes.zaxis.label.set_size('small')
            axes.tick_params(axis='both', which='major', labelsize='small')
        axes = self.plot.get_axes_bar()
        if axes is not None:
            axes.tick_params(axis='both', which='major', labelsize='small')

    def __enable_menu(self, state):
        for menu in self.menuClearSelect:
            menu.Enable(state)

    def __on_press(self, event):
        if self.settings.clickTune and matplotlib.__version__ >= '1.2' and event.dblclick:
            frequency = int(event.xdata * 1e6)
            self.remoteControl.tune(frequency)
        elif isinstance(self.plot, PlotterPreview):
            self.plot.to_front()

    def __on_enter(self, _event):
        self.toolTip.Enable(False)

    def __on_leave(self, _event):
        self.toolTip.Enable(True)
        self.status.set_info('', level=None)

    def __on_motion(self, event):
        axes = self.plot.get_axes()
        axesBar = self.plot.get_axes_bar()
        xpos = event.xdata
        ypos = event.ydata
        text = ""

        if (xpos is None or ypos is None or self.spectrum is None
                or event.inaxes is None):
            spectrum = None
        elif event.inaxes == axesBar:
            spectrum = None
            level = self.plot.get_bar().norm.inverse(ypos)
            text = "{}".format(format_precision(self.settings, level=level))
        elif self.settings.display == Display.PLOT:
            timeStamp = max(self.spectrum)
            spectrum = self.spectrum[timeStamp]
        elif self.settings.display == Display.SPECT:
            timeStamp = num2epoch(ypos)
            if timeStamp in self.spectrum:
                spectrum = self.spectrum[timeStamp]
            else:
                nearest = min(self.spectrum.keys(),
                              key=lambda k: abs(k - timeStamp))
                spectrum = self.spectrum[nearest]
        elif self.settings.display == Display.SURFACE:
            spectrum = None
            coords = axes.format_coord(event.xdata, event.ydata)
            match = re.match('x=([-|0-9|\.]+).*y=([0-9|\:]+).*z=([-|0-9|\.]+)',
                             coords)
            if match is not None and match.lastindex == 3:
                freq = float(match.group(1))
                level = float(match.group(3))
                text = "{}, {}".format(
                    *format_precision(self.settings, freq, level))
        else:
            spectrum = None

        if spectrum is not None and len(spectrum) > 0:
            x = min(spectrum.keys(), key=lambda freq: abs(freq - xpos))
            if min(spectrum.keys(), key=float) <= xpos <= max(spectrum.keys(),
                                                              key=float):
                y = spectrum[x]
                text = "{}, {}".format(*format_precision(self.settings, x, y))
            else:
                text = format_precision(self.settings, xpos)

            markers = find_artists(self.figure, 'peak')
            markers.extend(find_artists(self.figure, 'peakThres'))
            hit = False
            for marker in markers:
                if isinstance(marker, Line2D):
                    location = marker.get_path().vertices[0]
                    markX, markY = axes.transData.transform(location)
                    dist = abs(math.hypot(event.x - markX, event.y - markY))
                    if dist <= 5:
                        if self.settings.display == Display.PLOT:
                            tip = "{}, {}".format(*format_precision(
                                self.settings, location[0], location[1]))
                        else:
                            tip = "{}".format(
                                format_precision(self.settings, location[0]))
                        self.toolTip.SetTip(tip)
                        hit = True
                        break
            self.toolTip.Enable(hit)

        self.status.set_info(text, level=None)

    def __on_size(self, event):
        ppi = wx.ScreenDC().GetPPI()
        size = [float(v) for v in self.canvas.GetSize()]
        width = size[0] / ppi[0]
        height = size[1] / ppi[1]
        self.figure.set_figwidth(width)
        self.figure.set_figheight(height)
        self.figure.set_dpi(ppi[0])
        event.Skip()

    def __on_draw(self, _event):
        axes = self.plot.get_axes()
        if axes is not None:
            self.background = self.canvas.copy_from_bbox(axes.bbox)
            self.__draw_overlay()

    def __on_idle(self, _event):
        if self.doDraw and self.plot.get_plot_thread() is None:
            self.__hide_overlay()
            self.doDraw = False
            if os.name == 'nt':
                threading.Thread(target=self.__draw_canvas,
                                 name='Draw').start()
            else:
                self.__draw_canvas()

    def __on_timer(self, _event):
        self.timer.Stop()
        self.set_plot(None, None, None, None, self.annotate)

    def __draw_canvas(self):
        try:
            self.isDrawing = True
            self.canvas.draw()
        except wx.PyDeadObjectError:
            pass

        self.isDrawing = False
        wx.CallAfter(self.status.set_busy, False)

    def __draw_overlay(self):
        if self.background is not None:
            self.canvas.restore_region(self.background)
            self.__draw_select()
            self.draw_measure()
            axes = self.plot.get_axes()
            if axes is not None:
                self.canvas.blit(axes.bbox)

    def __draw_select(self):
        if self.selectStart is not None and self.selectEnd is not None:
            self.mouseSelect.draw(self.selectStart, self.selectEnd)

    def __hide_overlay(self):
        if self.plot is not None:
            self.plot.hide_measure()
        self.__hide_select()

    def __hide_select(self):
        if self.mouseSelect is not None:
            self.mouseSelect.hide()

    def create_plot(self):
        if self.plot is not None:
            self.plot.close()

        self.toolbar.set_auto(True)

        if self.settings.display == Display.PLOT:
            self.plot = Plotter(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.SPECT:
            self.plot = Spectrogram(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.SURFACE:
            self.plot = Plotter3d(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.STATUS:
            self.plot = PlotterStatus(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.TIMELINE:
            self.plot = PlotterTime(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.PREVIEW:
            self.plot = PlotterPreview(self.notify, self.figure, self.settings)
            self.plot.set_window(self)

        self.__set_fonts()

        self.toolbar.set_plot(self.plot)
        self.toolbar.set_type(self.settings.display)
        self.measureTable.set_type(self.settings.display)

        self.set_plot_title()
        self.figure.subplots_adjust(top=0.85)
        self.redraw_plot()
        self.plot.scale_plot(True)
        self.mouseZoom = MouseZoom(self.toolbar,
                                   plot=self.plot,
                                   callbackHide=self.__hide_overlay)
        self.mouseSelect = MouseSelect(self.plot, self.on_select,
                                       self.on_selected)
        self.measureTable.show(self.settings.showMeasure)
        self.panel.SetFocus()

    def on_select(self):
        self.hide_measure()

    def on_selected(self, start, end):
        self.__enable_menu(True)
        self.selectStart = start
        self.selectEnd = end
        self.measureTable.set_selected(self.spectrum, start, end)

    def add_menu_clear_select(self, menu):
        self.menuClearSelect.append(menu)
        menu.Enable(False)

    def draw(self):
        self.doDraw = True

    def show_measure_table(self, show):
        self.measureTable.show(show)
        self.Layout()

    def set_plot(self, spectrum, isLimited, limit, extent, annotate=False):
        if spectrum is not None and extent is not None:
            if isLimited is not None and limit is not None:
                self.spectrum = copy.copy(spectrum)
                self.extent = extent
                self.annotate = annotate
                self.isLimited = isLimited
                self.limit = limit

        if self.plot.get_plot_thread() is None and not self.isDrawing:
            self.timer.Stop()
            self.measureTable.set_selected(self.spectrum, self.selectStart,
                                           self.selectEnd)

            if isLimited:
                self.spectrum = reduce_points(spectrum, limit)

            self.status.set_busy(True)
            self.plot.set_plot(self.spectrum, self.extent, annotate)
            if self.settings.display == Display.PREVIEW:
                self.status.set_busy(False)

        else:
            self.timer.Start(200, oneShot=True)

    def set_plot_title(self):
        if len(self.settings.devicesRtl) > 0:
            gain = self.settings.devicesRtl[self.settings.indexRtl].gain
        else:
            gain = 0
        self.plot.set_title("Frequency Spectrogram\n{} - {} MHz,"
                            " gain = {}dB".format(self.settings.start,
                                                  self.settings.stop, gain))

    def redraw_plot(self):
        if self.spectrum is not None:
            self.set_plot(self.spectrum, self.settings.pointsLimit,
                          self.settings.pointsMax, self.extent,
                          self.settings.annotate)

    def set_grid(self, on):
        self.plot.set_grid(on)

    def set_selected(self, start, end):
        self.selectStart = start
        self.selectEnd = end
        self.__draw_select()

    def hide_toolbar(self, hide):
        self.toolbar.Show(not hide)

    def hide_measure(self):
        if self.plot is not None:
            self.plot.hide_measure()

    def draw_measure(self):
        if self.measure is not None and self.measure.is_valid():
            self.plot.draw_measure(self.measure, self.show)

    def update_measure(self, measure=None, show=None):
        if not measure and not show:
            self.measureTable.update_measure()
        else:
            self.measure = measure
            self.show = show
            self.__draw_overlay()

    def get_figure(self):
        return self.figure

    def get_axes(self):
        return self.plot.get_axes()

    def get_canvas(self):
        return self.canvas

    def get_toolbar(self):
        return self.toolbar

    def get_mouse_select(self):
        return self.mouseSelect

    def scale_plot(self, force=False):
        self.plot.scale_plot(force)

    def clear_plots(self):
        self.plot.clear_plots()
        self.spectrum = None
        self.doDraw = True

    def clear_selection(self):
        self.measure = None
        self.measureTable.clear_measurement()
        self.selectStart = None
        self.selectEnd = None
        self.mouseSelect.clear()
        self.__enable_menu(False)

    def close(self):
        self.plot.close()
        close_modeless()
Пример #5
0
class Panel_Plotting_Helper(wx.Panel):
    def __init__(self, parent):
        w, h = parent.GetSize()
        wx.Panel.__init__(self,
                          parent=parent,
                          size=(w, 0.7 * h),
                          style=wx.SUNKEN_BORDER)
        self.parent = parent
        self.legends = []
        self.legendpos = [0.5, 1]

        self.fig = Figure(
            figsize=(12, 6),
            dpi=90)  # create a figure size 8x6 inches, 80 dots per inches
        self.splts = []
        self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
        self.toolbar = Toolbar(self.canvas)  # matplotlib toolbar
        # additional toolbar
        status_txt = wx.StaticText(self.toolbar, label='    Status on hover: ', pos=(230, 7), \
                                   size=(100, 17))
        self.status = wx.TextCtrl(self.toolbar, pos=(330,4), size=(300, 22), \
                                  style=wx.TE_READONLY)
        self.toolbar.Realize()

        self.figw, self.figh = self.fig.get_window_extent(
        ).width, self.fig.get_window_extent().height

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toolbar, 0, wx.GROW)
        sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(sizer)
        self.box_width_fraction = 1.0
        self.box_height_fraction = 0.9
        self.lines = []
        self.lined = dict()
        self.draggableList = ['Text', 'Legend']
        # print(self.toolbar.GetBackgroundColour())

        self.fig.canvas.mpl_connect('resize_event', self.squeeze_legend)
        self.fig.canvas.mpl_connect('pick_event', self.on_pick)
        self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)
        self.fig.canvas.mpl_connect('figure_leave_event', self.on_leave)

    def plot_J(self, J, theta, format, r, count):
        index = count % 3 + 3
        self.splts[index].plot(np.arange(len(J)),
                               J,
                               color=format['color'],
                               linewidth=format['linewidth'],
                               linestyle=format['linestyle'],
                               label=format['label'],
                               picker=True)
        self.splts[index].set_xlabel("Number of Iteration", fontsize=FONT_SIZE)
        self.splts[index].set_ylabel("Cost value", fontsize=FONT_SIZE)
        self.set_ticks(self.splts[index], np.arange(len(J)), J)
        comment = r + ': [\n'
        for t in theta:
            comment += '    ' + str(t) + '\n'
        comment += ']'
        props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
        annotate = self.splts[index].annotate(comment, xy=(len(J)-1, J[len(J)-1]), xytext=(len(J)/2, (J[0]+J[len(J)-1])/2), \
                                                  arrowprops=dict(facecolor='black', shrink=0.05), bbox=props, fontsize=FONT_SIZE, picker=True)
        annotate.draggable(True)

    def plot_data_gradient_descent(self, X, y, format):
        print("Plotting data ...")
        for i in range(int(round(len(self.splts) / 2))):
            self.plot_data(self.splts[i], X, y, format)
        self.update_canvas()

    def plot_data_normal_equation(self, X, y, format):
        print("Plotting data ...")
        for i in range(int(round((len(self.splts) + 1) / 2))):
            self.plot_data(self.splts[i], X, y, format)
        self.update_canvas()

    def plot_data(self, splt, X, y, format):
        line, = splt.plot(X,
                          y,
                          'ro',
                          color=format['color'],
                          label=format['label'],
                          picker=True)
        self.set_ticks(splt, X, y)
        self.lines.append(line)
        splt.set_xlabel("X1", fontsize=FONT_SIZE)
        splt.set_ylabel("Y", fontsize=FONT_SIZE)

    def set_ticks(self, splt, X, y):
        xticks = self.make_ticks(X)
        yticks = self.make_ticks(y)
        splt.set_xticks(xticks)
        splt.set_yticks(yticks)
        for tick in splt.get_xticklabels():
            tick.set_rotation(45)
            tick.set_fontsize(FONT_SIZE)
        for tick in splt.get_yticklabels():
            tick.set_rotation(45)
            tick.set_fontsize(FONT_SIZE)

    def plot_all_gradient_descent(self, object):
        print(
            "Plotting Linear-Regression (Gradient Descent) and J-Convergence ..."
        )
        count = 0
        for r in object:
            c = self.random_color()
            self.splts[count].plot(object[r]['data']['x'],
                                   object[r]['data']['y'],
                                   color=c,
                                   linestyle="-",
                                   label="Linear Regression (alpha=" + r + ")",
                                   picker=True)
            self.set_ticks(self.splts[count], object[r]['data']['x'],
                           object[r]['data']['y'])
            self.plot_J(
                object[r]['J_history'], object[r]['theta'], {
                    "color": c,
                    "linewidth": 5,
                    "linestyle": "-",
                    "label": "Convergence of J"
                }, r, count)
            count += 1
        self.show_legend()
        self.update_canvas()

    def plot_all_normal_equation(self, object):
        print("Plotting Linear-Regression (Normal Equation) ...")
        count = 0
        for r in object:
            c = self.random_color()
            line, = self.splts[count].plot(
                object[r]['data']['x'],
                object[r]['data']['y'],
                color=c,
                linestyle="-",
                label="Linear Regression (Normal Equation)",
                picker=True)
            self.lines.append(line)
            self.set_ticks(self.splts[count], object[r]['data']['x'],
                           object[r]['data']['y'])
            comment = 'Theta: [\n'
            for t in object[r]['theta']:
                comment += '    ' + str(t[0]) + '\n'
            comment += ']'
            # place a text box in upper left in axes coords
            props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
            annotate = self.splts[count].annotate(comment, xy=(min(object[r]['data']['x']), max(object[r]['data']['y'])), \
                                                      xytext=(min(object[r]['data']['x']), max(object[r]['data']['y'])), bbox=props, fontsize=FONT_SIZE, picker=True)
            annotate.draggable(True)
            count += 1
        self.show_legend()
        self.update_canvas()

    def show_legend(self):
        self.legends = []
        for i in range(len(self.splts)):
            splt = self.splts[i]
            # Shrink current axis by 20%
            box = splt.get_position()
            splt.set_position([box.x0, box.y0, box.width * self.box_width_fraction, \
                               box.height * self.box_height_fraction])
            # Now add the legend with some customizations.
            legend = splt.legend(loc='upper center',
                                 ncol=1,
                                 fancybox=True,
                                 shadow=True)
            legend.set_bbox_to_anchor((self.legendpos[0], \
                                       self.legendpos[1] + legend.get_window_extent().height/self.figh + 0.25))
            legend.figure.canvas.mpl_connect('pick_event', self.on_pick)
            legend.draggable(True)
            # lined = dict()
            # for legline, origline in zip(legend.get_lines(), self.lines):
            #    legline.set_picker(5)  # 5 pts tolerance
            #    self.lined[legline] = origline
            self.legends.append(legend)
            if legend:
                # The frame is matplotlib.patches.Rectangle instance surrounding the legend.
                frame = legend.get_frame()
                frame.set_facecolor('0.90')
                # Set the fontsize
                for label in legend.get_texts():
                    label.set_fontsize(FONT_SIZE)
                for label in legend.get_lines():
                    label.set_linewidth(0.75)  # the legend line width
            else:
                pass

    def make_ticks(self, data):
        minn = np.min(data)
        maxx = np.max(data)
        return np.arange(minn, maxx, int((maxx - minn) / 3))

    def squeeze_legend(self, evt):
        new_height = self.fig.get_window_extent().height
        self.box_height_fraction = new_height / self.figh
        self.figh = new_height
        new_width = self.fig.get_window_extent().width
        self.box_width_fraction = new_width / self.figw
        self.figw = new_width
        self.show_legend()
        self.update_canvas()

    def on_pick(self, evt):
        if isinstance(evt.artist, Text):
            # box_points = evt.artist.get_position()
            global TEXT_DRAGGABLE
            TEXT_DRAGGABLE = not TEXT_DRAGGABLE
            evt.artist.draggable(TEXT_DRAGGABLE)
        elif isinstance(evt.artist, Line2D):
            # box_points = evt.artist.get_clip_box()
            pass
        elif isinstance(evt.artist, Legend):
            # box_points = evt.artist.get_clip_box()
            global LEGEND_DRAGGABLE
            LEGEND_DRAGGABLE = not LEGEND_DRAGGABLE
            evt.artist.draggable(LEGEND_DRAGGABLE)
        else:
            print(evt.artist)
            pass

        # print("You've clicked on a bar with coords:\n %r, %r" % (box_points , evt.artist))
        self.update_canvas()

    def on_motion(self, mouseevt):
        w, h = self.canvas.GetSize()
        if mouseevt.x in range(0, int(w + 1)) and mouseevt.y in range(
                0, int(h + 1)):
            self.status.SetValue('Click on %r for dragging On/Off' %
                                 self.draggableList)
        else:
            pass

    def on_leave(self, mouseevt):
        self.status.SetValue('')

    def make_figure(self, type):
        self.fig.clf()
        if type == 'gd':
            gs = GridSpec(2, 3)
            gs.update(hspace=0.7, wspace=0.8)
            self.splts = [
                self.fig.add_subplot(gs[int(i / 3), int(i % 3)])
                for i in range(2 * 3)
            ]  # grid nxn
        elif type == 'ne':
            gs = GridSpec(1, 1)
            gs.update(hspace=0.7, wspace=0.8)
            self.splts = [
                self.fig.add_subplot(gs[int(i / 3), int(i % 3)])
                for i in range(1 * 1)
            ]  # grid nxn
        else:
            pass

    def random_color(self):
        rgbl = [0, random.random(), random.random()]
        return tuple(rgbl)

    def update_canvas(self):
        self.fig.canvas.draw()
        self.canvas.Refresh()
        self.toolbar.update()
Пример #6
0
class diffaction_int(wx.Frame):
    def __init__(self, filename=None):

        self.fullpath = fullpath
        self.iconspath = resource_path('icons')

        self.mpl_old = mpl_old

        im = Image.open(os.path.join(self.iconspath, 'diff_profile_text.png'))
        im = im.convert('L')
        x_str = im.tobytes('raw', im.mode, 0, 1)
        self.pattern = np.fromstring(x_str, np.uint8)
        self.pattern.shape = im.size[1], im.size[0]

        self.pattern_open = np.array([])
        self.size = self.pattern.shape
        self.camlen = 100
        self.accv = 200
        self.imgcal = 244
        #self.img_con = 0.05
        #self.img_con16 = 0.0001
        self.img_con = Param(1, minimum=0.01, maximum=1.9)
        self.img_contrast = (self.pattern.min(), self.pattern.max())
        accvm = self.accv * 1000
        self.wavelen = con.h / (np.sqrt(2 * con.m_e * con.e * accvm)) * 1 / (
            np.sqrt(1 + (con.e * accvm) / (2 * con.m_e * con.c**2)))
        self.pixel_size = self.PixelSize()
        print(self.pixel_size)

        wx.Frame.__init__(self,
                          None,
                          -1,
                          'Diffraction Ring Profiler',
                          size=(550, 350))

        self.Bind(wx.EVT_CLOSE, self.OnExit)

        iconFile = os.path.join(self.iconspath, "diff_profiler_ico.ico")
        icon1 = wx.Icon(iconFile, wx.BITMAP_TYPE_ICO)
        self.SetIcon(icon1)

        # dirname is an APPLICATION variable that we're choosing to store
        # in with the frame - it's the parent directory for any file we
        # choose to edit in this frame
        self.dirname = self.fullpath

        self.statbar = self.CreateStatusBar(
        )  # A Statusbar in the bottom of the window
        self.statbar.SetFieldsCount(2)
        self.statbar.SetStatusText("None", 1)

        # Setting up the menu. filemenu is a local variable at this stage.
        patternmenu = wx.Menu()
        # use ID_ for future easy reference - much better that "48", "404" etc
        # The & character indicates the short cut key
        patternmenu.Append(ID_OPEN, "&Open", " Open a file to edit")
        patternmenu.AppendSeparator()
        patternmenu.Append(ID_EXIT, "E&xit", " Terminate the program")

        # Setting up the menu. filemenu is a local variable at this stage.
        editmenu = wx.Menu()
        # use ID_ for future easy reference - much better that "48", "404" etc
        # The & character indicates the short cut key
        editmenu.Append(ID_UNDO, "&Undo", " Remove last point or circle")

        # Setting up the menu. filemenu is a local variable at this stage.
        toolsmenu = wx.Menu()
        # use ID_ for future easy reference - much better that "48", "404" etc
        # The & character indicates the short cut key
        toolsmenu.Append(
            ID_CAL, "&Calibrate Pixel Size",
            " Calibrate pixel size using marked rings and known d-spacing")
        toolsmenu.Append(
            ID_PREF, "Ca&lculate Pixel Size",
            " Calculate pixel size using image resolution and cameralength")
        toolsmenu.AppendSeparator()
        toolsmenu.Append(ID_PIX, "&Dead Pixel Fix",
                         " Remove dead and hot pixels from the pattern")
        #toolsmenu.Append(ID_MARK, "&Mark Rings"," Mark diffraction rings to find the pattern center")
        toolsmenu.Append(ID_INT, "&Profile",
                         " Extract profiles from the diffraction pattern")

        # Setting up the menu. filemenu is a local variable at this stage.
        helpmenu = wx.Menu()
        # use ID_ for future easy reference - much better that "48", "404" etc
        # The & character indicates the short cut key
        helpmenu.Append(ID_ABOUT, "&About", " Information about this program")

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(patternmenu,
                       "&Pattern")  # Adding the "patternmenu" to the MenuBar
        menuBar.Append(editmenu, "&Edit")
        menuBar.Append(toolsmenu,
                       "&Tools")  # Adding the "patternmenu" to the MenuBar
        menuBar.Append(helpmenu,
                       "&Help")  # Adding the "patternmenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
        # Note - previous line stores the whole of the menu into the current object

        self.SetBackgroundColour(wx.Colour("WHITE"))

        self.figure = Figure(figsize=(8, 8), dpi=76)
        self.figure.patch.set_facecolor('#F2F1F0')
        self.axes = self.figure.add_subplot(111)
        self.axes.set_aspect(1)
        self.figure.tight_layout()

        #log_pattern = log(1+a*self.pattern)#/log(1+a*self.pattern).max()*255

        self.img = self.axes.imshow(self.pattern,
                                    cmap='gray',
                                    aspect='equal',
                                    interpolation='bicubic')
        #axi.set_xlim(0, size[1])
        #axi.set_ylim(0, size[0])
        #canvas = axi.figure.canvas
        self.axes.set_autoscale_on(False)

        self.canvas = FigureCanvas(self, -1, self.figure)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)

        # Capture the paint message
        wx.EvtHandler.Bind(self, wx.EVT_PAINT, self.OnPaint)

        self.toolbar = MyNavigationToolbar(self, self.canvas, True,
                                           self.OnUndo)
        self.toolbar.Realize()

        tw, th = self.toolbar.GetSize()
        fw, fh = self.canvas.GetSize()
        self.toolbar.SetSize(wx.Size(fw, th))
        self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)

        # update the axes menu on the toolbar
        self.toolbar.update()

        self.img_conSliderGroup = SliderGroup(self,
                                              label='Image gamma:',
                                              param=self.img_con)
        self.sizer.Add(self.img_conSliderGroup.panel,
                       0,
                       wx.EXPAND | wx.ALIGN_CENTER | wx.ALL,
                       border=0)

        # Define the code to be run when a menu option is selected
        self.Bind(wx.EVT_MENU, self.OnAbout, id=ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnExit, id=ID_EXIT)
        self.Bind(wx.EVT_MENU, self.OnOpen, id=ID_OPEN)
        #self.Bind(wx.EVT_MENU, self.toolbar._on_markrings, id=ID_MARK)
        self.Bind(wx.EVT_MENU, self.toolbar._on_integrate, id=ID_INT)
        self.Bind(wx.EVT_MENU, self.OnUndo, id=ID_UNDO)
        self.Bind(wx.EVT_MENU, self.OnPref, id=ID_PREF)
        self.Bind(wx.EVT_MENU, self.OnCal, id=ID_CAL)
        self.Bind(wx.EVT_MENU, self.OnPix, id=ID_PIX)

        self.SetSizer(self.sizer)
        self.Fit()

        if filename:
            print(filename[0])
            self.dirname, self.filename = os.path.split(
                os.path.abspath(filename[0]))
            self.openimage()

    def PixelSize(self):
        return 1 / (((self.imgcal / 2.54) * 100) * self.wavelen *
                    (float(self.camlen) / 100))  #computes 1/m per pixel
        #1/(2*sin(.5*(arctan((arange(B)*Dd)/((float(camlen) / 100)*((imgcal / 2.54) * 100))))))/(wavelen * 10**10)

    def OnPaint(self, event):
        self.canvas.draw()
        event.Skip()

    def UpdateStatusbar(self):
        self.statbar.SetStatusText(
            "CamL: {0} cm | AccV: {1} kV | Res: {2:0.4f} 1/Å".format(
                self.camlen, self.accv, self.pixel_size * 10**-10), 0)

    def OnAbout(self, e):

        info = wx.adv.AboutDialogInfo()
        info.Name = "Diffraction Ring Profiler"
        info.Version = "1.2"
        info.Copyright = "(C) 2011 Brian Olsen"
        info.Description = "This program is for extracting intensity\n profiles from diffraction ring patterns\n"
        info.WebSite = ("http://code.google.com/p/diffraction-ring-profiler/",
                        "Diffraction Ring Profiler Website")
        info.Developers = ["Brian Olsen"]

        # change the wx.ClientDC to use self.panel instead of self
        info.License = 'Licensed under GPL 3.0 \n http://www.gnu.org/licenses/gpl.html'

        # Then we call wx.AboutBox giving it that info object
        wx.adv.AboutBox(info)

#        self.aboutme = wx.MessageDialog( self, "This program is for extracting intensity\n"
#                    " profiles from diffraction ring patterns\n\n" "Diffraction Ring Profiler 1.2\n\n"
#                    "(c) Brian Olsen, Licensed under GPL 3.0\n\n" "http://code.google.com/p/diffraction-ring-profiler/",
#                    "About Diffraction Ring Profiler", wx.OK)
#        self.aboutme.ShowModal() # Shows it
# widget / frame defined earlier so it can come up fast when needed

    def OnExit(self, e):
        # A modal with an "are you sure" check - we don't want to exit
        # unless the user confirms the selection in this case ;-)
        self.doiexit = wx.MessageDialog(self, "Do you want to quit?\n",
                                        "Warning", wx.YES_NO)
        igot = self.doiexit.ShowModal()  # Shows it
        self.doiexit.Destroy()
        if igot == wx.ID_YES:
            self.Destroy()  # Closes out this simple application

    def OnOpen(self, e):
        # In this case, the dialog is created within the method because
        # the directory name, etc, may be changed during the running of the
        # application. In theory, you could create one earlier, store it in
        # your frame object and change it when it was called to reflect
        # current parameters / values
        dlg = wx.FileDialog(
            self, "Choose a diffraction image", self.dirname, "",
            "Image Files|*.tif;*.TIF;*.tiff;*.TIFF;*.jpg;*.JPG;*.png;*.PNG;*.bmp;*.BMP;*.dm3;*.DM3|All Files|*.*",
            wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            self.openimage()
            print(self.dirname)
        dlg.Destroy()

    def openimage(self):

        self.toolbar.circles = []
        self.toolbar.point3 = np.array([])

        self.canvas.mpl_disconnect(self.toolbar.cid)

        name, ext = os.path.splitext(self.filename)
        print(self.dirname, name, ext, os.path.join(self.dirname,
                                                    self.filename))

        if ext == '.dm3' or ext == '.DM3':
            dm3f = dm3.DM3(os.path.join(self.dirname, self.filename))
            print(dm3f.info, dm3f.pxsize)

            self.pattern_open = dm3f.imagedata - dm3f.imagedata.min()
            #self.pattern_open = array(self.pattern_open)
            self.pattern_open.shape
            #print9self.pattern_open[[182],[1336]])

            a = self.img_con.value
            self.img_contrast = (dm3f.contrastlimits[0] - dm3f.imagedata.min(),
                                 dm3f.contrastlimits[1] - dm3f.imagedata.min())
            print(dm3f.info['mag'], dm3f.info['hv'])
            self.accv = int(float(dm3f.info['hv']) / 1000.0)
            if dm3f.info['mode'] == b'DIFFRACTION':
                self.camlen = int(float(dm3f.info['mag']) / 10.0)
            print(self.camlen, self.accv)

            if dm3f.pxsize[0]:
                if dm3f.pxsize[1] == b'1/nm':
                    self.pixel_size = dm3f.pxsize[0] * 10**9
                    print('.dm3 set pixel_size:', self.pixel_size)
                elif dm3f.pxsize[1] == b'1/A':
                    self.pixel_size = dm3f.pxsize[0] * 10**10
                    print('.dm3 set pixel_size:', self.pixel_size)
                elif dm3f.pxsize[1] == b'1/m':
                    self.pixel_size = dm3f.pxsize[0]
                    print('.dm3 set pixel_size:', self.pixel_size)
                else:
                    self.pixel_size = self.PixelSize()
                    print(
                        'No units in calibration. Using calculated pixel_size:',
                        self.pixel_size)
            elif dm3f.pxsize[0] == 1:
                self.pixel_size = self.PixelSize()
                print(
                    'Calibration of 1. Likely unset. Using calculated pixel_size:',
                    self.pixel_size)
            else:
                self.pixel_size = self.PixelSize()
                print(
                    'Calibration of 0. Likely unset. Using calculated pixel_size:',
                    self.pixel_size)
        else:
            im = Image.open(os.path.join(self.dirname, self.filename))
            Image._initialized = 2
            print(im.mode)
            #im.show()
            if im.mode == 'L':
                # return MxN luminance array
                print('luminance')
                x_str = im.tobytes('raw', im.mode, 0, 1)
                self.pattern_open = np.fromstring(x_str, np.uint8)
                self.pattern_open.shape = im.size[1], im.size[0]
            elif im.mode == 'I;16':
                # return MxN luminance array
                print('I;16')
                x_str = im.tobytes('raw', im.mode, 0, 1)
                self.pattern_open = np.fromstring(x_str, np.uint16)
                self.pattern_open.shape = im.size[1], im.size[0]
            elif im.mode == 'I;16B':
                # return MxN luminance array
                print('I;16')
                x_str = im.tobytes('raw', im.mode, 0, 1)
                self.pattern_open = np.fromstring(x_str, '>u2')
                self.pattern_open.shape = im.size[1], im.size[0]
            else:
                # return MxN luminance array
                print('convert')
                try:
                    im = im.convert('L')
                    x_str = im.tobytes('raw', im.mode, 0, 1)
                    self.pattern_open = np.fromstring(x_str, np.uint8)
                    self.pattern_open.shape = im.size[1], im.size[0]
                except ValueError:
                    dlg.Destroy()
                    error_file = 'Image file must be grayscale.'
                    print(error_file)
                    error_int_dlg = Error(self, -1, 'Error', error_file)
                    error_int_dlg.Show(True)
                    error_int_dlg.Centre()
                    self.axes.clear()
                    self.axes.imshow(self.pattern,
                                     cmap='gray',
                                     aspect='equal',
                                     origin='upper')
                    self.canvas.draw()
                    self.pattern_open = np.array([])
                    self.SetTitle("Diffraction Ring Profiler")
                    return
            self.img_contrast = (self.pattern_open.min(),
                                 self.pattern_open.max())

        #log_pattern = log(1+0.001*self.pattern_open)#/log(1+a*pattern).max()*255
        self.size = self.pattern_open.shape
        print('shape: ', self.size)

        self.axes.clear()
        self.img = self.axes.imshow(self.pattern_open,
                                    cmap='gray',
                                    aspect='equal',
                                    origin='upper',
                                    vmin=self.img_contrast[0],
                                    vmax=self.img_contrast[1])
        self.axes.xaxis.set_ticks_position('bottom')
        self.axes.yaxis.set_ticks_position('left')
        self.canvas.draw()

        self.SetTitle("Diffraction Ring Profiler - " + self.filename)
        self.UpdateStatusbar()
        self.img_con.set(1)

    def OnUndo(self, e):
        # Undo last point or circle

        print(self.toolbar.point3.size)
        print(self.axes.lines)
        print(self.toolbar.hist)

        undo = self.toolbar.hist[-1]

        if undo == 'start':
            print('back to start')
        elif undo == 'circ':
            self.toolbar.circles.pop(-1)
            for circle in self.toolbar.circles:
                print(circle.radius)
            self.axes.patches.pop(-1)
            self.axes.texts.pop(-1)
            del self.axes.lines[-4:]
            del self.toolbar.hist[-4:]
            print(self.toolbar.hist)
            self.canvas.draw()
        elif undo == 'point3' and self.toolbar.point3.size == 2:
            self.toolbar.point3 = np.array([])
            print(self.toolbar.point3)
            self.axes.lines.pop(-1)
            self.canvas.draw()
            del self.toolbar.hist[-1:]
        elif undo == 'point3':
            self.toolbar.point3 = self.toolbar.point3[:-1, :]
            print(self.toolbar.point3)
            self.axes.lines.pop(-1)
            self.canvas.draw()
            del self.toolbar.hist[-1:]
        elif undo == 'line':
            self.axes.patches.pop(-1)
            self.axes.texts.pop(-1)
            del self.axes.lines[-2:]
            del self.toolbar.hist[-3:]
            print(self.toolbar.hist)
            self.canvas.draw()
        elif undo == 'point2':
            self.toolbar.point2 = np.array([])
            print(self.toolbar.point2)
            self.axes.lines.pop(-1)
            self.canvas.draw()
            del self.toolbar.hist[-1:]
        else:
            print('undo error')

    def OnPix(self, e):
        std_cutoff = 80
        filter_size = 3
        self.pattern_open, num_filter, pattern_diff = self.filter_outliers(
            self.pattern_open, filter_size, std_cutoff)
        self.img.set_data(self.pattern_open)
        self.canvas.draw()
        print(num_filter)
        #figure()
        #imshow(pattern_diff, cmap='gray')
        #show()

    def filter_outliers(self, pattern, filter_size, std_cutoff):
        pattern[np.nonzero(pattern > 1e9)] = 0
        pattern_filter = median_filter(pattern, size=filter_size)
        pattern_diff = pattern - pattern_filter
        pattern_index = np.nonzero(
            np.logical_or(
                -np.std(pattern_diff) * std_cutoff + pattern_diff.mean() >
                pattern_diff, pattern_diff >
                np.std(pattern_diff) * std_cutoff + pattern_diff.mean()))
        print(pattern_index)
        if pattern[pattern_index].any():
            pattern_final = np.copy(pattern)
            print(pattern_final[pattern_index])
            num_filter = len(pattern_final[pattern_index])
            print(num_filter)
            pattern_final[pattern_index] = pattern_filter[pattern_index]
            pattern_diff_final = pattern - pattern_final
            print(np.nonzero(pattern > pattern.max() * .8), pattern.max(),
                  pattern_filter.max(), np.median(pattern_diff_final),
                  (pattern_diff_final).max())
        else:
            pattern_final = np.copy(pattern)
            num_filter = 0
        return pattern_final, num_filter, pattern_diff

    def OnPref(self, e):
        dlg = Pref(self, -1, 'Calculate Pixel Size')
        dlg.Show(True)
        dlg.Centre()

    def OnCal(self, e):
        dlg = Cal(self, -1, 'Calibrate Pixel Size')
        dlg.Show(True)
        dlg.Centre()
Пример #7
0
class G3Plot(wx.Frame):
    """

    G3Plot creates a frame with a toolbar that holds a G-3 graph (2D y vs.
    x plot).  The graph allows multiple plots from multicolumn data 'x, y1,
    y2, ...'  given at successive x-values, given in one or more files.
    Wildcard file names are accepted.

    """
    def __init__(self,
                 files,
                 verbose=False,
                 title='(x,y) data',
                 formt='k',
                 xlabel='X',
                 ylabel='Y',
                 ymin=-0.1,
                 ymax=0.05,
                 xmin=0.0,
                 xmax=1.0,
                 pos=(50, 60),
                 size=(640, 500)):

        wx.Frame.__init__(self, None, -1, "G3 Plot", pos, size)

        # self.SetBackgroundColour(wx.NamedColor("WHITE"))

        self.panel = None
        self.dpi = None
        self.fig = None
        self.canvas = None
        self.axes = None
        self.toolbar = None

        # Just in case we need to have these values stored
        self.verbose = verbose
        self.title = title
        self.formt = formt
        self.xlabel = xlabel
        self.ylabel = ylabel
        self.ymin = ymin
        self.ymax = ymax
        self.xmin = xmin
        self.xmax = xmax

        if self.verbose:
            print('xmin, xmax, ymin, ymax: ', self.xmin, self.xmax, self.ymin,
                  self.ymax)

        self.subplot = []
        # Give the figure size in inches, and rez
        self.figure = Figure(figsize=(6.4, 4.8), dpi=100)
        # Wait to create the subplot when AddSubplot() is called
        #        self.axes = self.figure.add_subplot(1,1,1)
        #        self.axes.set_title(self.title)
        #        self.axes.set_xlabel(self.xlabel)
        #        self.axes.set_ylabel(self.ylabel)

        self.PlotFiles(files)  # create axes and plot all the data
        self.canvas = FigureCanvas(self, -1, self.figure)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
        # Capture the paint message
        # wx.EVT_PAINT(self, self.OnPaint)

        self.toolbar = MyNavigationToolbar(self.canvas, True)
        self.toolbar.Realize()
        if wx.Platform == '__WXMAC__':
            # Mac platform (OSX 10.3, MacPython) does not seem to cope with
            # having a toolbar in a sizer. This work-around gets the buttons
            # back, but at the expense of having the toolbar at the top
            self.SetToolBar(self.toolbar)
        else:
            # On Windows platform, default window size is incorrect, so set
            # toolbar width to figure width.
            tw, th = self.toolbar.GetSize()
            fw, fh = self.canvas.GetSize()
            # By adding toolbar in sizer, we are able to put it at the bottom
            # of the frame - so appearance is closer to GTK version.
            # As noted above, doesn't work for Mac.
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)

        # update the axes menu on the toolbar
        self.toolbar.update()
        self.SetSizer(self.sizer)
        self.Fit()

#----------------------------------------------------------------------

    def PlotFiles(self, file_list):
        """
        Loops through all files and makes a call to _PlotFile to plot
        each data set to the canvas.
        """
        self.plot_data = []

        if self.verbose:

            print("Processing %d files." % len(file_list))

        for f in file_list:

            this_file = os.path.abspath(f)

            if os.path.isfile(this_file):

                try:

                    self._PlotFile(this_file)

                except Exception as e:

                    sys.exit("Error plotting files: %s" % e)

            else:

                print("File Error: '%s' is not found." % this_file)

#----------------------------------------------------------------------

    def _PlotFile(self, f):
        """
        Parses the data in file f and plots all data columns

        """

        # Will end up being a list of lists. First item
        # of the list will be the time step, all following
        # items will be output data at each time step.
        plot_data = None

        if self.verbose:

            print("Plotting file: %s" % f)

        this_file = os.path.abspath(f)

        if os.path.isfile(this_file):

            num_items = None

            fdata = open(this_file, 'r')

            for line in fdata.readlines():

                data = line.split()

                if plot_data is None:

                    num_items = len(data)

                    plot_data = [[] for i in range(num_items)]

                for indx, d in enumerate(data):

                    if indx < num_items:

                        try:

                            plot_data[indx].append(d)

                        except IndexError as e:

                            print("Error processing data line for index %d" %
                                  indx)

            # Now we plot all of the data we collected.
            t = plot_data[0]

            for indx, x in enumerate(plot_data[1:]):

                if self.verbose:
                    num_plots = len(plot_data[1:])
                    print("\tPlotting data set %d of %d" %
                          (indx + 1, num_plots))

                xa = np.asarray(t, dtype=float)
                ya = np.asarray(x, dtype=float)
                self._AddSubplot(xa, ya)

        else:

            print("File Error: '%s' is not found." % this_file)

#----------------------------------------------------------------------

    def _AddSubplot(self, t, x):
        """
        Create a subplot if one doesn't exist, and plot the (t, x) data.
        For historical reasons the x-axis variable is called 't' and the
        y-axis variable 'x'.  This should be changed!

        The add_subplot method of a Figure creates an Axes instance
        (111) == (1,1,1) --> row 1, col 1, Figure 1
       
        """

        if self.axes is None:
            self.axes = self.figure.add_subplot(1, 1, 1)
            # This is where Axes attributes are set
            self.axes.set_title(self.title)
            self.axes.set_xlabel(self.xlabel)
            self.axes.set_ylabel(self.ylabel)

        if self.xmin is None or self.xmax is None:
            self.axes.set_autoscalex_on(True)
        else:
            self.axes.set_autoscalex_on(False)
            self.axes.axis(xmin=self.xmin, xmax=self.xmax)

        if self.ymin is None or self.ymax is None:
            self.axes.set_autoscaley_on(True)
        else:
            self.axes.set_autoscaley_on(False)
            self.axes.axis(ymin=self.ymin, ymax=self.ymax)

        # With the new, or an exising Axes instance, plot the data
        if self.formt is None:
            self.axes.plot(t, x)
        else:
            self.axes.plot(t, x, self.formt)

#----------------------------------------------------------------------

    def OnPaint(self, event):
        self.canvas.draw()
        event.Skip()
Пример #8
0
class PlotPanel(wx.Panel):
    """The PlotPanel has a Figure and a Canvas. OnSize events simply set a
flag, and the actual resizing of the figure is triggered by an Idle event."""
    def __init__(self, parent, color=None, dpi=None, **kwargs):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        self.parent = parent

        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi)
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.SetColor(color)

        self._SetSize()
        #self.draw()

        self._resizeflag = False

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def _onSize(self, event):
        self._resizeflag = True
        #print 'Resizing Plot'
        #self._SetSize()

    def _onIdle(self, evt):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize(self):
        pixels = tuple(self.GetClientSize())
        if not tuple(self.canvas.GetSize()) == pixels:
            self.SetSize(pixels)
            self.canvas.SetSize(pixels)
            self.figure.set_size_inches(
                float(pixels[0]) / self.figure.get_dpi(),
                float(pixels[1]) / self.figure.get_dpi())
            try:
                if self.IsShown():
                    self.draw()
            except:
                pass

    def draw(self):
        pass  # abstract, to be overridden by child classes
Пример #9
0
class Spectrogram(StandardMonitorPage):
    """Main class for a page that generates real-time spectrogram plots of EEG.
    """
    def __init__(self, *args, **kwargs):
        """Construct a new Spectrogram page.

        Args:
            *args, **kwargs:  Arguments to pass to the Page base class.
        """
        self.initConfig()

        # initialize Page base class
        StandardMonitorPage.__init__(self,
                                     name='Spectrogram',
                                     configPanelClass=ConfigPanel,
                                     *args,
                                     **kwargs)

        self.initCanvas()
        self.initLayout()

    def initConfig(self):
        self.filter = True  # use raw or filtered signal
        self.chanIndex = 0  # index of channel to show
        self.width = 5.0  # width of window to use for computing PSD

        self.decimationFactor = 1  # decimation factor, e.g., 2 will decimate to half sampRate

        self.interpolation = 'none'

        self.normScale = 'log'
        self.scale = -2

        self.method = 'Wavelet'

        self.setRefreshDelay(200)

        self.waveletConfig = util.Holder(nFreq=100, span=10)

        self.fourierConfig = util.Holder()

    def initCanvas(self):
        """Initialize a new matplotlib canvas, figure and axis.
        """
        self.plotPanel = wx.Panel(self)
        self.plotPanel.SetBackgroundColour('white')
        plotSizer = wx.BoxSizer(orient=wx.VERTICAL)
        self.plotPanel.SetSizer(plotSizer)

        self.fig = plt.Figure(facecolor='white')
        #self.canvas = FigureCanvas(parent=self, id=wx.ID_ANY, figure=self.fig)
        self.canvas = FigureCanvas(parent=self.plotPanel,
                                   id=wx.ID_ANY,
                                   figure=self.fig)

        self.ax = self.fig.add_subplot(1, 1, 1)
        self.ax.set_xlabel('Time (s)')
        self.ax.set_ylabel('Frequency (Hz)')

        self.cbAx = self.fig.add_axes([0.91, 0.05, 0.03, 0.93])

        #self.fig.subplots_adjust(hspace=0.0, wspace=0.0,
        #    left=0.035, right=0.92, top=0.98, bottom=0.05)

        self.adjustMargins()

        self.firstPlot()

        self.lastSize = (0, 0)
        self.needsResizePlot = True
        self.canvas.Bind(wx.EVT_SIZE, self.resizePlot)
        self.canvas.Bind(wx.EVT_IDLE, self.idleResizePlot)

        ##self.plotToolbar = widgets.PyPlotNavbar(self.canvas)
        ##plotSizer.Add(self.plotToolbar, proportion=0, flag=wx.EXPAND)
        plotSizer.Add(self.canvas, proportion=1, flag=wx.EXPAND)

        #self.plotToolbar.Hide()

    def initLayout(self):
        self.initStandardLayout()

        plotPaneAuiInfo = aui.AuiPaneInfo().Name('canvas').Caption(
            'Spectrogram').CenterPane()
        #self.auiManager.AddPane(self.canvas, plotPaneAuiInfo)
        self.auiManager.AddPane(self.plotPanel, plotPaneAuiInfo)

        self.auiManager.Update()

        self.canvas.Hide()

    def afterUpdateSource(self):
        self.configPanel.updateChannels()

    def afterStart(self):
        # make sure canvas is visible
        self.canvas.Show()
        self.plotPanel.Layout()

        # trigger initial plot update
        self.needsFirstPlot = True

    def getCap(self):
        cap = self.src.getEEGSecs(self.width, filter=self.filter, copy=False)
        if self.decimationFactor > 1:
            cap.decimate(self.decimationFactor)

        return cap

    def getSpectrum(self, cap):
        # configurable XXX - idfah
        data = cap.data[:, self.chanIndex] * sig.windows.tukey(
            cap.data.shape[0])  # tukey or hann? XXX - idfah

        freqs, powers, phases = self.cwt.apply(data)

        # configurable XXX - idfah
        powers = np.clip(powers, 1.0e-10, np.inf)

        return freqs, powers

    def firstPlot(self, event=None):
        cap = self.getCap()

        self.cwt = sig.CWT(sampRate=cap.getSampRate(),
                           freqs=self.waveletConfig.nFreq,
                           span=self.waveletConfig.span)

        if self.isRunning():
            freqs, powers = self.getSpectrum(cap)
        else:
            freqs = np.arange(1, self.src.getSampRate() // 2 + 1)
            powers = np.zeros((128, 10, 1))
            powers[0, 0, 0] = 1.0

        self.ax.cla()
        self.cbAx.cla()

        self.ax.set_xlabel('Time (s)')
        self.ax.set_ylabel('Frequency (Hz)')

        self.wimg = self.ax.imshow(powers[:, :, 0].T,
                                   interpolation=self.interpolation,
                                   origin='lower',
                                   aspect='auto',
                                   norm=self.getNorm(),
                                   extent=self.getExtent(cap, freqs),
                                   cmap=plt.cm.get_cmap('jet'),
                                   animated=True)

        self.cbar = self.fig.colorbar(self.wimg, cax=self.cbAx)
        self.cbar.set_label(r'Power Density ($V^2 / Hz$)')

        #self.updateNorm(powers)

        self.canvas.draw()

        #self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.background = self.canvas.copy_from_bbox(self.ax.bbox)

        self.needsFirstPlot = False

    def adjustMargins(self):
        self.fig.subplots_adjust(hspace=0.0,
                                 wspace=0.0,
                                 left=0.045,
                                 right=0.90,
                                 top=0.98,
                                 bottom=0.07)

    def resizePlot(self, event):
        # prevents handling extra resize events, hack XXX - idfah
        size = self.canvas.GetSize()
        if self.lastSize == size:
            return
        else:
            self.lastSize = size

        # this is all a hack to do resizing on idle when page is not running
        # should this be a custom FigureCanvas derived widget? XXX - idfah
        if self.isRunning():
            # when running, just do event.Skip() this will
            # call canvas._onSize since it is second handler
            self.needsResizePlot = False
            event.Skip()
        else:
            # flag to resize on next idle event
            self.needsResizePlot = True

    def idleResizePlot(self, event):
        # if not running and flagged for resize
        if not self.isRunning() and self.needsResizePlot:
            ##self.adjustMargins()
            self.needsResizePlot = False
            # call canvas resize method manually
            # hack alert, we just pass None as event
            # since it's not used anyway
            self.canvas._onSize(None)

    def getExtent(self, cap, freqs):
        return (0.0, cap.getNObs() / float(cap.getSampRate()), np.min(freqs),
                np.max(freqs))

    def getNorm(self):
        mx = 10**self.scale

        if self.normScale == 'linear':
            mn = 0.0
            norm = pltLinNorm(mn, mx)

        elif self.normScale == 'log':
            mn = 1e-10
            norm = pltLogNorm(mn, mx)

        else:
            raise RuntimeError('Invalid norm %s.' % norm)

        return norm

    def updatePlot(self, event=None):
        """Draw the spectrogram plot.
        """
        if self.needsFirstPlot:
            self.firstPlot()

        else:
            cap = self.getCap()
            freqs, powers = self.getSpectrum(cap)

            #self.updateNorm(powers)

            self.canvas.restore_region(self.background)
            self.wimg.set_array(powers[:, :, 0].T)
            self.wimg.set_extent(self.getExtent(cap, freqs))
            self.ax.draw_artist(self.wimg)

            ##self.cbAx.draw_artist(self.cbar.patch)
            ##self.cbAx.draw_artist(self.cbar.solids)

            #self.cbar.draw_all()
            #self.canvas.blit(self.cbAx.bbox)

            #self.canvas.blit(self.fig.bbox)
            self.canvas.blit(self.ax.bbox)

            # for debugging, redraws everything
            ##self.canvas.draw()

    def captureImage(self, event=None):
        ## Parts borrowed from backends_wx.py from matplotlib
        # Fetch the required filename and file type.
        filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
        default_file = self.canvas.get_default_filename()
        dlg = wx.FileDialog(self, "Save to file", "", default_file, filetypes,
                            wx.SAVE | wx.OVERWRITE_PROMPT)
        dlg.SetFilterIndex(filter_index)
        if dlg.ShowModal() == wx.ID_OK:
            dirname = dlg.GetDirectory()
            filename = dlg.GetFilename()
            format = exts[dlg.GetFilterIndex()]
            basename, ext = os.path.splitext(filename)
            if ext.startswith('.'):
                ext = ext[1:]
            if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format != ext:
                #looks like they forgot to set the image type drop
                #down, going with the extension.
                format = ext
            self.canvas.print_figure(os.path.join(dirname, filename),
                                     format=format)
Пример #10
0
class FIRBandpassConfigPanel(FilterConfigPanel):
    def __init__(self, *args, **kwargs):
        FilterConfigPanel.__init__(self, *args, **kwargs)

        # options go in top-level sizer
        self.initOptions()

        # other stuff split horizontally by bottomSizer
        self.bottomSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.initSliders()
        self.initResponse()
        self.sizer.Add(self.bottomSizer, proportion=1, flag=wx.EXPAND)

        self.initLayout()

    def initOptions(self):
        optionsSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.filtTypeComboBox = wx.ComboBox(self, choices=list(self.flt.filtMap.keys()),
            value=self.flt.filtType, style=wx.CB_DROPDOWN)
        self.Bind(wx.EVT_COMBOBOX, self.setFiltType, self.filtTypeComboBox)
        optionsSizer.Add(self.filtTypeComboBox, proportion=1,
                flag=wx.LEFT | wx.TOP | wx.RIGHT | wx.ALIGN_CENTER, border=20)

        self.sizer.Add(optionsSizer, proportion=0)#, flag=wx.EXPAND)

    def setFiltType(self, event):
        filtType = self.filtTypeComboBox.GetValue()

        if filtType not in self.flt.filtMap.keys():
            raise RuntimeError('Invalid filter type: %s.' % str(filtType))

        self.flt.filtType = filtType
        self.updateResponse()

    def initSliders(self):
        sliderSizer = wx.BoxSizer(wx.HORIZONTAL)

        lowFreqControlBox = widgets.ControlBox(self, label='lowFreq', orient=wx.VERTICAL)
        self.lowFreqText = wx.StaticText(self, label='%6.2f(Hz)' % self.flt.lowFreq)
        lowFreqTextSizer = wx.BoxSizer(orient=wx.VERTICAL)
        lowFreqTextSizer.Add(self.lowFreqText, proportion=0, flag=wx.ALIGN_CENTER_HORIZONTAL)
        self.lowFreqSlider = wx.Slider(self, style=wx.SL_VERTICAL | wx.SL_INVERSE,
                minValue=0, maxValue=int(self.flt.nyquist*4), value=int(self.flt.lowFreq*4))
        self.Bind(wx.EVT_SLIDER, self.setLowFreq, self.lowFreqSlider)
        lowFreqControlBox.Add(lowFreqTextSizer, proportion=0,
                flag=wx.TOP | wx.BOTTOM | wx.EXPAND, border=8)
        lowFreqControlBox.Add(self.lowFreqSlider, proportion=1,
                flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=25)

        sliderSizer.Add(lowFreqControlBox, proportion=1,
                flag=wx.ALL | wx.EXPAND, border=10)

        highFreqControlBox = widgets.ControlBox(self, label='highFreq', orient=wx.VERTICAL)
        self.highFreqText = wx.StaticText(self, label='%6.2f(Hz)' % self.flt.highFreq)
        highFreqTextSizer = wx.BoxSizer(orient=wx.VERTICAL)
        highFreqTextSizer.Add(self.highFreqText, proportion=0, flag=wx.ALIGN_CENTER_HORIZONTAL)
        self.highFreqSlider = wx.Slider(self, style=wx.SL_VERTICAL | wx.SL_INVERSE,
                minValue=0, maxValue=int(self.flt.nyquist*4), value=int(self.flt.highFreq*4))
        self.Bind(wx.EVT_SLIDER, self.setHighFreq, self.highFreqSlider)
        highFreqControlBox.Add(highFreqTextSizer, proportion=0,
                flag=wx.TOP | wx.BOTTOM | wx.EXPAND, border=8)
        highFreqControlBox.Add(self.highFreqSlider, proportion=1,
                flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=25)

        sliderSizer.Add(highFreqControlBox, proportion=1,
                flag=wx.ALL | wx.EXPAND, border=10)

        orderControlBox = widgets.ControlBox(self, label='Order', orient=wx.VERTICAL)
        self.orderText = wx.StaticText(self, label='%2d' % self.flt.order)
        orderTextSizer = wx.BoxSizer(orient=wx.VERTICAL)
        orderTextSizer.Add(self.orderText, proportion=0, flag=wx.ALIGN_CENTER_HORIZONTAL)
        self.orderSlider = wx.Slider(self, style=wx.SL_VERTICAL | wx.SL_INVERSE,
                minValue=2, maxValue=50, value=self.flt.order // 2)
        self.Bind(wx.EVT_SLIDER, self.setOrder, self.orderSlider)
        orderControlBox.Add(orderTextSizer, proportion=0,
                flag=wx.TOP | wx.BOTTOM | wx.EXPAND, border=8)
        orderControlBox.Add(self.orderSlider, proportion=1,
                flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=25)

        sliderSizer.Add(orderControlBox, proportion=1,
                flag=wx.ALL | wx.EXPAND, border=10)

        self.bottomSizer.Add(sliderSizer, proportion=1, flag=wx.EXPAND)

    def setLowFreq(self, event):
        self.flt.lowFreq = self.lowFreqSlider.GetValue() / 4.0
        self.lowFreqText.SetLabel('%6.2f(Hz)' % self.flt.lowFreq)
        self.updateResponse()

    def setHighFreq(self, event):
        self.flt.highFreq = self.highFreqSlider.GetValue() / 4.0
        self.highFreqText.SetLabel('%6.2f(Hz)' % self.flt.highFreq)
        self.updateResponse()

    def setOrder(self, event):
        self.flt.order = self.orderSlider.GetValue() * 2
        self.orderText.SetLabel('%2d' % self.flt.order)
        self.updateResponse()

    def initResponse(self):
        self.freqResponseFig = plt.Figure()
        self.freqResponseCanvas = FigureCanvas(parent=self,
                id=wx.ID_ANY, figure=self.freqResponseFig)
        self.freqResponseAx = self.freqResponseFig.add_subplot(1,1,1)
        #self.freqResponseFig.tight_layout()

        self.phaseResponseFig = plt.Figure()
        self.phaseResponseCanvas = FigureCanvas(parent=self,
                id=wx.ID_ANY, figure=self.phaseResponseFig)
        self.phaseResponseAx = self.phaseResponseFig.add_subplot(1,1,1)
        #self.freqResponseFig.tight_layout()

        responseSizer = wx.BoxSizer(wx.VERTICAL)

        freqResponseControlBox = widgets.ControlBox(self,
                label='Frequency Response', orient=wx.VERTICAL)
        freqResponseControlBox.Add(self.freqResponseCanvas, proportion=1,
                flag=wx.ALL | wx.EXPAND, border=8)
        responseSizer.Add(freqResponseControlBox, proportion=1,
                flag=wx.TOP | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=10)

        phaseResponseControlBox = widgets.ControlBox(self,
                label='Phase Response', orient=wx.VERTICAL)
        phaseResponseControlBox.Add(self.phaseResponseCanvas, proportion=1,
                flag=wx.ALL | wx.EXPAND, border=8)
        responseSizer.Add(phaseResponseControlBox, proportion=1,
                flag=wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=10)

        self.bottomSizer.Add(responseSizer, proportion=1, flag=wx.EXPAND)

        self.freqResponseCanvas.SetMinSize((0,0))
        self.phaseResponseCanvas.SetMinSize((0,0))

        # could we prevent resize when panel is not visible? XXX - idfah
        self.freqResponseLastSize = (0,0)
        self.freqResponseCanvas.Bind(wx.EVT_SIZE, self.freqResponseResize)
        self.phaseResponseLastSize = (0,0)
        self.phaseResponseCanvas.Bind(wx.EVT_SIZE, self.phaseResponseResize)

        self.updateResponse()

    def freqResponseResize(self, event):
        # prevents handling extra resize events, hack XXX - idfah
        size = self.freqResponseCanvas.GetSize()
        if self.freqResponseLastSize == size:
            return

        self.freqResponseLastSize = size
        event.Skip()

    def phaseResponseResize(self, event):
        # prevents handling extra resize events, hack XXX - idfah
        size = self.phaseResponseCanvas.GetSize()
        if self.phaseResponseLastSize == size:
            return

        self.phaseResponseLastSize = size
        event.Skip()

    def updateResponse(self):
        self.flt.updateFilter()

        self.freqResponseAx.cla()
        self.flt.bp.plotFreqResponse(ax=self.freqResponseAx, linewidth=2)
        self.freqResponseAx.autoscale(tight=True)
        self.freqResponseAx.legend(prop={'size': 12})
        self.freqResponseCanvas.draw()

        self.phaseResponseAx.cla()
        self.flt.bp.plotPhaseResponse(ax=self.phaseResponseAx, linewidth=2)
        self.phaseResponseAx.legend(prop={'size': 12})
        self.phaseResponseAx.autoscale(tight=True)

        self.phaseResponseCanvas.draw()
Пример #11
0
class PanelGraph(wx.Panel):
    def __init__(self, panel, notify, settings, callbackMotion, remoteControl):
        self.panel = panel
        self.notify = notify
        self.plot = None
        self.settings = settings
        self.remoteControl = remoteControl
        self.spectrum = None
        self.isLimited = None
        self.limit = None
        self.extent = None
        self.annotate = None

        self.mouseSelect = None
        self.mouseZoom = None
        self.measureTable = None

        self.background = None

        self.selectStart = None
        self.selectEnd = None

        self.menuClearSelect = []

        self.measure = None
        self.show = None

        self.doDraw = False

        wx.Panel.__init__(self, panel)

        self.figure = matplotlib.figure.Figure(facecolor='white')
        self.canvas = FigureCanvas(self, -1, self.figure)

        self.measureTable = PanelMeasure(self, settings)

        self.toolbar = NavigationToolbar(self.canvas, self, settings,
                                         self.__hide_overlay)
        self.toolbar.Realize()

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.canvas, 1, wx.EXPAND)
        vbox.Add(self.measureTable, 0, wx.EXPAND)
        vbox.Add(self.toolbar, 0, wx.EXPAND)
        self.SetSizer(vbox)
        vbox.Fit(self)

        self.create_plot()

        self.canvas.mpl_connect('button_press_event', self.__on_press)
        self.canvas.mpl_connect('motion_notify_event', callbackMotion)
        self.canvas.mpl_connect('draw_event', self.__on_draw)
        self.canvas.mpl_connect('idle_event', self.__on_idle)
        self.Bind(wx.EVT_SIZE, self.__on_size)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer)

    def __set_fonts(self):
        axes = self.plot.get_axes()
        if axes is not None:
            axes.xaxis.label.set_size('small')
            axes.yaxis.label.set_size('small')
            if self.settings.display == Display.SURFACE:
                axes.zaxis.label.set_size('small')
            axes.tick_params(axis='both', which='major', labelsize='small')
        axes = self.plot.get_axes_bar()
        if axes is not None:
            axes.tick_params(axis='both', which='major', labelsize='small')

    def __enable_menu(self, state):
        for menu in self.menuClearSelect:
            menu.Enable(state)

    def __on_press(self, event):
        if self.settings.clickTune and matplotlib.__version__ >= '1.2' and event.dblclick:
            frequency = int(event.xdata * 1e6)
            self.remoteControl.tune(frequency)

    def __on_size(self, event):
        ppi = wx.ScreenDC().GetPPI()
        size = [float(v) for v in self.canvas.GetSize()]
        width = size[0] / ppi[0]
        height = size[1] / ppi[1]
        self.figure.set_figwidth(width)
        self.figure.set_figheight(height)
        self.figure.set_dpi(ppi[0])
        event.Skip()

    def __on_draw(self, _event):
        axes = self.plot.get_axes()
        if axes is not None:
            self.background = self.canvas.copy_from_bbox(axes.bbox)
            self.__draw_overlay()

    def __on_idle(self, _event):
        if self.doDraw and self.plot.get_plot_thread() is None:
            self.__hide_overlay()
            self.canvas.draw()
            self.doDraw = False

    def __on_timer(self, _event):
        self.timer.Stop()
        self.set_plot(None, None, None, None, self.annotate)

    def __draw_overlay(self):
        if self.background is not None:
            self.canvas.restore_region(self.background)
            self.__draw_select()
            self.draw_measure()
            axes = self.plot.get_axes()
            if axes is None:
                self.canvas.draw()
            else:
                self.canvas.blit(axes.bbox)

    def __draw_select(self):
        if self.selectStart is not None and self.selectEnd is not None:
            self.mouseSelect.draw(self.selectStart, self.selectEnd)

    def __hide_overlay(self):
        if self.plot is not None:
            self.plot.hide_measure()
        self.__hide_select()

    def __hide_select(self):
        if self.mouseSelect is not None:
            self.mouseSelect.hide()

    def create_plot(self):
        if self.plot is not None:
            self.plot.close()

        self.toolbar.set_auto(True)

        if self.settings.display == Display.PLOT:
            self.plot = Plotter(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.SPECT:
            self.plot = Spectrogram(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.SURFACE:
            self.plot = Plotter3d(self.notify, self.figure, self.settings)
        elif self.settings.display == Display.STATUS:
            self.plot = PlotterStatus(self.notify, self.figure, self.settings)
        else:
            self.plot = PlotterTime(self.notify, self.figure, self.settings)

        self.__set_fonts()

        self.toolbar.set_plot(self.plot)
        self.toolbar.set_type(self.settings.display)
        self.measureTable.set_type(self.settings.display)

        self.set_plot_title()
        self.figure.subplots_adjust(top=0.85)
        self.redraw_plot()
        self.plot.scale_plot(True)
        self.mouseZoom = MouseZoom(self.toolbar,
                                   plot=self.plot,
                                   callbackHide=self.__hide_overlay)
        self.mouseSelect = MouseSelect(self.plot, self.on_select,
                                       self.on_selected)
        self.measureTable.show(self.settings.showMeasure)
        self.panel.SetFocus()

    def on_select(self):
        self.hide_measure()

    def on_selected(self, start, end):
        self.__enable_menu(True)
        self.selectStart = start
        self.selectEnd = end
        self.measureTable.set_selected(self.spectrum, start, end)

    def add_menu_clear_select(self, menu):
        self.menuClearSelect.append(menu)
        menu.Enable(False)

    def draw(self):
        self.doDraw = True

    def show_measure_table(self, show):
        self.measureTable.show(show)
        self.Layout()

    def set_plot(self, spectrum, isLimited, limit, extent, annotate=False):
        if spectrum is not None and extent is not None:
            if isLimited is not None and limit is not None:
                self.spectrum = copy.copy(spectrum)
                self.extent = extent
                self.annotate = annotate
                self.isLimited = isLimited
                self.limit = limit

        if self.plot.get_plot_thread() is None:
            self.timer.Stop()
            self.measureTable.set_selected(self.spectrum, self.selectStart,
                                           self.selectEnd)
            if isLimited:
                spectrum = reduce_points(spectrum, limit)
            self.plot.set_plot(self.spectrum, self.extent, annotate)

        else:
            self.timer.Start(200, oneShot=True)

    def set_plot_title(self):
        if len(self.settings.devicesRtl) > 0:
            gain = self.settings.devicesRtl[self.settings.indexRtl].gain
        else:
            gain = 0
        self.plot.set_title("Frequency Spectrogram\n{} - {} MHz,"
                            " gain = {}dB".format(self.settings.start,
                                                  self.settings.stop, gain))

    def redraw_plot(self):
        if self.spectrum is not None:
            self.set_plot(self.spectrum, self.settings.pointsLimit,
                          self.settings.pointsMax, self.extent,
                          self.settings.annotate)

    def set_grid(self, on):
        self.plot.set_grid(on)

    def hide_measure(self):
        if self.plot is not None:
            self.plot.hide_measure()

    def draw_measure(self):
        if self.measure is not None and self.measure.is_valid():
            self.plot.draw_measure(self.measure, self.show)

    def update_measure(self, measure=None, show=None):
        if not measure and not show:
            self.measureTable.update_measure()
        else:
            self.measure = measure
            self.show = show
            self.__draw_overlay()

    def get_figure(self):
        return self.figure

    def get_axes(self):
        return self.plot.get_axes()

    def get_canvas(self):
        return self.canvas

    def get_toolbar(self):
        return self.toolbar

    def scale_plot(self, force=False):
        self.plot.scale_plot(force)

    def clear_plots(self):
        self.plot.clear_plots()
        self.spectrum = None
        self.doDraw = True

    def clear_selection(self):
        self.measure = None
        self.measureTable.clear_measurement()
        self.selectStart = None
        self.selectEnd = None
        self.mouseSelect.clear()
        self.__enable_menu(False)

    def close(self):
        close_modeless()
Пример #12
0
class PlotWin(wx.Frame):
    
    def __init__(self,parent):
        self.parent=parent
        self.listeners = {}
        self.makeFrame()
        self.initMenu()
        self.initPopUpMenu()

    def makeFrame(self):
        global canvas #@@@@
        # Got this trick for a two stage creation from
        # http://wiki.wxpython.org/index.cgi/TwoStageCreation
        pre = wx.PreFrame()
        self.res = XmlResource(homepath+"/plotwin.xrc")
        self.res.LoadOnFrame(pre,self.parent,"plotwin")
        self.PostCreate(pre)
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.Show()

        self.figure = Figure()
        self.axes = [self.figure.add_subplot(111)]
        self.canvas = FigureCanvas(self, -1, self.figure)
        canvas = self.canvas #@@@@
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.Fit()
        self.addToolbar()

        
    def initMenu(self):
        self.menubar = XRCCTRL(self, "menubar") 
        bindings = (
            ("file_exit", self.onFileExit),
            ("layout_subplots", self.onLayout),
            ("help_about", self.onHelpAbout))
        for id,fun in bindings:
            wx.EVT_MENU(self, XRCID(id),fun)

    def initPopUpMenu(self):
        filetraceMenu=wx.Menu()
        filetraceMenu.Append(ID_TRACE_NEW_LINE, "New line plot...")
        filetraceMenu.Append(ID_TRACE_ADD_LINE, "Add line plot...")
        filetraceMenu.Append(ID_TRACE_NEW_BAR, "New bar plot...")
        
        filelistenerMenu=wx.Menu()
        filelistenerMenu.Append(ID_LISTENER_NEW_LINE, "New line plot...")
        filelistenerMenu.Append(ID_LISTENER_NEW_BAR, "New bar plot...")
        
        self.popup = wx.Menu()
        self.popup.AppendMenu(ID_PLOT_TRACE, "Plot file trace", filetraceMenu)
        self.popup.AppendMenu(ID_PLOT_LISTENER, "Plot from listener",
                              filelistenerMenu)
        self.popup.AppendSeparator()
        self.popup.Append(ID_CLEAR_PLOT, "Clear plot")
        self.popup.Append(ID_PLOT_PARAMETERS, "Plot parameters...")

        self.Bind(wx.EVT_MENU, self.onClearPlot, id=ID_CLEAR_PLOT)
        self.Bind(wx.EVT_MENU, self.onPlotParameters, id=ID_PLOT_PARAMETERS)
        self.Bind(wx.EVT_MENU, self.onTraceLine, id=ID_TRACE_NEW_LINE)
        self.Bind(wx.EVT_MENU, self.onTraceLine, id=ID_TRACE_ADD_LINE)
        self.Bind(wx.EVT_MENU, self.onTraceNewBar, id=ID_TRACE_NEW_BAR)
        self.Bind(wx.EVT_MENU, self.onListenerNewLine, id=ID_LISTENER_NEW_LINE)
        self.Bind(wx.EVT_MENU, self.onListenerNewBar, id=ID_LISTENER_NEW_BAR)

    def addToolbar(self):
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        if wx.Platform == '__WXMAC__':
            # Mac platform (OSX 10.3, MacPython) does not seem to cope with
            # having a toolbar in a sizer. This work-around gets the buttons
            # back, but at the expense of having the toolbar at the top
            self.SetToolBar(self.toolbar)
        else:
            # On Windows platform, default window size is incorrect, so set
            # toolbar width to figure width.
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            # By adding toolbar in sizer, we are able to put it at the bottom
            # of the frame - so appearance is closer to GTK version.
            # As noted above, doesn't work for Mac.
            self.toolbar.SetSize(wx.Size(fw, th))
            self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        # update the axes menu on the toolbar
        self.toolbar.update()
        self.canvas.mpl_connect("button_press_event", self.onButtonPress)

    # ---------------------------------------------------------------------

    def onFileExit(self,evt):
        pass
        
    def onLayout(self,evt):
        dlg=self.res.LoadDialog(self, "layoutDlg")
        wx.EVT_BUTTON(dlg,XRCID("button_OK"),
                   lambda evt: dlg.EndModal(wx.ID_OK))
        wx.EVT_BUTTON(dlg,XRCID("button_Cancel"),
                   lambda evt: dlg.EndModal(wx.ID_CANCEL))
        ret = dlg.ShowModal()
        if ret == wx.ID_OK:
            self.numRows = XRCCTRL(dlg, "rowSpin").GetValue()
            self.numCols = XRCCTRL(dlg, "colSpin").GetValue()
            self.newLayout()
        dlg.Destroy()

    def onButtonPress(self,evt):
        if not evt.inaxes:
            return
        if evt.button==wx.MOUSE_BTN_RIGHT and not self.toolbar._active:
            self.currentAxis = evt.inaxes
            x=evt.x
            y=self.canvas.GetSize().GetHeight()-evt.y
            self.PopupMenu(self.popup, wx.Point(x,y))

    def onTraceLine(self,evt):
        traceFile = self.openTraceFile()
        if not traceFile:
            return
        if evt.GetId() == ID_TRACE_NEW_LINE:
            self.currentAxis.clear()
        xvec=[]
        yvec=[]
        for line in traceFile:
            x,y=line.split()
            xvec.append(float(x))
            yvec.append(float(y))
        traceFile.close()
        self.currentAxis.plot(xvec,yvec)

    def onTraceNewBar(self,evt):
        traceFile = self.openTraceFile()
        if not traceFile:
            return
        data = {}
        for line in traceFile:
            # Lines have the format: time item1;item2;item3
            # where the items have the format: xvalue,yvalue
            t,line = line.split(' ',1)
            line = line.strip()
            if line:
                items=line.split(';')
                for item in items:
                    x,y=item.split(',')
                    data[int(x)]=float(y)
        traceFile.close()
        xvec=data.keys()
        yvec=data.values()
        self.currentAxis.bar(xvec,yvec)
        self.currentAxis.set_title("Trace: %s"%os.path.basename(traceFile.name))

    def onListenerNewLine(self,evt):
        result = self.newLineListenerDlg()
        if not result:
            return
        traceID,updateFreq,visiblePoints,keepInvisiblePoints = result
        if not traceID or not updateFreq or visiblePoints < 0:
            return
        self.onClearPlot(None)
        self.listeners[traceID] = LineListener(
            traceID, self.currentAxis, 1.0/updateFreq, visiblePoints,
            keepInvisiblePoints)

    def onListenerNewBar(self,evt):
        result = self.newBarListenerDlg()
        if not result:
            return
        traceID,updateFreq = result
        if not traceID or not updateFreq:
            return
        self.onClearPlot(None)
        self.listeners[traceID] = BarListener(
            traceID, self.currentAxis, 1.0/updateFreq) 

    def onClearPlot(self,evt):
        self.currentAxis.clear()
        for traceID,listener in self.listeners.items():
            if listener.axis == self.currentAxis:
                listener.unregister()
                del self.listeners[traceID]

    def onPlotParameters(self,evt):
        pass

    def onHelpAbout(self,evt):
        pass

    def OnPaint(self, evt):
        self.canvas.draw()

    def simReloaded(self):
        """Called by the simulation controller when the simulation is reloaded.

        Reregister all listeners, since they have been unregistered.
        """
        for listener in self.listeners.values():
            listener.reregister()
        
    # --------------------------------------------------------------------
    
    def newLayout(self):
        self.figure.clear()
        self.axes = []
	layoutCode = self.numRows*100 + self.numCols*10
        for row in range(self.numRows):
            for col in range(self.numCols):
                plotnum = row*self.numCols + col + 1
                axis=self.figure.add_subplot(layoutCode+plotnum)
                self.axes.append(axis)
        self.canvas.draw()
        for listener in self.listeners.values():
            listener.unregister()
        self.listeners={}
            

    def openTraceFile(self):
        dlg = wx.FileDialog(
            self, message="Choose a trace file",
            defaultDir=os.getcwd(), 
            defaultFile="",
            wildcard="All files (*.*)|*.*",
            style=wx.OPEN | wx.CHANGE_DIR)
        if dlg.ShowModal() != wx.ID_OK:
            return None
        filename = os.path.abspath(dlg.GetPaths()[0])
        try:
            traceFile=file(filename)
        except IOError,message:
            dlg = wx.MessageDialog(self, str(message),
                                   'File open error',
                                   wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            return None
        return traceFile