Ejemplo n.º 1
0
def _match_error_to_data_set(x, ex):
    """
    Inflates ex to match the dimensionality of x, "intelligently". 
    x is assumed to be a 2D array.
    """
    # Simplest case, ex is None or a number
    if not _fun.is_iterable(ex):

        # Just make a matched list of Nones
        if ex is None: ex = [ex] * len(x)

        # Make arrays of numbers
        if _fun.is_a_number(ex):
            value = ex  # temporary storage
            ex = []
            for n in range(len(x)):
                ex.append([value] * len(x[n]))

    # Otherwise, ex is iterable

    # Default behavior: If the elements are all numbers and the length matches
    # that of the first x-array, assume this is meant to match all the x
    # data sets
    if _fun.elements_are_numbers(ex) and len(ex) == len(x[0]):
        ex = [ex] * len(x)

    # The user may specify a list of some iterable and some not. Assume
    # in this case that at least the lists are the same length
    for n in range(len(x)):
        # do nothing to the None's
        # Inflate single numbers to match
        if _fun.is_a_number(ex[n]): ex[n] = [ex[n]] * len(x[n])

    return ex
Ejemplo n.º 2
0
def _match_error_to_data_set(x, ex):
    """
    Inflates ex to match the dimensionality of x, "intelligently". 
    x is assumed to be a 2D array.
    """
    # Simplest case, ex is None or a number
    if not _fun.is_iterable(ex):
        
        # Just make a matched list of Nones
        if ex is None: ex = [ex]*len(x)
        
        # Make arrays of numbers
        if _fun.is_a_number(ex): 
            value = ex # temporary storage
            ex    = []
            for n in range(len(x)): 
                ex.append([value]*len(x[n]))
    
    # At this point, ex is iterable
    
    # Default behavior: If the elements are all numbers and the length matches
    # that of the first x-array, assume this is meant to match all the x
    # data sets
    if _fun.elements_are_numbers(ex) and len(ex) == len(x[0]): ex = [ex]*len(x)

    # Make sure it's a list (for appending)
    if not type(ex) == list: ex = list(ex)

    # The user may specify a list of some iterable and some not. 
    # The list length may not match
    while len(ex) < len(x): ex.append(ex[-1])
    
    # Now they are the same length
    for n in range(len(x)):
        # do nothing to the None's
        # Inflate single numbers to match
        if _fun.is_a_number(ex[n]): ex[n] = [ex[n]]*len(x[n])
        
    return ex    
