コード例 #1
0
def divby(df, divisor=0, axis=0, sameshape=True):
    ''' Small wrapper around pandas.divide() that takes in either column integers, names,
    or entire arrays as the divisor.  Note, pandas.divide by default is rowwise, but here
    it defaults to column-wise.
    
    Parameters:
    -----------
      df:  Dataframe object.
      divisor: (See notes below)
      axis: Division axis. 0=column-wise division. 1=row-wise
      sameshape: If true, function will check that the divisor as the same shape as
        the data along that axis.  For example, is an array of 2000 units, 
        and axis=0, then the row dimension must be 2000 for the dataframe.
        AFAIK df.div does not enforce this stringency, which sometimes can lead
        to hard-to-find bugs.
    
    Notes:
    ------
      This program first checks if divisor is an integer.  If not, it attempts
      to lookup by rowname or columnname.  Finally, it tries to divide by the divisor itself,
      if the divisor is an array/series.  This seemed like a flexible way to do this 
      without too much type checking.'''

    ### Column-wise division
    if axis==0:        
        if isinstance(divisor, int):
            divisor=df.columns[divisor]
        
        else:
            try:
                divisor=df[divisor]
            except Exception:
                pass #divisor=divisor
            
        divlen=df.shape[0] #Store length of a single column


    ### Rowwise division    
    elif axis==1:
        if isinstance(divisor, int):
            divisor=df.ix[divisor]
        
        else:
            try:
                divisor=df.xs(divisor)
            except KeyError:
                pass
            
        divlen=df.shape[1]
        
    else:
        raise badvalue_error('axis', '0,1')
    
    ### Enforce strict shapetype
    if sameshape:
        if len(divisor) != divlen:
            raise TypeError('Divisor dimensions %s do not match dividend' 
            ' dimension %s along axis = %s'%(divlen, len(divisor), axis))
    
    return df.divide(divisor, axis=axis)
コード例 #2
0
def divby(df, divisor=0, axis=0, sameshape=True):
    ''' Small wrapper around pandas.divide() that takes in either column integers, names,
    or entire arrays as the divisor.  Note, pandas.divide by default is rowwise, but here
    it defaults to column-wise.
    
    Parameters:
    -----------
      df:  Dataframe object.
      divisor: (See notes below)
      axis: Division axis. 0=column-wise division. 1=row-wise
      sameshape: If true, function will check that the divisor as the same shape as
        the data along that axis.  For example, is an array of 2000 units, 
        and axis=0, then the row dimension must be 2000 for the dataframe.
        AFAIK df.div does not enforce this stringency, which sometimes can lead
        to hard-to-find bugs.
    
    Notes:
    ------
      This program first checks if divisor is an integer.  If not, it attempts
      to lookup by rowname or columnname.  Finally, it tries to divide by the divisor itself,
      if the divisor is an array/series.  This seemed like a flexible way to do this 
      without too much type checking.'''

    ### Column-wise division
    if axis == 0:
        if isinstance(divisor, int):
            divisor = df.columns[divisor]

        else:
            try:
                divisor = df[divisor]
            except Exception:
                pass  #divisor=divisor

        divlen = df.shape[0]  #Store length of a single column

    ### Rowwise division
    elif axis == 1:
        if isinstance(divisor, int):
            divisor = df.ix[divisor]

        else:
            try:
                divisor = df.xs(divisor)
            except KeyError:
                pass

        divlen = df.shape[1]

    else:
        raise badvalue_error('axis', '0,1')

    ### Enforce strict shapetype
    if sameshape:
        if len(divisor) != divlen:
            raise TypeError('Divisor dimensions %s do not match dividend'
                            ' dimension %s along axis = %s' %
                            (divlen, len(divisor), axis))

    return df.divide(divisor, axis=axis)
コード例 #3
0
def cmget(color):
    ''' Return colormap from string (eg 'jet')'''
    try:
        cmap=getattr(cm, color)
    except AttributeError:
        raise badvalue_error(color, 'a custom LInearSegmentedColormap or a string matching \
        the default colormaps available to matplotlib (http://dept.astro.lsa.umich.edu/~msshin/science/code/matplotlib_cm/)') 
    return cmap
