Beispiel #1
0
def transform_frame(frame,
                    transform,
                    columns=None,
                    direction='forward',
                    return_all=True,
                    args=(),
                    **kwargs):
    '''
    Apply transform to specified columns.

    direction: 'forward' | 'inverse'
    return_all: bool
        True -  return all columns, with specified ones transformed.
        False - return only specified columns.

    .. warning:: deprecated
    '''
    tfun, tname = parse_transform(transform, direction)
    columns = to_list(columns)
    if columns is None:
        columns = frame.columns
    if return_all:
        transformed = frame.copy()
        for c in columns:
            transformed[c] = tfun(frame[c], *args, **kwargs)
    else:
        transformed = frame.filter(columns).apply(tfun, *args, **kwargs)
    return transformed
    def apply(self, func, ids=None, applyto='measurement', noneval=nan,
              setdata=False, output_format='dict', ID=None,
              **kwargs):
        '''
        Apply func to each of the specified measurements.

        Parameters
        ----------
        func : callable 
            Accepts a Measurement object or a DataFrame. 
        ids : hashable| iterable of hashables | None
            Keys of measurements to which func will be applied.
            If None is given apply to all measurements. 
        applyto :  'measurement' | 'data'
            * 'measurement' : apply to measurements objects themselves.
            * 'data'        : apply to measurement associated data
        noneval : obj
            Value returned if applyto is 'data' but no data is available.
        setdata : bool
            Whether to set the data in the Measurement object.
            Used only if data is not already set.
        output_format : ['dict' | 'collection']
            * collection : keeps result as collection
            WARNING: For collection, func should return a copy of the measurement instance rather
            than the original measurement instance.
        Returns
        -------
        Dictionary keyed by measurement keys containing the corresponding output of func
        or returns a collection (if output_format='collection').
        '''
        if ids is None:
            ids = self.keys()
        else:
            ids = to_list(ids)
        result = dict((i, self[i].apply(func, applyto, noneval, setdata)) for i in ids)

        if output_format == 'collection':
            can_keep_as_collection = all(
                [isinstance(r, self._measurement_class) for r in result.values()])
            if not can_keep_as_collection:
                raise TypeError(
                    'Cannot turn output into a collection. The provided func must return results of type {}'.format(
                        self._measurement_class))

            new_collection = self.copy()
            # Locate IDs to remove
            ids_to_remove = [x for x in self.keys() if x not in ids]
            # Remove data for these IDs
            for ids in ids_to_remove:
                new_collection.pop(ids)
            # Update keys with new values
            for k, v in new_collection.iteritems():
                new_collection[k] = result[k]
            if ID is not None:
                new_collection.ID = ID
            return new_collection
        else:
            # Return a dictionary
            return result
Beispiel #3
0
    def add_callback(self, func):
        """ Registers a call back function """
        if func is None: return
        func_list = to_list(func)

        if not hasattr(self, 'callback_list'):
            self.callback_list = func_list
        else:
            self.callback_list.extend(func_list)
 def filter_by_key(self, keys, ID=None):
     """
     Keep only Measurements with given keys.
     """
     keys = to_list(keys)
     fil = lambda x: x in keys
     if ID is None:
         ID = self.ID
     return self.filter(fil, applyto='keys', ID=ID)
    def add_callback(self, func):
        """ Registers a call back function """
        if func is None: return
        func_list = to_list(func)

        if not hasattr(self, 'callback_list'):
            self.callback_list = func_list
        else:
            self.callback_list.extend(func_list)
Beispiel #6
0
 def filter_by_key(self, keys, ID=None):
     """
     Keep only Measurements with given keys.
     """
     keys = to_list(keys)
     fil = lambda x: x in keys
     if ID is None:
         ID = self.ID
     return self.filter(fil, applyto='keys', ID=ID)
Beispiel #7
0
 def filter_by_rows(self, rows, ID=None):
     """
     Keep only Measurements in corresponding rows.
     """
     rows = to_list(rows)
     fil = lambda x: x in rows
     applyto = {k: self._positions[k][0] for k in self.iterkeys()}
     if ID is None:
         ID = self.ID
     return self.filter(fil, applyto=applyto, ID=ID)