Ejemplo n.º 3
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=1, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    xdata, ydata        Arrays (or arrays of arrays) of data to plot
    eydata, exdata      Arrays of x and y errorbar values
    label               string or array of strings for the line labels
    xlabel=''           label for the x-axis
    ylabel=''           label for the y-axis
    title=''            title for the axes; set to None to have nothing.
    shell_history=1     how many commands from the pyshell history to include
                        with the title
    xshift=0, yshift=0  progressive shifts on the data, to make waterfall plots
    xshift_every=1      perform the progressive shift every 1 or n'th line.
    yshift_every=1      perform the progressive shift every 1 or n'th line.
    style               style cycle object.
    clear=True          if no axes are specified, clear the figure, otherwise
                        clear just the axes.
    axes=None           which axes to use, or "gca" for the current axes
    xscale,yscale       'linear' by default. Set either to 'log' for log axes
    grid=False          Should we draw a grid on the axes?
    legend='best'       where to place the legend (see pylab.legend())
                        Set this to None to ignore the legend.
    legend_max=20       number of legend entries before it's truncated with '...'
    autoformat=True     Should we format the figure for printing?
    False               Should the format be tall?
    draw=True           whether or not to draw the plot after plotting


    **kwargs are sent to pylab.errorbar()
    """

    _pylab.ioff()

    # make sure everything is at least iterable.
    if not _fun.is_iterable(xdata): xdata = [xdata]
    if not _fun.is_iterable(exdata): exdata = [exdata]
    if not _fun.is_iterable(ydata): ydata = [ydata]
    if not _fun.is_iterable(eydata): eydata = [eydata]

    # make sure at least xdata and ydata are 2-D
    if _fun.is_a_number(xdata[0]): xdata = [xdata]
    if _fun.is_a_number(ydata[0]): ydata = [ydata]

    # make sure the number of data sets agrees
    N = max(len(xdata), len(ydata))
    for n in range(N - len(xdata)):
        xdata.append(xdata[0])
    for n in range(N - len(ydata)):
        ydata.append(ydata[0])
    for n in range(N - len(exdata)):
        exdata.append(exdata[0])
    for n in range(N - len(eydata)):
        eydata.append(eydata[0])

    # loop over each x and y data set, making sure None's are all converted
    # to counting arrays
    for n in range(N):

        # clean up the [None]'s
        if _fun.is_iterable(xdata[n]) and xdata[n][0] == None: xdata[n] = None
        if _fun.is_iterable(ydata[n]) and ydata[n][0] == None: ydata[n] = None

        if xdata[n] == None and ydata[n] == None:
            print "ERROR: " + str(n) + "'th data set is (None, None)."
            return

        if xdata[n] == None: xdata[n] = _n.arange(len(ydata[n]))
        if ydata[n] == None: ydata[n] = _n.arange(len(xdata[n]))

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label] * N
    while len(label) < len(ydata):
        label.append(label[0])

    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max - 2] = '...'
        for n in range(legend_max - 1, len(label) - 1):
            label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear()  # axes cleared later

    # setup axes
    if axes == "gca" or axes == None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0, len(xdata)):
        # get the label
        if label: l = str(label[n])
        else: l = str(n)

        # calculate the x an y progressive shifts
        dx = xshift * (n / xshift_every)
        dy = yshift * (n / yshift_every)

        # if we're supposed to coarsen the data, do so.
        x = _fun.coarsen_array(xdata[n], coarsen)
        y = _fun.coarsen_array(ydata[n], coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style == None: kwargs.update(style.next())
        axes.errorbar(x + dx, y + dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Ejemplo n.º 4
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=1, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    xdata, ydata        Arrays (or arrays of arrays) of data to plot
    eydata, exdata      Arrays of x and y errorbar values
    label               string or array of strings for the line labels
    xlabel=''           label for the x-axis
    ylabel=''           label for the y-axis
    title=''            title for the axes; set to None to have nothing.
    shell_history=1     how many commands from the pyshell history to include
                        with the title
    xshift=0, yshift=0  progressive shifts on the data, to make waterfall plots
    xshift_every=1      perform the progressive shift every 1 or n'th line.
    yshift_every=1      perform the progressive shift every 1 or n'th line.
    style               style cycle object.
    clear=True          if no axes are specified, clear the figure, otherwise
                        clear just the axes.
    axes=None           which axes to use, or "gca" for the current axes
    xscale,yscale       'linear' by default. Set either to 'log' for log axes
    grid=False          Should we draw a grid on the axes?
    legend='best'       where to place the legend (see pylab.legend())
                        Set this to None to ignore the legend.
    legend_max=20       number of legend entries before it's truncated with '...'
    autoformat=True     Should we format the figure for printing?
    False               Should the format be tall?
    draw=True           whether or not to draw the plot after plotting


    **kwargs are sent to pylab.errorbar()
    """

    _pylab.ioff()

    # make sure everything is at least iterable.
    if not _fun.is_iterable(xdata):  xdata  = [xdata]
    if not _fun.is_iterable(exdata): exdata = [exdata]
    if not _fun.is_iterable(ydata):  ydata  = [ydata]
    if not _fun.is_iterable(eydata): eydata = [eydata]

    # make sure at least xdata and ydata are 2-D
    if _fun.is_a_number(xdata[0]): xdata = [xdata]
    if _fun.is_a_number(ydata[0]): ydata = [ydata]

    # make sure the number of data sets agrees
    N = max(len(xdata),len(ydata))
    for n in range(N-len( xdata)):  xdata.append( xdata[0])
    for n in range(N-len( ydata)):  ydata.append( ydata[0])
    for n in range(N-len(exdata)): exdata.append(exdata[0])
    for n in range(N-len(eydata)): eydata.append(eydata[0])

    # loop over each x and y data set, making sure None's are all converted
    # to counting arrays
    for n in range(N):

        # clean up the [None]'s
        if _fun.is_iterable(xdata[n]) and xdata[n][0] is None: xdata[n] = None
        if _fun.is_iterable(ydata[n]) and ydata[n][0] is None: ydata[n] = None

        if xdata[n] is None and ydata[n] is None:
            print "ERROR: "+str(n)+"'th data set is (None, None)."
            return

        if xdata[n] is None: xdata[n] = _n.arange(len(ydata[n]))
        if ydata[n] is None: ydata[n] = _n.arange(len(xdata[n]))

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label]*N
    while len(label) < len(ydata):  label.append(label[0])

    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max-2] = '...'
        for n in range(legend_max-1,len(label)-1): label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear() # axes cleared later

    # setup axes
    if axes=="gca" or axes is None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0,len(xdata)):
        # get the label
        if label: l = str(label[n])
        else:     l = str(n)

        # calculate the x an y progressive shifts
        dx = xshift*(n/xshift_every)
        dy = yshift*(n/yshift_every)
        
        # if we're supposed to coarsen the data, do so.
        x  = _fun.coarsen_array(xdata[n],  coarsen)
        y  = _fun.coarsen_array(ydata[n],  coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style is None: kwargs.update(style.next())
        axes.errorbar(x+dx, y+dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Ejemplo n.º 5
0
def _match_data_sets(x,y):
    """
    Makes sure everything is the same shape. "Intelligently".
    """
    
    # If x is a value, use this for the step size.
    dx = 1.0
    if _fun.is_a_number(x): 
        dx = x
        x  = None
        
    # Handle the None for x or y
    if x is None or len(x) == 0: 
        # If x is None, y can be either [1,2] or [[1,2],[1,2]] or []
        if len(y) == 0: x = []
    
        elif _fun.is_iterable(y[0]):
            # make an array of arrays to match
            x = []
            for n in range(len(y)):
                x.append(list(dx*_n.array(range(len(y[n])))))
        else: x = list(range(len(y)))
    
    # If y is a value, use this for the step size.
    dy = 1.0
    if _fun.is_a_number(y): 
        dy = y
        y  = None

    if y is None or len(y) == 0: 
        # If y is none, x can be either [1,2] or [[1,2],[1,2]] or []
        if len(x) == 0: y = []
        
        elif _fun.is_iterable(x[0]):
            # make an array of arrays to match
            y = []
            for n in range(len(x)):
                y.append(list(dy*_n.array(range(len(x[n])))))
        else: y = list(range(len(x)))
    
    # At this point they should be matched, but may still be 1D
    # Default behavior: if all elements are numbers in both, assume they match
    if _fun.elements_are_numbers(x): x=[x]
    if _fun.elements_are_numbers(y): y=[y]

    # Make sure they are both lists (so append works!)
    if not type(x) == list: x = list(x)
    if not type(y) == list: y = list(y)

    # Make sure they're the same length
    while len(x) > len(y): y.append(y[-1])
    while len(y) > len(x): x.append(x[-1])

    # Second default behavior: shared array [1,2,3], [[1,2,1],[1,2,1]] or vis versa
    if _fun.elements_are_numbers(x) and not _fun.elements_are_numbers(y): x = [x]*len(y)
    if _fun.elements_are_numbers(y) and not _fun.elements_are_numbers(x): y = [y]*len(x)

    # Clean up any remaining Nones
    for n in range(len(x)):
        if x[n] is None: x[n] = list(range(len(y[n])))
        if y[n] is None: y[n] = list(range(len(x[n])))
    
    return x, y
Ejemplo n.º 6
0
def databoxes(ds,
              xscript=0,
              yscript=1,
              eyscript=None,
              exscript=None,
              g=None,
              plotter=xy_data,
              transpose=False,
              **kwargs):
    """
    Plots the listed databox objects with the specified scripts.

    ds        list of databoxes
    xscript   script for x data
    yscript   script for y data
    eyscript  script for y error
    exscript  script for x error
    plotter   function used to do the plotting
    transpose applies databox.transpose() prior to plotting
    g         optional dictionary of globals for the supplied scripts

    **kwargs are sent to plotter()
    """
    if not _fun.is_iterable(ds): ds = [ds]

    if 'xlabel' not in kwargs: kwargs['xlabel'] = str(xscript)
    if 'ylabel' not in kwargs: kwargs['ylabel'] = str(yscript)

    # First make sure everything is a list of scripts (or None's)
    if not _fun.is_iterable(xscript): xscript = [xscript]
    if not _fun.is_iterable(yscript): yscript = [yscript]
    if not _fun.is_iterable(exscript): exscript = [exscript]
    if not _fun.is_iterable(eyscript): eyscript = [eyscript]

    # make sure exscript matches shape with xscript (and the same for y)
    if len(exscript) < len(xscript):
        for n in range(len(xscript) - 1):
            exscript.append(exscript[0])
    if len(eyscript) < len(yscript):
        for n in range(len(yscript) - 1):
            eyscript.append(eyscript[0])

    # Make xscript and exscript match in shape with yscript and eyscript
    if len(xscript) < len(yscript):
        for n in range(len(yscript) - 1):
            xscript.append(xscript[0])
            exscript.append(exscript[0])

    # check for the reverse possibility
    if len(yscript) < len(xscript):
        for n in range(len(xscript) - 1):
            yscript.append(yscript[0])
            eyscript.append(eyscript[0])

    # now check for None's (counting scripts)
    for n in range(len(xscript)):
        if xscript[n] is None and yscript[n] is None:
            print("Two None scripts? But... why?")
            return
        if xscript[n] is None:
            if type(yscript[n]) == str:
                xscript[n] = 'range(len(' + yscript[n] + '))'
            else:
                xscript[n] = 'range(len(c(' + str(yscript[n]) + ')))'
        if yscript[n] is None:
            if type(xscript[n]) == str:
                yscript[n] = 'range(len(' + xscript[n] + '))'
            else:
                yscript[n] = 'range(len(c(' + str(xscript[n]) + ')))'

    xdatas = []
    ydatas = []
    exdatas = []
    eydatas = []
    labels = []

    # Loop over all the data boxes
    for i in range(len(ds)):

        # Reset the default globals
        all_globals = dict(n=i, m=len(ds) - 1 - i)

        # Update them with the user-specified globals
        if not g == None: all_globals.update(g)

        # For ease of coding
        d = ds[i]

        # Take the transpose if necessary
        if transpose: d = d.transpose()

        # Generate the x-data; returns a list of outputs, one for each xscript
        xdata = d(xscript, all_globals)

        # Loop over each xdata, appending to the master list, and generating a label
        for n in range(len(xdata)):
            xdatas.append(xdata[n])

            # Normal data set is a 1d array
            labels.append(_os.path.split(d.path)[-1])

        # Special case: single-point per file
        if _fun.is_a_number(xdata[0]) == 1 and len(ds) > 1:
            labels = [
                _os.path.split(ds[0].path)[-1] + ' - ' +
                _os.path.split(ds[-1].path)[-1]
            ]

        # Append the other data sets to their master lists
        for y in d(yscript, all_globals):
            ydatas.append(y)
        for x in d(exscript, all_globals):
            exdatas.append(x)
        for y in d(eyscript, all_globals):
            eydatas.append(y)

    if "label" in kwargs: labels = kwargs.pop("label")

    plotter(xdatas, ydatas, eydatas, exdatas, label=labels, **kwargs)