コード例 #4
0
ファイル: plot_utils.py プロジェクト: wapsyed/scikit-spectra
def _df_colormapper(df, cmap, axis=0, colorbymax=False, vmin=None, vmax=None):
    ''' Maps matplotlibcolors to a dataframe based on the mean value of each curve along that
    axis.  

    Parameters
    ----------
    colorbymax : bool (False)
        If true, curves are colored based on their maxima value (ie largest
        curve is max color regardless of where it appears in time). Otherwise,
        curves are colored chornologically.

    Notes
    -----
    Useful for df.plot() which doesn't take a normalized colormap natively. 
    cmap can be an instance of an RGB color map, or a string which such that 
    cm.string will produce one.
    '''

    if isinstance(cmap, basestring):
        cmap = cmget(cmap)

    if axis != 0 and axis != 1:
        raise badvalue_error(axis, 'integers 0 or 1')

    # Min and max values of color map must be min and max of dataframe
    if not vmin:
        try:
            vmin = min(df.min(axis=axis))
        except TypeError:  #If df only is one column...
            vmin = df.min(axis=axis)
    if not vmax:
        try:
            vmax = max(df.max(axis=axis))
        except TypeError:
            vmax = df.max(axis=axis)

    cNorm = mplcolors.Normalize(vmin=vmin, vmax=vmax)
    scalarmap = cm.ScalarMappable(norm=cNorm, cmap=cmap)

    if axis == 0:
        if colorbymax:
            colors = [scalarmap.to_rgba(df[x].max()) for x in df.columns]
        else:
            colors = [
                scalarmap.to_rgba(x)
                for x in np.linspace(vmin, vmax, len(df.columns))
            ]

    elif axis == 1:
        if colorbymax:
            colors = [scalarmap.to_rgba(df.ix[x].max()) for x in df.index]
        else:
            colors = [
                scalarmap.to_rgba(x)
                for x in np.linspace(vmin, vmax, len(df.index))
            ]

    return colors
コード例 #5
0
ファイル: plot_utils.py プロジェクト: wapsyed/scikit-spectra
def cmget(color):
    ''' Return colormap from string (eg 'jet')'''
    try:
        cmap = getattr(cm, color)
    except AttributeError:
        raise badvalue_error(
            color, 'a custom LInearSegmentedColormap or a string matching \
        the default colormaps available to matplotlib (http://dept.astro.lsa.umich.edu/~msshin/science/code/matplotlib_cm/)'
        )
    return cmap
コード例 #6
0
def _df_colormapper(df, cmap, axis=0, colorbymax=False, vmin=None, vmax=None):
    ''' Maps matplotlibcolors to a dataframe based on the mean value of each curve along that
    axis.  

    Parameters
    ----------
    colorbymax : bool (False)
        If true, curves are colored based on their maxima value (ie largest
        curve is max color regardless of where it appears in time). Otherwise,
        curves are colored chornologically.

    Notes
    -----
    Useful for df.plot() which doesn't take a normalized colormap natively. 
    cmap can be an instance of an RGB color map, or a string which such that 
    cm.string will produce one.
    '''

    if isinstance(cmap, basestring): 
        cmap=cmget(cmap)

    if axis != 0 and axis != 1:
        raise badvalue_error(axis, 'integers 0 or 1')

    # Min and max values of color map must be min and max of dataframe
    if not vmin:
        try:
            vmin = min(df.min(axis=axis)) 
        except TypeError: #If df only is one column...
            vmin = df.min(axis=axis)
    if not vmax:   
        try:
            vmax = max(df.max(axis=axis))
        except TypeError:
            vmax = df.max(axis=axis)

    cNorm = mplcolors.Normalize(vmin=vmin, vmax=vmax)
    scalarmap = cm.ScalarMappable(norm=cNorm, cmap=cmap)    

    if axis == 0:
        if colorbymax:
            colors=[scalarmap.to_rgba(df[x].max()) for x in df.columns]
        else:
            colors = [scalarmap.to_rgba(x) for x in 
                      np.linspace(vmin, vmax, len(df.columns))]

    elif axis == 1:
        if colorbymax:
            colors=[scalarmap.to_rgba(df.ix[x].max()) for x in df.index]                
        else:
            colors = [scalarmap.to_rgba(x) for x in 
                      np.linspace(vmin, vmax, len(df.index))]

    return colors
コード例 #7
0
def _annotate_mappable(df, cmap, axis=0, vmin=None, vmax=None):

    if isinstance(cmap, basestring): 
        cmap=cmget(cmap)

    if axis != 0 and axis != 1:
        raise badvalue_error(axis, 'integers 0 or 1')

    # Min and max values of color map must be min and max of dataframe
    if not vmin:
        vmin=min(df.min(axis=axis))
    if not vmax:        
        vmax=max(df.max(axis=axis))

    cNorm = mplcolors.Normalize(vmin=vmin, vmax=vmax)
    scalarmap = cm.ScalarMappable(norm=cNorm, cmap=cmap)    
