Example #1
0
class PlotPanel(wx.Panel):
    """
    The PlotPanel
    """
    def __init__(self,
                 parent,
                 name=None,
                 color=None,
                 dpi=None,
                 n_axes=1,
                 **kwargs):
        # initialize Panel
        if 'id' not in iter(kwargs.keys()):
            kwargs['id'] = wx.ID_ANY
        if 'style' not in iter(kwargs.keys()):
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)
        self.SetMinSize((100, 40))

        # The logging logger instance.
        loggerName = __name__ + "." + self.__class__.__name__
        self.logger = logging.getLogger(loggerName)

        # The name of the plot panel.
        self.name = name

        # initialize matplotlib stuff
        self.figure = mpl.figure.Figure(None, dpi=dpi, facecolor='white')
        self.canvas = FigureCanvas(self, -1, self.figure)

        # The axes.
        self._axes = []
        axes_height = 1 / n_axes
        for k in range(n_axes):
            self._axes.append(
                self.figure.add_axes([0, k * axes_height, 1, axes_height]))
        self.canvas.SetMinSize((30, 10))
        self.SetBackgroundColour('white')

        # The axes backgrounds for blit animation.
        self.blit_backgrounds = []

        # Add the canvas to the sizer.
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        self.canvas.Bind(wx.EVT_SET_FOCUS, self.on_set_focus)
        self.Bind(wx.EVT_SET_FOCUS, self.on_set_focus2)
        self.canvas.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.canvas.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.canvas.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)

    @property
    def axes(self):
        ''' The axes of the panel.

        If only one axis is present, return the axes, otherwise return a list of axes.
        '''
        if len(self._axes) == 1:
            return self._axes[0]
        else:
            return self._axes

    def on_wx_xlick(self, event):
        self.logger.debug("on_wx_xlick in plot_panel %s. event: %s", self.name,
                          event)

    def on_set_focus(self, event):
        self.logger.debug("on_set_focus in plot_panel %s. event: %s",
                          self.name, event)
        self.logger.debug("Event should propagate: %s",
                          event.ShouldPropagate())
        #event.ResumePropagation(1)
        event.Skip()

    def on_set_focus2(self, event):
        self.logger.debug("on_set_focus2 in plot_panel %s. event: %s",
                          self.name, event)

    def on_key_down(self, event):
        self.logger.debug("on_key_down in plot_panel %s. event: %s", self.name,
                          event)
        event.ResumePropagation(1)
        event.Skip()

    def on_key_up(self, event):
        self.logger.debug("on_key_up in plot_panel %s. event: %s", self.name,
                          event)
        event.ResumePropagation(1)
        event.Skip()

    def on_left_down(self, event):
        self.logger.debug("on_left_down in plot_panel %s. event: %s",
                          self.name, event)
        event.ResumePropagation(30)
        event.Skip()

    def set_color(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))
        self.canvas.Refresh()

    def set_n_axes(self, n_axes):
        ''' Set the number of axes provided by the plot panel.
        '''
        # Delete the existing axes.
        for cur_ax in self._axes:
            self.figure.delaxes(cur_ax)
        self._axes = []

        # Create the new number of axes.
        axes_height = old_div(1, n_axes)
        for k in range(n_axes):
            self._axes.append(
                self.figure.add_axes([0, k * axes_height, 1, axes_height]))

    def draw(self):
        ''' Draw the canvas to make the changes visible.
        '''
        self.canvas.draw()

    def save_blit_background(self):
        ''' Save the axes background for animation.
        '''
        self.blit_backgrounds = []
        for cur_axes in self._axes:
            self.blit_backgrounds.append(
                self.canvas.copy_from_bbox(cur_axes.bbox))

    def restore_blit_background(self):
        ''' Restore the axes background for animation.
        '''
        for k, cur_bg in enumerate(self.blit_backgrounds):
            self.canvas.restore_region(cur_bg, bbox=self._axes[k].bbox)

    def draw_blit_artists(self, artists):
        ''' Draw the artist for animation.
        '''
        for cur_artist in artists:
            for cur_line_artist in cur_artist.line_artist:
                cur_line_artist.axes.draw_artist(cur_line_artist)

            for cur_text_artist in cur_artist.text_artist:
                cur_text_artist.axes.draw_artist(cur_text_artist)

    def update_display(self):
        ''' Update the display of the docking frame.

        '''
        assert False, 'The update_display method must be defined!'