Beispiel #8
0
 def filter_by_cols(self, cols, ID=None):
     """
     Keep only Measurements in corresponding columns.
     """
     rows = to_list(cols)
     fil = lambda x: x in rows
     applyto = {k: self._positions[k][1] for k in self.iterkeys()}
     if ID is None:
         ID = self.ID + '.filtered_by_cols'
     return self.filter(fil, applyto=applyto, ID=ID)
 def filter_by_rows(self, rows, ID=None):
     """
     Keep only Measurements in corresponding rows.
     """
     rows = to_list(rows)
     fil = lambda x: x in rows
     applyto = {k: self._positions[k][0] for k in self.iterkeys()}
     if ID is None:
         ID = self.ID
     return self.filter(fil, applyto=applyto, ID=ID)
 def filter_by_cols(self, cols, ID=None):
     """
     Keep only Measurements in corresponding columns.
     """
     rows = to_list(cols)
     fil = lambda x: x in rows
     applyto = {k: self._positions[k][1] for k in self.iterkeys()}
     if ID is None:
         ID = self.ID + '.filtered_by_cols'
     return self.filter(fil, applyto=applyto, ID=ID)
Beispiel #11
0
    def __init__(self, vert, channels, region, name=None):
        self.vert = vert
        channels = to_list(channels)
        self.channels = channels

        if name == None:
            self.name = "Unnamed Gate {0}".format(Gate.unnamed_gate_num)
            Gate.unnamed_gate_num += 1
        else:
            self.name = name

        self.region = region
        self.validiate_input()
Beispiel #12
0
    def __init__(self, vert, channels, region, name=None):
        self.vert = vert
        channels = to_list(channels)
        self.channels = channels

        if name == None:
            self.name = "Unnamed Gate {0}".format(Gate.unnamed_gate_num)
            Gate.unnamed_gate_num += 1
        else:
            self.name = name

        self.region = region
        self.validate_input()
Beispiel #13
0
 def _find_orientation(self, ax_channels):
     ax_channels = to_list(ax_channels)
     c = self.channels[0]
     if ax_channels is not None:
         try:
             i = ax_channels.index(c)
             if i == 0:
                 flip = False
             else:
                 flip = True
         except ValueError:
             raise Exception("""Trying to plot gate that is defined on channel {0},
                             but figure axis correspond to channels {1}""".format(c, ax_channels))
     if len(self.channels) == 2:
         c = self.channels[1]
         if c not in ax_channels:
             raise Exception("""Trying to plot gate that is defined on channel {0},
                             but figure axis correspond to channels {1}""".format(c, ax_channels))
     return flip
Beispiel #14
0
 def get_measurement_metadata(self,
                              fields,
                              ids=None,
                              noneval=nan,
                              output_format='DataFrame'):
     """
     Get the metadata fields of specified measurements (all if None given).
     
     Parameters
     ----------
     fields : str | iterable of str 
         Names of metadata fields to be returned.
     ids : hashable| iterable of hashables | None
         Keys of measurements for which metadata will be returned.
         If None is given return metadata of all measurements. 
     noneval : obj
         Value returned if applyto is 'data' but no data is available.
     output_format :  'DataFrame' | 'dict'
         'DataFrame' : return DataFrame,
         'dict'      : return dictionary.
     
     Returns
     -------
     Measurement metadata in specified output_format.
     """
     fields = to_list(fields)
     func = lambda x: x.get_meta_fields(fields)
     meta_d = self.apply(func,
                         ids=ids,
                         applyto='measurement',
                         noneval=noneval,
                         output_format='dict')
     if output_format is 'dict':
         return meta_d
     elif output_format is 'DataFrame':
         from pandas import DataFrame as DF
         meta_df = DF(meta_d, index=fields)
         return meta_df
     else:
         msg = ("The output_format must be either 'dict' or 'DataFrame'. " +
                "Encountered unsupported value %s." % repr(output_format))
         raise Exception(msg)