#   http://stackoverflow.com/questions/6600579/colorbar-for-matplotlib-plot-surface-command
    scalarmap.set_array(np.arange(0,1)) #Thsi can be anything, arbitrary
    return scalarmap, vmin, vmax
コード例 #8
0
ファイル: plot_utils.py プロジェクト: wapsyed/scikit-spectra
def _annotate_mappable(df, cmap, axis=0, vmin=None, vmax=None):

    if isinstance(cmap, basestring):
        cmap = cmget(cmap)

    if axis != 0 and axis != 1:
        raise badvalue_error(axis, 'integers 0 or 1')

    # Min and max values of color map must be min and max of dataframe
    if not vmin:
        vmin = min(df.min(axis=axis))
    if not vmax:
        vmax = max(df.max(axis=axis))

    cNorm = mplcolors.Normalize(vmin=vmin, vmax=vmax)
    scalarmap = cm.ScalarMappable(norm=cNorm, cmap=cmap)
    #   http://stackoverflow.com/questions/6600579/colorbar-for-matplotlib-plot-surface-command
    scalarmap.set_array(np.arange(0, 1))  #Thsi can be anything, arbitrary
    return scalarmap, vmin, vmax
コード例 #9
0
def easy_legend(ax, fancy=True, position='top', **legendkwds):
    ''' Wrapper around ax.legend to make it easy to move a legend around the edges of the plot.  Made for sensible
    numbers of lines (1-15) and tries to choose smart placement to avoid conflict with lines, labels etc...

    BROKEN!!!

    This is a bust, since plotting legend is easy enough.  See guide, especially with the 'loc'      
    http://matplotlib.org/users/legend_guide.html

    If coming back to this, here are the issues to resolve:
       legend['loc'] must be enabled for the bounding box to work correctly/consistently.
       bbox coordinates are (left edge, bottom edge) of legend.  
         -controlling bottom edge is really dumb because want the top edge to clear the xlabel for example, and bottom
           edge depends on thickness of plot.  Putting the legend on top actually works nicely for this.

       If plotting outside left/right of plot, need to squeeze the plot in afterall, it will not accommadate my legend.
       Had this code, but deleted it.  Basically, need to squeeze left/right width of the axes.bounding width by 20%
       per column of legend.  
       (see second reply here http://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot)


    '''

    ir=lambda x: int(round(x))
    position=position.lower() 
    legendkwds['loc']=3 #MUST BE SET TO SOMETHING, 2 or 3 doesn't matter, or lower left is no longer start point    

    if position not in ['top', 'bottom', 'left', 'right']:
        raise badvalue_error(position, 'top, bottom, left, or right')

    ################################################################
    ### Choose skinny legend for top bottom, long for left/right ###
    ################################################################
    if 'ncol' not in legendkwds:
        if position=='top' or position=='bottom':

            if len(ax.lines) < 4:
                ncol=len(ax.lines)
            else:
                ncol=4           
        else:
            ncol=ir( len(ax.lines)/20.0) #For left right, nice if columns have large vertical extent (10 lines is good)
            if ncol==0:
                ncol=1
        legendkwds['ncol']=ncol

    ###################################################
    ### Choose legend position around plot elements ###
    ###################################################

    box=ax.get_position()   #Can do box.x0 and stuff when resetting ax.set_position()

    if 'bbox_to_anchor' not in legendkwds:  #Don't use has_key(), gone in 3.x

        if position=='top':     
            ''' Legend slightly inside the upper bound of plot'''
            if ax.get_title() == '':
                bbox_to_anchor=(0.2, 1.025)  #0.25 will only center plot if plot is 0.5 units long, then
            else:                             #other end at 0.75.  0.2 looks nice for 8 column uv-vis plot. 
                bbox_to_anchor=(0.2, 1.05)   #Also depends on size of monitor!! so either way, screwed


        elif position=='bottom':
            ''' Centered legend under the label'''

            if ax.get_xlabel()=='':
                bbox_to_anchor=(0.25, -0.025)
            else:
                bbox_to_anchor=(0.25, -0.05)


        elif position=='right':
            ''' Squeeze 20% width inward per column in legend to make room'''
            bbox_to_anchor=(1.05, 0.0) #WHY DOESNT 1,1 work

        elif position=='left':
            ''' Squeeze 20% width inward per column in legend to make room'''
            if ax.get_ylabel()=='':
                bbox_to_anchor=(-0.07, 1.0)   
            else:
                bbox_to_anchor=(-0.12, 1.0)


        legendkwds['bbox_to_anchor']=bbox_to_anchor

    if fancy and 'fancybox' not in legendkwds and 'shadow' not in legendkwds:
        legendkwds['fancybox']=True
        legendkwds['shadow']=True

    if 'borderaxespad' not in legendkwds:
        legendkwds['borderaxespad']=0.0  #Havne't played with this

        ### WHY IS MODE BROKEN (comes up garbled on plot)  