Example #2
0
class ParticleMotionFrame(wx.Frame):
    '''
    '''
    def __init__(self,
                 parent=None,
                 id=wx.ID_ANY,
                 title='particle motion',
                 size=(600, 600),
                 dpi=90):
        ''' Initialize the instance.
        '''
        wx.Frame.__init__(self,
                          parent=parent,
                          id=id,
                          title=title,
                          pos=wx.DefaultPosition,
                          style=wx.DEFAULT_FRAME_STYLE)
        self.SetMinSize(size)

        # initialize matplotlib stuff
        self.figure = mpl.figure.Figure(None, dpi=dpi, facecolor='white')
        self.canvas = FigureCanvas(self, -1, self.figure)

        #self.grid = axesgrid.AxesGrid(self.figure, 111,
        #                              nrows_ncols = (2, 2),
        #                              axes_pad = 0,
        #                              label_mode = "1")

        self.axes = {}
        self.axes['xy'] = self.figure.add_subplot(111)
        self.axes['xy'].set_aspect('equal')
        self.divider = axesgrid.make_axes_locatable(self.axes['xy'])
        self.axes['yz'] = self.divider.append_axes("right",
                                                   size="100%",
                                                   pad=0,
                                                   sharey=self.axes['xy'])
        self.axes['xz'] = self.divider.append_axes("bottom",
                                                   size="100%",
                                                   pad=0,
                                                   sharex=self.axes['xy'])
        self.annotate_axes()

        self.canvas.SetMinSize((30, 10))
        self.SetBackgroundColour('white')

        # Add the canvas to the sizer.
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        # The particle motion lines.
        self.lines = {}
        self.lines['xy'] = None
        self.lines['xz'] = None
        self.lines['yz'] = None

        # The particle motion start markers.
        self.start_markers = {}
        self.start_markers['xy'] = None
        self.start_markers['xz'] = None
        self.start_markers['yz'] = None

        # The feature annotation.
        self.feature_text = None

    def annotate_axes(self):
        ''' Annotate the axes.
        '''
        self.axes['xy'].set_xlabel('x')
        self.axes['xy'].set_ylabel('y')
        self.axes['xy'].xaxis.set_label_position('top')
        self.axes['xy'].xaxis.set_tick_params(labeltop=False,
                                              labelbottom=False)

        self.axes['xz'].set_xlabel('x')
        self.axes['xz'].set_ylabel('z')

        self.axes['yz'].set_xlabel('z')
        self.axes['yz'].set_ylabel('y')
        self.axes['yz'].get_xaxis().set_label_position('top')
        self.axes['yz'].get_yaxis().set_label_position('right')
        self.axes['yz'].xaxis.set_tick_params(labeltop=False,
                                              labelbottom=False)
        self.axes['yz'].yaxis.set_tick_params(labelleft=False, labelright=True)

    def clear_axes(self):
        ''' Clear all plots in the axes.
        '''
        for cur_key, cur_axes in self.axes.items():
            if self.lines[cur_key] is not None:
                cur_axes.lines.remove(self.lines[cur_key])
                del self.lines[cur_key]
                self.lines[cur_key] = None

            if self.start_markers[cur_key] is not None:
                cur_axes.lines.remove(self.start_markers[cur_key])
                del self.start_markers[cur_key]
                self.start_markers[cur_key] = None

    def plot_xy(self, x_data, y_data, start_marker=False):
        ''' Plot the xy particle motion.
        '''
        self.plot(x=x_data, y=y_data, mode='xy', start_marker=start_marker)

    def plot_xz(self, x_data, z_data, start_marker=False):
        ''' Plot the xy particle motion.
        '''
        self.plot(x=x_data, y=z_data, mode='xz', start_marker=start_marker)

    def plot_yz(self, y_data, z_data, start_marker=False):
        ''' Plot the xy particle motion.
        '''
        self.plot(x=z_data, y=y_data, mode='yz', start_marker=start_marker)

    def plot(self, x, y, mode, start_marker=False):
        ''' Plot data in the corresponding axes.

        '''
        cur_axes = self.axes[mode]
        cur_line = self.lines[mode]
        if cur_line is None:
            cur_lines = cur_axes.plot(x, y, 'k')
            self.lines[mode] = cur_lines[0]
        else:
            cur_line.set_xdata(x)
            cur_line.set_ydata(y)

        if start_marker:
            cur_lines = cur_axes.plot(x[0], y[0], 'ro')
            self.start_markers[mode] = cur_lines[0]

    def set_feature_annotation(self, features):
        '''
        '''
        if self.feature_text is not None:
            self.axes['xz'].texts.remove(self.feature_text)

        azimuth = np.rad2deg(features['azimuth'])
        if azimuth < 0:
            azimuth = azimuth + 180

        msg = "Polarization features:\n\n"
        msg += "polarization strength: %f" % features['pol_strength'] + '\n'
        msg += "ellipticity: %f" % features['ellipticity'] + '\n'
        msg += "apparent azimuth: %f / %f" % (azimuth, azimuth + 180) + "\n"
        msg += "apparent incidence: %f" % np.rad2deg(
            features['incidence']) + "\n"
        self.feature_text = self.axes['xz'].text(
            1.1,
            0.95,
            msg,
            verticalalignment='top',
            horizontalalignment='left',
            transform=self.axes['xz'].transAxes,
            size=10)

    def set_axes_limits(self):
        ''' Adjust the axes limits.
        '''
        max_amp = []
        for cur_line in self.lines.values():
            cur_x_max = np.max(np.abs(cur_line.get_xdata()))
            cur_y_max = np.max(np.abs(cur_line.get_ydata()))
            max_amp.append(np.max([cur_x_max, cur_y_max]))
        max_amp = np.max(max_amp)

        for cur_axes in self.axes.values():
            cur_axes.set_xlim((-max_amp, max_amp))
            cur_axes.set_ylim((-max_amp, max_amp))
