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])
            if len(xdata)>1: labels.append(str(n)+": "+_os.path.split(d.path)[-1])
            else:            labels.append(_os.path.split(d.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)