Ejemplo n.º 1
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.º 2
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.º 3
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=0, 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, autoformat_window=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    Parameters
    ----------
    xdata, ydata        
        Arrays (or arrays of arrays) of data to plot
    eydata=None, exdata=None     
        Arrays of x and y errorbar values
    label=None         
        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=0     
        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=None            
        style cycle object.
    clear=True          
        If no axes are specified (see below), clear the figure, otherwise clear just the axes.
    axes=None           
        Which matplotlib axes to use, or "gca" for the current axes
    xscale='linear', yscale='linear'      
        'linear' or 'log' x and y axis scales.
    grid=False          
        Should we draw a grid on the axes?
    legend='best'       
        Where to place the legend (see pylab.legend() for options)
        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?
    autoformat_window=True
        Should we resize and reposition the window when autoformatting?
    tall=False               
        Should the format be tall?
    draw=True           
        Whether or not to draw the plot after plotting.

    See matplotlib's errorbar() function for additional optional keyword arguments.
    """
    _pylab.ioff()

    # Make sure the dimensionality of the data sets matches
    xdata, ydata = _match_data_sets(xdata, ydata)
    exdata = _match_error_to_data_set(xdata, exdata)
    eydata = _match_error_to_data_set(ydata, eydata)

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label] * len(xdata)
    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
        l = str(n) + ": " + str(label[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(next(style))
        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, modify_geometry=autoformat_window)
        _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=0, 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, autoformat_window=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    Parameters
    ----------
    xdata, ydata        
        Arrays (or arrays of arrays) of data to plot
    eydata=None, exdata=None     
        Arrays of x and y errorbar values
    label=None         
        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=0     
        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=None            
        style cycle object.
    clear=True          
        If no axes are specified (see below), clear the figure, otherwise clear just the axes.
    axes=None           
        Which matplotlib axes to use, or "gca" for the current axes
    xscale='linear', yscale='linear'      
        'linear' or 'log' x and y axis scales.
    grid=False          
        Should we draw a grid on the axes?
    legend='best'       
        Where to place the legend (see pylab.legend() for options)
        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?
    autoformat_window=True
        Should we resize and reposition the window when autoformatting?
    tall=False               
        Should the format be tall?
    draw=True           
        Whether or not to draw the plot after plotting.

    See matplotlib's errorbar() function for additional optional keyword arguments.
    """
    _pylab.ioff()
    
    # Make sure the dimensionality of the data sets matches
    xdata, ydata = _match_data_sets(xdata, ydata)
    exdata = _match_error_to_data_set(xdata, exdata)
    eydata = _match_error_to_data_set(ydata, eydata)
    
    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label]*len(xdata)
    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[n]=='_nolegend_':
            l = '_nolegend_'
        else:
            l = str(n)+": "+str(label[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(next(style))
        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, modify_geometry=autoformat_window)
        _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 magphase_data(xdata,
                  ydata,
                  eydata=None,
                  exdata=None,
                  xscale='linear',
                  mscale='linear',
                  pscale='linear',
                  mlabel='Magnitude',
                  plabel='Phase',
                  phase='degrees',
                  figure='gcf',
                  clear=1,
                  **kwargs):
    """
    Plots the magnitude and phase of complex ydata.

    xdata               real-valued x-axis data
    ydata               complex-valued y-axis data
    eydata=None         complex-valued y-error
    exdata=None         real-valued x-error
    xscale='linear'     'log' or 'linear'
    mscale='linear'     'log' or 'linear' (only applies to the magnitude graph)
    pscale='linear'     'log' or 'linear' (only applies to the phase graph)
    mlabel='Magnitude'  y-axis label for magnitude plot
    plabel='Phase'      y-axis label for phase plot
    phase='degrees'     'degrees' or 'radians'
    figure='gcf'        figure instance
    clear=1             clear the figure?

    kwargs are sent to plot.xy.data()
    """

    if figure == 'gcf': f = _pylab.gcf()
    if clear: f.clear()

    axes1 = _pylab.subplot(211)
    axes2 = _pylab.subplot(212, sharex=axes1)

    m = _n.abs(ydata)
    p = _n.angle(ydata)
    if phase == 'degrees':
        for n in range(len(ydata)):
            p[n] = p[n] * 180.0 / _n.pi

    # do the elliptical error transformation
    em = []
    ep = []
    er = []
    ei = []
    if eydata == None:
        em = None
        ep = None
        er = None
        ei = None
    else:

        if eydata[n] == None:
            em.append(None)
            ep.append(None)
        else:
            er = _n.real(eydata[n])
            ei = _n.imag(eydata[n])
            em.append(0.5 * ((er + ei) + (er - ei) * _n.cos(p[n])))
            ep.append(0.5 * ((er + ei) - (er - ei) * _n.cos(p[n])) / m[n])

        # convert to degrees
        if phase == 'degrees':
            if not ep[n] == None: ep[n] = ep[n] * 180.0 / _n.pi

    if phase == 'degrees': plabel = plabel + " (degrees)"
    else: plabel = plabel + " (radians)"
    if kwargs.has_key('xlabel'): xlabel = kwargs.pop('xlabel')
    else: xlabel = ''
    if kwargs.has_key('ylabel'): kwargs.pop('ylabel')

    if not kwargs.has_key('draw'): kwargs['draw'] = False
    if not kwargs.has_key('tall'): kwargs['tall'] = False
    if not kwargs.has_key('autoformat'): kwargs['autoformat'] = True

    autoformat = kwargs['autoformat']
    kwargs['autoformat'] = False
    kwargs['xlabel'] = ''
    xy_data(xdata,
            m,
            em,
            exdata,
            ylabel=mlabel,
            axes=axes1,
            clear=0,
            xscale=xscale,
            yscale=mscale,
            **kwargs)

    kwargs['autoformat'] = autoformat
    kwargs['xlabel'] = xlabel
    xy_data(xdata,
            p,
            ep,
            exdata,
            ylabel=plabel,
            axes=axes2,
            clear=0,
            xscale=xscale,
            yscale=pscale,
            **kwargs)

    axes2.set_title('')
    _pt.auto_zoom(axes=axes1)
    _pylab.draw()
Ejemplo n.º 6
0
def magphase_data(xdata, ydata, eydata=None, exdata=None, xscale='linear', mscale='linear', pscale='linear', mlabel='Magnitude', plabel='Phase', phase='degrees', figure='gcf', clear=1,  **kwargs):
    """
    Plots the magnitude and phase of complex ydata.

    xdata               real-valued x-axis data
    ydata               complex-valued y-axis data
    eydata=None         complex-valued y-error
    exdata=None         real-valued x-error
    xscale='linear'     'log' or 'linear'
    mscale='linear'     'log' or 'linear' (only applies to the magnitude graph)
    pscale='linear'     'log' or 'linear' (only applies to the phase graph)
    mlabel='Magnitude'  y-axis label for magnitude plot
    plabel='Phase'      y-axis label for phase plot
    phase='degrees'     'degrees' or 'radians'
    figure='gcf'        figure instance
    clear=1             clear the figure?

    kwargs are sent to plot.xy.data()
    """

    if figure == 'gcf': f = _pylab.gcf()
    if clear: f.clear()

    axes1 = _pylab.subplot(211)
    axes2 = _pylab.subplot(212,sharex=axes1)

    m = _n.abs(ydata)
    p = _n.angle(ydata)
    if phase=='degrees': 
        for n in range(len(ydata)):
            p[n] = p[n]*180.0/_n.pi

    # do the elliptical error transformation
    em = []
    ep = []
    er = []
    ei = []    
    if eydata==None:
        em = None
        ep = None
        er = None
        ei = None
    else:
           
            if eydata[n] == None: 
                em.append(None)
                ep.append(None)
            else:
                er = _n.real(eydata[n])
                ei = _n.imag(eydata[n])
                em.append(0.5*((er+ei) + (er-ei)*_n.cos(p[n]))   )
                ep.append(0.5*((er+ei) - (er-ei)*_n.cos(p[n]))/m[n] )
            
            # convert to degrees
            if phase=='degrees':
                if not ep[n]==None: ep[n] = ep[n]*180.0/_n.pi       
            

    if phase=='degrees':         plabel = plabel + " (degrees)"
    else:                        plabel = plabel + " (radians)"
    if kwargs.has_key('xlabel'): xlabel=kwargs.pop('xlabel')
    else:                        xlabel=''
    if kwargs.has_key('ylabel'): kwargs.pop('ylabel')
    
    if not kwargs.has_key('draw'): kwargs['draw'] = False
    if not kwargs.has_key('tall'): kwargs['tall'] = False
    if not kwargs.has_key('autoformat'):   kwargs['autoformat'] = True

    autoformat = kwargs['autoformat']
    kwargs['autoformat'] = False    
    kwargs['xlabel'] = ''
    xy_data(xdata, m, em, exdata, ylabel=mlabel, axes=axes1, clear=0, xscale=xscale, yscale=mscale, **kwargs)

    kwargs['autoformat'] = autoformat
    kwargs['xlabel'] = xlabel
    xy_data(xdata, p, ep, exdata, ylabel=plabel, axes=axes2, clear=0, xscale=xscale, yscale=pscale, **kwargs)

    axes2.set_title('')
    _pt.auto_zoom(axes=axes1)
    _pylab.draw()