Example #3
0
class PlotPanel(wx.Panel):
    """
    The PlotPanel
    """
    def __init__(self, parent, name=None, color=None, dpi=None, **kwargs):
        # 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)
        self.SetMinSize((100, 40))

        # The logging logger instance.
        loggerName = __name__ + "." + self.__class__.__name__
        self.logger = logging.getLogger(loggerName)

        # The name of the plot panel.
        self.name = name

        # initialize matplotlib stuff
        self.figure = mpl.figure.Figure(None, dpi=dpi, facecolor='white')
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_axes([0, 0, 1, 1])
        self.canvas.SetMinSize((30, 10))
        self.SetBackgroundColour('white')

        # Add the canvas to the sizer.
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        self.canvas.Bind(wx.EVT_SET_FOCUS, self.on_set_focus)
        self.Bind(wx.EVT_SET_FOCUS, self.on_set_focus2)
        self.canvas.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.canvas.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.canvas.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)

    def on_wx_xlick(self, event):
        self.logger.debug("on_wx_xlick in plot_panel %s. event: %s", self.name,
                          event)

    def on_set_focus(self, event):
        self.logger.debug("on_set_focus in plot_panel %s. event: %s",
                          self.name, event)
        self.logger.debug("Event should propagate: %s",
                          event.ShouldPropagate())
        #event.ResumePropagation(1)
        event.Skip()

    def on_set_focus2(self, event):
        self.logger.debug("on_set_focus2 in plot_panel %s. event: %s",
                          self.name, event)

    def on_key_down(self, event):
        self.logger.debug("on_key_down in plot_panel %s. event: %s", self.name,
                          event)
        event.ResumePropagation(1)
        event.Skip()

    def on_key_up(self, event):
        self.logger.debug("on_key_up in plot_panel %s. event: %s", self.name,
                          event)
        event.ResumePropagation(1)
        event.Skip()

    def on_left_down(self, event):
        self.logger.debug("on_left_down in plot_panel %s. event: %s",
                          self.name, event)
        event.ResumePropagation(30)
        event.Skip()

    def set_color(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))
        self.canvas.Refresh()

    def draw(self):
        ''' Draw the canvas to make the changes visible.
        '''
        self.canvas.draw()

    def update_display(self):
        ''' Update the display of the docking frame.

        '''
        assert False, 'The update_display method must be defined!'