Beispiel #15
0
    def set_positions(self, positions=None, position_mapper='name', ids=None):
        '''
        checks for position validity & collisions,
        but not that all measurements are assigned.

        Parameters
        -----------
        positions : is dict-like of measurement_key:(row,col)
        parser :
            callable - gets key and returns position
            mapping  - key:pos
            'name'   - parses things like 'A1', 'G12'
            'number' - converts number to positions, going over rows first.
        ids :
            parser will be applied to specified ids only. 
            If None is given, parser will be applied to all measurements.

        TODO: output a more informative message for position collisions
        '''
        if positions is None:
            if ids is None:
                ids = self.keys()
            else:
                ids = to_list(ids)
            mapper = self._get_ID2position_mapper(position_mapper)
            positions = dict((ID, mapper(ID)) for ID in ids)
        else:
            pass
        # check that resulting assignment is unique (one measurement per position)
        temp = self._positions.copy()
        temp.update(positions)
        if not len(temp.values()) == len(set(temp.values())):
            msg = 'A position can only be occupied by a single measurement'
            raise Exception(msg)

        for k, pos in positions.iteritems():
            if not self._is_valid_position(pos):
                msg = 'Position {} is not supported for this collection'.format(
                    pos)
                raise ValueError(msg)
            self._positions[k] = pos
            self[k]._set_position(self.ID, pos)
    def set_positions(self, positions=None, position_mapper='name', ids=None):
        '''
        checks for position validity & collisions,
        but not that all measurements are assigned.

        Parameters
        -----------
        positions : is dict-like of measurement_key:(row,col)
        parser :
            callable - gets key and returns position
            mapping  - key:pos
            'name'   - parses things like 'A1', 'G12'
            'number' - converts number to positions, going over rows first.
        ids :
            parser will be applied to specified ids only. 
            If None is given, parser will be applied to all measurements.

        TODO: output a more informative message for position collisions
        '''
        if positions is None:
            if ids is None:
                ids = self.keys()
            else:
                ids = to_list(ids)
            mapper = self._get_ID2position_mapper(position_mapper)
            positions = dict((ID, mapper(ID)) for ID in ids)
        else:
            pass
        # check that resulting assignment is unique (one measurement per position)
        temp = self._positions.copy()
        temp.update(positions)
        if not len(temp.values()) == len(set(temp.values())):
            msg = 'A position can only be occupied by a single measurement'
            raise Exception(msg)

        for k, pos in positions.iteritems():
            if not self._is_valid_position(pos):
                msg = 'Position {} is not supported for this collection'.format(pos)
                raise ValueError(msg)
            self._positions[k] = pos
            self[k]._set_position(self.ID, pos)
Beispiel #17
0
 def _find_orientation(self, ax_channels):
     ax_channels = to_list(ax_channels)
     c = self.channels[0]
     if ax_channels is not None:
         try:
             i = ax_channels.index(c)
             if i == 0:
                 flip = False
             else:
                 flip = True
         except ValueError:
             raise Exception("""Trying to plot gate that is defined on channel {0},
                             but figure axis correspond to channels {1}""".format(c,
                                                                                  ax_channels))
     if len(self.channels) == 2:
         c = self.channels[1]
         if c not in ax_channels:
             raise Exception("""Trying to plot gate that is defined on channel {0},
                             but figure axis correspond to channels {1}""".format(c,
                                                                                  ax_channels))
     return flip