#    if 'mode' not in legendkwds:
    #       legendkwds['mode']='expand'


    ax.legend(**legendkwds)
    return ax
コード例 #10
0
ファイル: plot_utils.py プロジェクト: wapsyed/scikit-spectra
def easy_legend(ax, fancy=True, position='top', **legendkwds):
    ''' Wrapper around ax.legend to make it easy to move a legend around the edges of the plot.  Made for sensible
    numbers of lines (1-15) and tries to choose smart placement to avoid conflict with lines, labels etc...

    BROKEN!!!

    This is a bust, since plotting legend is easy enough.  See guide, especially with the 'loc'      
    http://matplotlib.org/users/legend_guide.html

    If coming back to this, here are the issues to resolve:
       legend['loc'] must be enabled for the bounding box to work correctly/consistently.
       bbox coordinates are (left edge, bottom edge) of legend.  
         -controlling bottom edge is really dumb because want the top edge to clear the xlabel for example, and bottom
           edge depends on thickness of plot.  Putting the legend on top actually works nicely for this.

       If plotting outside left/right of plot, need to squeeze the plot in afterall, it will not accommadate my legend.
       Had this code, but deleted it.  Basically, need to squeeze left/right width of the axes.bounding width by 20%
       per column of legend.  
       (see second reply here http://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot)


    '''

    ir = lambda x: int(round(x))
    position = position.lower()
    legendkwds[
        'loc'] = 3  #MUST BE SET TO SOMETHING, 2 or 3 doesn't matter, or lower left is no longer start point

    if position not in ['top', 'bottom', 'left', 'right']:
        raise badvalue_error(position, 'top, bottom, left, or right')

    ################################################################
    ### Choose skinny legend for top bottom, long for left/right ###
    ################################################################
    if 'ncol' not in legendkwds:
        if position == 'top' or position == 'bottom':

            if len(ax.lines) < 4:
                ncol = len(ax.lines)
            else:
                ncol = 4
        else:
            ncol = ir(
                len(ax.lines) / 20.0
            )  #For left right, nice if columns have large vertical extent (10 lines is good)
            if ncol == 0:
                ncol = 1
        legendkwds['ncol'] = ncol

    ###################################################
    ### Choose legend position around plot elements ###
    ###################################################

    box = ax.get_position(
    )  #Can do box.x0 and stuff when resetting ax.set_position()

    if 'bbox_to_anchor' not in legendkwds:  #Don't use has_key(), gone in 3.x

        if position == 'top':
            ''' Legend slightly inside the upper bound of plot'''
            if ax.get_title() == '':
                bbox_to_anchor = (
                    0.2, 1.025
                )  #0.25 will only center plot if plot is 0.5 units long, then
            else:  #other end at 0.75.  0.2 looks nice for 8 column uv-vis plot.
                bbox_to_anchor = (
                    0.2, 1.05
                )  #Also depends on size of monitor!! so either way, screwed

        elif position == 'bottom':
            ''' Centered legend under the label'''

            if ax.get_xlabel() == '':
                bbox_to_anchor = (0.25, -0.025)
            else:
                bbox_to_anchor = (0.25, -0.05)

        elif position == 'right':
            ''' Squeeze 20% width inward per column in legend to make room'''
            bbox_to_anchor = (1.05, 0.0)  #WHY DOESNT 1,1 work

        elif position == 'left':
            ''' Squeeze 20% width inward per column in legend to make room'''
            if ax.get_ylabel() == '':
                bbox_to_anchor = (-0.07, 1.0)
            else:
                bbox_to_anchor = (-0.12, 1.0)

        legendkwds['bbox_to_anchor'] = bbox_to_anchor

    if fancy and 'fancybox' not in legendkwds and 'shadow' not in legendkwds:
        legendkwds['fancybox'] = True
        legendkwds['shadow'] = True

    if 'borderaxespad' not in legendkwds:
        legendkwds['borderaxespad'] = 0.0  #Havne't played with this

        ### WHY IS MODE BROKEN (comes up garbled on plot)
#    if 'mode' not in legendkwds:
#       legendkwds['mode']='expand'

    ax.legend(**legendkwds)
    return ax