Example #4
0
class MagcalPanel(wx.Panel):
    _status_markup_strings = {
        mavlink.MAG_CAL_NOT_STARTED: 'Not started',
        mavlink.MAG_CAL_WAITING_TO_START: 'Waiting to start',
        mavlink.MAG_CAL_RUNNING_STEP_ONE: 'Step one',
        mavlink.MAG_CAL_RUNNING_STEP_TWO: 'Step two',
        mavlink.MAG_CAL_SUCCESS: '<span color="blue">Success</span>',
        mavlink.MAG_CAL_FAILED: '<span  color="red">Failed</span>',
    }

    _empty_color = '#7ea6ce'
    _filled_color = '#4680b9'

    def __init__(self, *k, **kw):
        super(MagcalPanel, self).__init__(*k, **kw)

        facecolor = self.GetBackgroundColour().GetAsString(wx.C2S_HTML_SYNTAX)
        fig = plt.figure(facecolor=facecolor, figsize=(1, 1))

        self._canvas = FigureCanvas(self, wx.ID_ANY, fig)
        self._canvas.SetMinSize((300, 300))

        self._id_text = wx.StaticText(self, wx.ID_ANY)
        self._status_text = wx.StaticText(self, wx.ID_ANY)
        self._completion_pct_text = wx.StaticText(self, wx.ID_ANY)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self._id_text)
        sizer.Add(self._status_text)
        sizer.Add(self._completion_pct_text)
        sizer.Add(self._canvas, proportion=1, flag=wx.EXPAND)
        self.SetSizer(sizer)

        ax = fig.add_subplot(111, axis_bgcolor=facecolor, projection='3d')
        self.configure_plot(ax)

    def configure_plot(self, ax):
        extra = .5
        lim = grid.radius + extra
        ax.set_xlim3d(-lim, lim)
        ax.set_ylim3d(-lim, lim)
        ax.set_zlim3d(-lim, lim)

        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_zlabel('z')

        ax.invert_zaxis()
        ax.invert_xaxis()

        ax.set_aspect('equal')

        self._polygons_collection = Poly3DCollection(
            grid.sections_triangles,
            edgecolors='#386694',
        )
        ax.add_collection3d(self._polygons_collection)

    def update_status_from_mavlink(self, m):
        status_string = self._status_markup_strings.get(m.cal_status, '???')
        self._status_text.SetLabelMarkup('<b>Status:</b> %s' % status_string, )

    def mavlink_magcal_report(self, m):
        self.update_status_from_mavlink(m)
        self._completion_pct_text.SetLabel('')

    def mavlink_magcal_progress(self, m):
        facecolors = []
        for i, mask in enumerate(m.completion_mask):
            for j in range(8):
                section = i * 8 + j
                if mask & 1 << j:
                    facecolor = self._filled_color
                else:
                    facecolor = self._empty_color
                facecolors.append(facecolor)
        self._polygons_collection.set_facecolors(facecolors)
        self._canvas.draw()

        self._id_text.SetLabelMarkup('<b>Compass id:</b> %d' % m.compass_id)

        self._completion_pct_text.SetLabelMarkup('<b>Completion:</b> %d%%' %
                                                 m.completion_pct)

        self.update_status_from_mavlink(m)

    _legend_panel = None

    @staticmethod
    def legend_panel(*k, **kw):
        if MagcalPanel._legend_panel:
            return MagcalPanel._legend_panel

        p = MagcalPanel._legend_panel = wx.Panel(*k, **kw)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        p.SetSizer(sizer)

        marker = wx.Panel(p, wx.ID_ANY, size=(10, 10))
        marker.SetBackgroundColour(MagcalPanel._empty_color)
        sizer.Add(marker, flag=wx.ALIGN_CENTER)
        text = wx.StaticText(p, wx.ID_ANY)
        text.SetLabel('Sections not hit')
        sizer.Add(text, border=4, flag=wx.ALIGN_CENTER | wx.LEFT)

        marker = wx.Panel(p, wx.ID_ANY, size=(10, 10))
        marker.SetBackgroundColour(MagcalPanel._filled_color)
        sizer.Add(marker, border=10, flag=wx.ALIGN_CENTER | wx.LEFT)
        text = wx.StaticText(p, wx.ID_ANY)
        text.SetLabel('Sections hit')
        sizer.Add(text, border=4, flag=wx.ALIGN_CENTER | wx.LEFT)
        return p