def transform_frame(frame, transform, columns=None, direction='forward',
                    return_all=True, args=(), **kwargs):
    '''
    Apply transform to specified columns.

    direction: 'forward' | 'inverse'
    return_all: bool
        True -  return all columns, with specified ones transformed.
        False - return only specified columns.

    .. warning:: deprecated
    '''
    tfun, tname = parse_transform(transform, direction)
    columns = to_list(columns)
    if columns is None:
        columns = frame.columns
    if return_all:
        transformed = frame.copy()
        for c in columns:
            transformed[c] = tfun(frame[c], *args, **kwargs)
    else:
        transformed = frame.filter(columns).apply(tfun, *args, **kwargs)
    return transformed
 def get_measurement_metadata(self, fields, ids=None, noneval=nan,
                              output_format='DataFrame'):
     """
     Get the metadata fields of specified measurements (all if None given).
     
     Parameters
     ----------
     fields : str | iterable of str 
         Names of metadata fields to be returned.
     ids : hashable| iterable of hashables | None
         Keys of measurements for which metadata will be returned.
         If None is given return metadata of all measurements. 
     noneval : obj
         Value returned if applyto is 'data' but no data is available.
     output_format :  'DataFrame' | 'dict'
         'DataFrame' : return DataFrame,
         'dict'      : return dictionary.
     
     Returns
     -------
     Measurement metadata in specified output_format.
     """
     fields = to_list(fields)
     func = lambda x: x.get_meta_fields(fields)
     meta_d = self.apply(func, ids=ids, applyto='measurement',
                         noneval=noneval, output_format='dict')
     if output_format is 'dict':
         return meta_d
     elif output_format is 'DataFrame':
         from pandas import DataFrame as DF
         meta_df = DF(meta_d, index=fields)
         return meta_df
     else:
         msg = ("The output_format must be either 'dict' or 'DataFrame'. " +
                "Encountered unsupported value %s." % repr(output_format))
         raise Exception(msg)
 def set_visible(self, visible=True):
     for artist in to_list(self.artist):
         artist.set_visible(visible)
Beispiel #21
0
def plotFCM(data,
            channel_names,
            kind='histogram',
            ax=None,
            autolabel=True,
            xlabel_kwargs={},
            ylabel_kwargs={},
            colorbar=False,
            grid=False,
            **kwargs):
    """
    Plots the sample on the current axis.

    Follow with a call to matplotlibs show() in order to see the plot.

    Parameters
    ----------
    data : DataFrame
    {graph_plotFCM_pars}
    {common_plot_ax}

    Returns
    -------
    The output of the plot command used
    """
    if ax == None: ax = pl.gca()

    xlabel_kwargs.setdefault('size', 16)
    ylabel_kwargs.setdefault('size', 16)

    channel_names = to_list(channel_names)

    if len(channel_names) == 1:
        # 1D so histogram plot
        kwargs.setdefault('color', 'gray')
        kwargs.setdefault('histtype', 'stepfilled')
        kwargs.setdefault('bins', 200)  # Do not move above

        x = data[channel_names[0]].values
        if len(x) >= 1:
            if (len(x) == 1) and isinstance(kwargs['bins'], int):
                # Only needed for hist (not hist2d) due to hist function doing
                # excessive input checking
                warnings.warn("One of the data sets only has a single event. " \
                              "This event won't be plotted unless the bin locations" \
                              " are explicitely provided to the plotting function. ")
                return None
            plot_output = ax.hist(x, **kwargs)
        else:
            return None

    elif len(channel_names) == 2:
        x = data[channel_names[0]].values  # value of first channel
        y = data[channel_names[1]].values  # value of second channel

        if len(x) == 0:
            # Don't draw a plot if there's no data
            return None
        if kind == 'scatter':
            kwargs.setdefault('edgecolor', 'none')
            plot_output = ax.scatter(x, y, **kwargs)
        elif kind == 'histogram':
            kwargs.setdefault('bins', 200)  # Do not move above
            kwargs.setdefault('cmin', 1)
            kwargs.setdefault('cmap', pl.cm.copper)
            kwargs.setdefault('norm', matplotlib.colors.LogNorm())
            plot_output = ax.hist2d(x, y, **kwargs)
            mappable = plot_output[-1]

            if colorbar:
                pl.colorbar(mappable, ax=ax)
        else:
            raise ValueError(
                "Not a valid plot type. Must be 'scatter', 'histogram'")

    pl.grid(grid)

    if autolabel:
        y_label_text = 'Counts' if len(
            channel_names) == 1 else channel_names[1]
        ax.set_xlabel(channel_names[0], **xlabel_kwargs)
        ax.set_ylabel(y_label_text, **ylabel_kwargs)

    return plot_output
Beispiel #22
0
 def set_visible(self, visible=True):
     for artist in to_list(self.artist):
         artist.set_visible(visible)
Beispiel #23
0
 def create_artist(self):
     self.poly = pl.Polygon(self.coordinates, color='k', fill=False)
     self.artist_list = to_list(self.poly)
     self.ax.add_artist(self.poly)
    def grid_plot(self, func, applyto='measurement', ids=None,
                  row_labels=None, col_labels=None,
                  xlim='auto', ylim='auto',
                  xlabel=None, ylabel=None,
                  colorbar=True,
                  row_label_xoffset=None, col_label_yoffset=None,
                  hide_tick_labels=True, hide_tick_lines=True,
                  hspace=0, wspace=0,
                  row_labels_kwargs={}, col_labels_kwargs={}):
        """
        Creates subplots for each well in the plate. Uses func to plot on each axis.
        Follow with a call to matplotlibs show() in order to see the plot.

        Parameters
        ----------
        func : callable
            func is a callable that accepts a measurement
            object (with an optional axis reference) and plots on the current axis.
            Return values from func are ignored.
            .. note: if using applyto='measurement', the function
            when querying for data should make sure that the data
            actually exists
        applyto : 'measurement' | 'data'
        {_graph_grid_layout}
        {bases_OrderedCollection_grid_plot_pars}

        Returns
        -------
        {_graph_grid_layout_returns}

        Examples
        ---------
        >>> def y(well, ax):
        >>>     data = well.get_data()
        >>>     if data is None:
        >>>         return None
        >>>     graph.plotFCM(data, 'Y2-A')
        >>> def z(data, ax):
        >>>     plot(data[0:100, 1], data[0:100, 2])
        >>> plate.plot(y, applyto='measurement');
        >>> plate.plot(z, applyto='data');
        """
        # Acquire call arguments to be passed to create plate layout
        callArgs = locals().copy()  # This statement must remain first. The copy is just defensive.
        [callArgs.pop(varname) for varname in
         ['self', 'func', 'applyto', 'ids', 'colorbar', 'xlim', 'ylim']]  # pop args

        callArgs['rowNum'] = self.shape[0]
        callArgs['colNum'] = self.shape[1]

        subplots_adjust_args = {}
        subplots_adjust_args.setdefault('right', 0.85)
        subplots_adjust_args.setdefault('top', 0.85)
        pl.subplots_adjust(**subplots_adjust_args)

        # Uses plate default row/col labels if user does not override them by specifying row/col labels
        if row_labels == None: callArgs['row_labels'] = self.row_labels
        if col_labels == None: callArgs['col_labels'] = self.col_labels

        ax_main, ax_subplots = graph.create_grid_layout(**callArgs)
        subplots_ax = DF(ax_subplots, index=self.row_labels, columns=self.col_labels)

        if ids is None:
            ids = self.keys()
        ids = to_list(ids)

        for ID in ids:
            measurement = self[ID]
            if not hasattr(measurement, 'data'):
                continue

            row, col = self._positions[ID]
            ax = subplots_ax[col][row]
            pl.sca(ax)  # sets the current axis

            if applyto == 'measurement':
                func(measurement, ax)  # reminder: pandas row/col order is reversed
            elif applyto == 'data':
                data = measurement.get_data()
                if data is not None:
                    if func.func_code.co_argcount == 1:
                        func(data)
                    else:
                        func(data, ax)
            else:
                raise ValueError('Encountered unsupported value {} for applyto parameter.'.format(
                    applyto))

        # Autoscaling axes
        graph.scale_subplots(ax_subplots, xlim=xlim, ylim=ylim)

        #####
        # Placing ticks on the top left subplot
        ax_label = ax_subplots[0, -1]
        pl.sca(ax_label)

        if xlabel:
            xlim = ax_label.get_xlim()
            pl.xticks([xlim[0], xlim[1]], rotation=90)

        if ylabel:
            ylim = ax_label.get_ylim()
            pl.yticks([ylim[0], ylim[1]], rotation=0)

        pl.sca(ax_main)  # sets to the main axis -- more intuitive

        return ax_main, ax_subplots
def plotFCM(data, channel_names, kind='histogram', ax=None,
            autolabel=True, xlabel_kwargs={}, ylabel_kwargs={},
            colorbar=False, grid=False,
            **kwargs):
    """
    Plots the sample on the current axis.

    Follow with a call to matplotlibs show() in order to see the plot.

    Parameters
    ----------
    data : DataFrame
    {graph_plotFCM_pars}
    {common_plot_ax}

    Returns
    -------
    The output of the plot command used
    """
    if ax == None: ax = pl.gca()

    xlabel_kwargs.setdefault('size', 16)
    ylabel_kwargs.setdefault('size', 16)

    channel_names = to_list(channel_names)

    if len(channel_names) == 1:
        # 1D so histogram plot
        kwargs.setdefault('color', 'gray')
        kwargs.setdefault('histtype', 'stepfilled')
        kwargs.setdefault('bins', 200)  # Do not move above

        x = data[channel_names[0]].values
        if len(x) >= 1:
            if (len(x) == 1) and isinstance(kwargs['bins'], int):
                # Only needed for hist (not hist2d) due to hist function doing
                # excessive input checking
                warnings.warn("One of the data sets only has a single event. " \
                              "This event won't be plotted unless the bin locations" \
                              " are explicitely provided to the plotting function. ")
                return None
            plot_output = ax.hist(x, **kwargs)
        else:
            return None

    elif len(channel_names) == 2:
        x = data[channel_names[0]].values  # value of first channel
        y = data[channel_names[1]].values  # value of second channel

        if len(x) == 0:
            # Don't draw a plot if there's no data
            return None
        if kind == 'scatter':
            kwargs.setdefault('edgecolor', 'none')
            plot_output = ax.scatter(x, y, **kwargs)
        elif kind == 'histogram':
            kwargs.setdefault('bins', 200)  # Do not move above
            kwargs.setdefault('cmin', 1)
            kwargs.setdefault('cmap', pl.cm.copper)
            kwargs.setdefault('norm', matplotlib.colors.LogNorm())
            plot_output = ax.hist2d(x, y, **kwargs)
            mappable = plot_output[-1]

            if colorbar:
                pl.colorbar(mappable, ax=ax)
        else:
            raise ValueError("Not a valid plot type. Must be 'scatter', 'histogram'")

    pl.grid(grid)

    if autolabel:
        y_label_text = 'Counts' if len(channel_names) == 1 else channel_names[1]
        ax.set_xlabel(channel_names[0], **xlabel_kwargs)
        ax.set_ylabel(y_label_text, **ylabel_kwargs)

    return plot_output
Beispiel #26
0
    def grid_plot(self,
                  func,
                  applyto='measurement',
                  ids=None,
                  row_labels=None,
                  col_labels=None,
                  xlim='auto',
                  ylim='auto',
                  xlabel=None,
                  ylabel=None,
                  colorbar=True,
                  row_label_xoffset=None,
                  col_label_yoffset=None,
                  hide_tick_labels=True,
                  hide_tick_lines=True,
                  hspace=0,
                  wspace=0,
                  row_labels_kwargs={},
                  col_labels_kwargs={}):
        """
        Creates subplots for each well in the plate. Uses func to plot on each axis.
        Follow with a call to matplotlibs show() in order to see the plot.

        Parameters
        ----------
        func : callable
            func is a callable that accepts a measurement
            object (with an optional axis reference) and plots on the current axis.
            Return values from func are ignored.
            .. note: if using applyto='measurement', the function
            when querying for data should make sure that the data
            actually exists
        applyto : 'measurement' | 'data'
        {_graph_grid_layout}
        {bases_OrderedCollection_grid_plot_pars}

        Returns
        -------
        {_graph_grid_layout_returns}

        Examples
        ---------
        >>> def y(well, ax):
        >>>     data = well.get_data()
        >>>     if data is None:
        >>>         return None
        >>>     graph.plotFCM(data, 'Y2-A')
        >>> def z(data, ax):
        >>>     plot(data[0:100, 1], data[0:100, 2])
        >>> plate.plot(y, applyto='measurement');
        >>> plate.plot(z, applyto='data');
        """
        # Acquire call arguments to be passed to create plate layout
        callArgs = locals().copy(
        )  # This statement must remain first. The copy is just defensive.
        [
            callArgs.pop(varname) for varname in
            ['self', 'func', 'applyto', 'ids', 'colorbar', 'xlim', 'ylim']
        ]  # pop args

        callArgs['rowNum'] = self.shape[0]
        callArgs['colNum'] = self.shape[1]

        subplots_adjust_args = {}
        subplots_adjust_args.setdefault('right', 0.85)
        subplots_adjust_args.setdefault('top', 0.85)
        pl.subplots_adjust(**subplots_adjust_args)

        # Uses plate default row/col labels if user does not override them by specifying row/col labels
        if row_labels == None: callArgs['row_labels'] = self.row_labels
        if col_labels == None: callArgs['col_labels'] = self.col_labels

        ax_main, ax_subplots = graph.create_grid_layout(**callArgs)
        subplots_ax = DF(ax_subplots,
                         index=self.row_labels,
                         columns=self.col_labels)

        if ids is None:
            ids = self.keys()
        ids = to_list(ids)

        for ID in ids:
            measurement = self[ID]
            if not hasattr(measurement, 'data'):
                continue

            row, col = self._positions[ID]
            ax = subplots_ax[col][row]
            pl.sca(ax)  # sets the current axis

            if applyto == 'measurement':
                func(measurement,
                     ax)  # reminder: pandas row/col order is reversed
            elif applyto == 'data':
                data = measurement.get_data()
                if data is not None:
                    if func.func_code.co_argcount == 1:
                        func(data)
                    else:
                        func(data, ax)
            else:
                raise ValueError(
                    'Encountered unsupported value {} for applyto parameter.'.
                    format(applyto))

        # Autoscaling axes
        graph.scale_subplots(ax_subplots, xlim=xlim, ylim=ylim)

        #####
        # Placing ticks on the top left subplot
        ax_label = ax_subplots[0, -1]
        pl.sca(ax_label)

        if xlabel:
            xlim = ax_label.get_xlim()
            pl.xticks([xlim[0], xlim[1]], rotation=90)

        if ylabel:
            ylim = ax_label.get_ylim()
            pl.yticks([ylim[0], ylim[1]], rotation=0)

        pl.sca(ax_main)  # sets to the main axis -- more intuitive

        return ax_main, ax_subplots
Beispiel #27
0
    def apply(self,
              func,
              ids=None,
              applyto='measurement',
              noneval=nan,
              setdata=False,
              output_format='dict',
              ID=None,
              **kwargs):
        '''
        Apply func to each of the specified measurements.

        Parameters
        ----------
        func : callable 
            Accepts a Measurement object or a DataFrame. 
        ids : hashable| iterable of hashables | None
            Keys of measurements to which func will be applied.
            If None is given apply to all measurements. 
        applyto :  'measurement' | 'data'
            * 'measurement' : apply to measurements objects themselves.
            * 'data'        : apply to measurement associated data
        noneval : obj
            Value returned if applyto is 'data' but no data is available.
        setdata : bool
            Whether to set the data in the Measurement object.
            Used only if data is not already set.
        output_format : ['dict' | 'collection']
            * collection : keeps result as collection
            WARNING: For collection, func should return a copy of the measurement instance rather
            than the original measurement instance.
        Returns
        -------
        Dictionary keyed by measurement keys containing the corresponding output of func
        or returns a collection (if output_format='collection').
        '''
        if ids is None:
            ids = self.keys()
        else:
            ids = to_list(ids)
        result = dict(
            (i, self[i].apply(func, applyto, noneval, setdata)) for i in ids)

        if output_format == 'collection':
            can_keep_as_collection = all([
                isinstance(r, self._measurement_class)
                for r in result.values()
            ])
            if not can_keep_as_collection:
                raise TypeError(
                    'Cannot turn output into a collection. The provided func must return results of type {}'
                    .format(self._measurement_class))

            new_collection = self.copy()
            # Locate IDs to remove
            ids_to_remove = [x for x in self.keys() if x not in ids]
            # Remove data for these IDs
            for ids in ids_to_remove:
                new_collection.pop(ids)
            # Update keys with new values
            for k, v in new_collection.iteritems():
                new_collection[k] = result[k]
            if ID is not None:
                new_collection.ID = ID
            return new_collection
        else:
            # Return a dictionary
            return result
 def create_artist(self):
     self.poly = pl.Polygon(self.coordinates, color='k', fill=False)
     self.artist_list = to_list(self.poly)
     self.ax.add_artist(self.poly)