def curvelinear_test1(fig):
    """
    grid for custom transform.
    """

    def tr(x, y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y - x

    def inv_tr(x, y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y + x

    grid_helper = GridHelperCurveLinear((tr, inv_tr))

    ax1 = Subplot(fig, 1, 2, 1, grid_helper=grid_helper)
    # ax1 will have a ticks and gridlines defined by the given
    # transform (+ transData of the Axes). Note that the transform of
    # the Axes itself (i.e., transData) is not affected by the given
    # transform.

    fig.add_subplot(ax1)

    xx, yy = tr([3, 6], [5.0, 10.])
    ax1.plot(xx, yy, linewidth=2.0)

    ax1.set_aspect(1.)
    ax1.set_xlim(0, 10.)
    ax1.set_ylim(0, 10.)

    ax1.axis["t"] = ax1.new_floating_axis(0, 3.)
    ax1.axis["t2"] = ax1.new_floating_axis(1, 7.)
    ax1.grid(True, zorder=0)
Exemplo n.º 2
0
def curvelinear_test1(fig):
    """
    grid for custom transform.
    """
    def tr(x, y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y - x

    def inv_tr(x, y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y + x

    grid_helper = GridHelperCurveLinear((tr, inv_tr))

    ax1 = Subplot(fig, 1, 2, 1, grid_helper=grid_helper)
    # ax1 will have a ticks and gridlines defined by the given
    # transform (+ transData of the Axes). Note that the transform of
    # the Axes itself (i.e., transData) is not affected by the given
    # transform.

    fig.add_subplot(ax1)

    xx, yy = tr([3, 6], [5.0, 10.])
    ax1.plot(xx, yy, linewidth=2.0)

    ax1.set_aspect(1.)
    ax1.set_xlim(0, 10.)
    ax1.set_ylim(0, 10.)

    ax1.axis["t"] = ax1.new_floating_axis(0, 3.)
    ax1.axis["t2"] = ax1.new_floating_axis(1, 7.)
    ax1.grid(True, zorder=0)
Exemplo n.º 3
0
def curvelinear_test1(fig):
    """
    grid for custom transform.
    """
    def tr(x, y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y-x
    def inv_tr(x,y):
        x, y = np.asarray(x), np.asarray(y)
        return x, y+x
    grid_helper = GridHelperCurveLinear((tr, inv_tr))
    ax1 = Subplot(fig, 1, 2, 1, grid_helper=grid_helper)
    fig.add_subplot(ax1)
    xx, yy = tr([3, 6], [5.0, 10.])
    ax1.plot(xx, yy)
    ax1.set_aspect(1.)
    ax1.set_xlim(0, 10.)
    ax1.set_ylim(0, 10.)
    ax1.axis["t"]=ax1.new_floating_axis(0, 3.)
    ax1.axis["t2"]=ax1.new_floating_axis(1, 7.)
    ax1.grid(True)
Exemplo n.º 4
0
def plotXcorr(qdata,save=False,fname='hmmSortingUnits.pdf'):

    unitTimePoints = qdata['unitTimePoints']
    samplingRate = qdata.get('samplingRate',30000.0)
    units = unitTimePoints.keys()
    nunits = len(units)
    xsize = max(10,nunits*2)
    fig = plt.figure(figsize=(xsize,(6.0/8)*xsize) )
    fig.subplots_adjust(left=0.03,right=0.97,bottom=0.03,top=0.97)
    i = 1
    if not 'XCorr' in qdata:
        if isinstance(qdata,dict):
            qdata['XCorr'] = {}
        else:
            qdata.create_group('XCorr')
    for k1 in xrange(len(units)-1) :
        if not units[k1] in qdata['XCorr']:
            qdata['XCorr'].create_group(units[k1])
        for k2 in xrange(k1+1,len(units)):
            if not units[k2] in qdata['XCorr'][units[k1]]:
                T1 = unitTimePoints[units[k1]][:]/(samplingRate/1000)
                T2 = unitTimePoints[units[k2]][:]/(samplingRate/1000)
                #compute differences less than 50 ms
                C = pdist_threshold2(T1,T2,50)
                qdata['XCorr'][units[k1]].create_dataset(units[k2],data=C,compression=2,fletcher32=True,shuffle=True)
            else:
                C = qdata['XCorr'][units[k1]][units[k2]][:]
            n,b = np.histogram(C,np.arange(-50,50),normed=True)
            ax = Subplot(fig,nunits-1,nunits,k1*nunits+k2) 
            fig.add_axes(ax)
            formatAxis(ax)
            ax.plot(b[:-1],n,'k')
            ax.fill_betweenx([0,n.max()],-1.0,1.0,color='r',alpha=0.3)
            if not (k1 == len(units)-2 and k2 == len(units)-1):
                ax.set_xticklabels('')
                ax.set_yticklabels('')
    if save:
        fig.savefig(os.path.expanduser('~/Documents/research/figures/SpikeSorting/hmm/%s' %( fname,)),bbox='tight') 
    else:
        plt.draw()
Exemplo n.º 5
0
def curvelinear_test1(fig):
    """
    Grid for custom transform.
    """
    def tr(x, y):
        x, y = numpy.asarray(x), numpy.asarray(y)
        return x, y - (2 * x)  # return x + (5 * y), (7 * y) + (3 * x)

    def inv_tr(x, y):
        x, y = numpy.asarray(x), numpy.asarray(y)
        return x, y + (2 * x)

    grid_helper = GridHelperCurveLinear((tr, inv_tr))

    ax1 = Subplot(fig, 1, 1, 1, grid_helper=grid_helper)
    # ax1 will have a ticks and gridlines defined by the given
    # transform (+ transData of the Axes). Note that the transform of
    # the Axes itself (i.e., transData) is not affected by the given
    # transform.

    fig.add_subplot(ax1)

    xx, yy = tr([0, 1], [0, 2])
    ax1.plot(xx, yy, linewidth=2.0)

    ax1.set_aspect(1)
    ax1.set_xlim(-3, 3)
    ax1.set_ylim(-3, 3)

    ax1.axis["t"] = ax1.new_floating_axis(
        0, 0
    )  # first argument appears to be slope, second argument appears to be starting point on vertical
    ax1.axis["t2"] = ax1.new_floating_axis(1, 0)
    ax1.axhline(y=0, color='r')
    ax1.axvline(x=0, color='r')
    ax1.grid(True, zorder=0)
Exemplo n.º 6
0
]
mesh_T, mesh_p = np.meshgrid(
    np.arange(-60.0,
              T_levels.max() - C_to_K + 0.1, 0.1), p_all)
theta_ep_mesh = Bolton.theta_ep_field(mesh_T, mesh_p)

# Plotting Code!

skew_grid_helper = GridHelperCurveLinear((from_thermo, to_thermo))

fig = plt.figure()
ax = Subplot(fig, 1, 1, 1, grid_helper=skew_grid_helper)
fig.add_subplot(ax)

for yi in y_p_levels:
    ax.plot((x_min, x_max), (yi, yi), color=(1.0, 0.8, 0.8))

for x_T in x_T_levels:
    ax.plot(x_T, y_all_p, color=(1.0, 0.5, 0.5))

for x_theta in x_thetas:
    ax.plot(x_theta, y_all_p, color=(1.0, 0.7, 0.7))

for x_mixing_ratio in x_mixing_ratios:
    good = p_all >= 600  # restrict mixing ratio lines to below 600 mb
    ax.plot(x_mixing_ratio[good], y_all_p[good], color=(0.8, 0.8, 0.6))

n_moist = len(theta_ep_mesh)
moist_colors = ((0.6, 0.9, 0.7), ) * n_moist
ax.contour(x_from_Tp(mesh_T + C_to_K, mesh_p),
           y_from_p(mesh_p),
Exemplo n.º 7
0
    from mpl_toolkits.axisartist import Subplot
    from mpl_toolkits.axisartist.grid_helper_curvelinear import \
        GridHelperCurveLinear

    def tr(x, y):  # source (data) to target (rectilinear plot) coordinates
        x, y = numpy.asarray(x), numpy.asarray(y)
        return x + 0.2 * y, y - x

    def inv_tr(x, y):
        x, y = numpy.asarray(x), numpy.asarray(y)
        return x - 0.2 * y, y + x

    grid_helper = GridHelperCurveLinear((tr, inv_tr))

    ax6 = Subplot(fig, nrow, ncol, 6, grid_helper=grid_helper)
    fig.add_subplot(ax6)
    ax6.set_title('non-ortho axes')

    xx, yy = tr([3, 6], [5.0, 10.])
    ax6.plot(xx, yy)

    ax6.set_aspect(1.)
    ax6.set_xlim(0, 10.)
    ax6.set_ylim(0, 10.)

    ax6.axis["t"] = ax6.new_floating_axis(0, 3.)
    ax6.axis["t2"] = ax6.new_floating_axis(1, 7.)
    ax6.grid(True)

    plt.show()
Exemplo n.º 8
0
def plotwitherrors(time, timeunit, means, meansunit, std):
    # ---> basic settings
    title = input('Title: ')
    y_name = input('Observable name: ')
    if title == '' or y_name == '':
        title = 'test'
        y_name = 'test'

    axistop_bool = False
    axisright_bool = False
    axisbottom_bool = True
    axisleft_bool = True
    # <--- basic settings

    # ---> analyse data
    # <--- analyse data

    # plot --->
    fig = plt.figure()
    ax = Subplot(fig, 111)
    fig.add_subplot(ax)

    ax.errorbar(time,
                means,
                yerr=std,
                marker='o',
                markersize=2,
                c='black',
                linestyle='none',
                ecolor='black',
                elinewidth=1,
                capthick=1,
                capsize=3)

    ax.plot(time,
            means,
            color='black',
            alpha=0.5,
            linewidth=1.0,
            linestyle='--')

    #legend and labels
    ax.legend(loc='best')
    plt.xlabel('time in ' + timeunit, **hfont)
    plt.ylabel(y_name + ' in ' + meansunit, **hfont)

    # visible axis
    ax.axis["right"].set_visible(axisright_bool)
    ax.axis["top"].set_visible(axistop_bool)
    ax.axis["bottom"].set_visible(axisbottom_bool)
    ax.axis["left"].set_visible(axisleft_bool)

    # <--- plot

    # save plot --->
    pdfdirectory = '../../figures/' + title + '.pdf'
    pgfdirectory = '../../figures/' + title + '.pgf'
    fig.savefig(pdfdirectory)
    plt.savefig(pgfdirectory)
    # <--- save plot

    print('test run successful')
    return None
Exemplo n.º 9
0
def plotSpikes(qdata,save=False,fname='hmmSorting.pdf',tuning=False,figsize=(10,6)):

    allSpikes = qdata['allSpikes'] 
    unitSpikes = qdata['unitSpikes']
    spikeIdx = qdata['spikeIdx']
    spikeIdx = qdata['unitTimePoints']
    units = qdata['unitTimePoints']
    spikeForms = qdata['spikeForms']
    channels = qdata['channels']
    uniqueIdx = qdata['uniqueIdx']
    samplingRate = qdata.get('samplingRate',30000.0)
    """
    mustClose = False
    if isinstance(dataFile,str):
        dataFile = h5py.File(dataFile,'r')
        mustClose = True
    data = dataFile['data'][:]
    """
    keys = np.array(units.keys())
    x = np.arange(32)[None,:] + 42*np.arange(spikeForms.shape[1])[:,None]
    xt = np.linspace(0,31,spikeForms.shape[-1])[None,:] + 42*np.arange(spikeForms.shape[1])[:,None]
    xch = 10 + 42*np.arange(len(channels))
    for c in units.keys():
        ymin,ymax = (5000,-5000)
        fig = plt.figure(figsize=figsize)
        fig.subplots_adjust(hspace=0.3)
        print "Unit: %s " %(str(c),)
        print "\t Plotting waveforms..."
        sys.stdout.flush()
        #allspikes = data[units[c][:,None]+np.arange(-10,22)[None,:],:]
        #allspikes = allSpikes[spikeIdx[c]]
        allspikes = qdata['unitSpikes'][c]
        otherunits = keys[keys!=c]
        #nonOverlapIdx = np.prod(np.array([~np.lib.arraysetops.in1d(spikeIdx[c],spikeIdx[c1]) for c1 in otherunits]),axis=0).astype(np.bool)
        #nonOverlapIdx = np.prod(np.array([pdist_threshold(spikeIdx[c],spikeIdx[c1],3) for c1 in otherunits]),axis=0).astype(np.bool)
        #nonOverlapIdx = uniqueIdx[c]
        nonOverlapIdx = qdata['nonOverlapIdx'][c]
        overlapIdx = np.lib.arraysetops.setdiff1d(np.arange(qdata['unitTimePoints'][c].shape[0]),nonOverlapIdx)
        #allspikes = allSpikes[np.lib.arraysetops.union1d(nonOverlapIdx,overlapIdx)]
        ax = Subplot(fig,2,3,1)
        fig.add_axes(ax)
        formatAxis(ax)
        #plt.plot(x.T,sp,'b')
        m = allspikes[:].mean(0)
        s = allspikes[:].std(0)
        plt.plot(x.T,m,'k',lw=1.5)
        #find the minimum point for this template
        ich = spikeForms[int(c)].min(1).argmin()
        ix = spikeForms[int(c)][ich,:].argmin()
        #plt.plot(x.T,spikeForms[int(c)][:,ix-10:ix+22].T,'r')
        plt.plot(x.T,np.roll(spikeForms[int(c)],10-ix,axis=1)[:,:32].T,'r')
        for i in xrange(x.shape[0]):
            plt.fill_between(x[i],m[:,i]-s[:,i],m[:,i]+s[:,i],color='b',alpha=0.5)
        yl = ax.get_ylim()
        ymin = min(ymin,yl[0])
        ymax = max(ymax,yl[1])
        ax.set_title('All spikes (%d)' % (allspikes.shape[0],))

        ax = Subplot(fig,2,3,2)
        fig.add_axes(ax)
        formatAxis(ax)
        if len(nonOverlapIdx)>0:
            m =  allspikes[:][nonOverlapIdx,:,:].mean(0)
            s =  allspikes[:][nonOverlapIdx,:,:].std(0)
            plt.plot(x.T,m,'k',lw=1.5)
            for i in xrange(x.shape[0]):
                plt.fill_between(x[i],m[:,i]-s[:,i],m[:,i]+s[:,i],color='b',alpha=0.5)
        #plt.plot(x.T,spikeForms[int(c)][:,ix-10:ix+22].T,'r')
        plt.plot(x.T,np.roll(spikeForms[int(c)],10-ix,axis=1)[:,:32].T,'r')
        yl = ax.get_ylim()
        ymin = min(ymin,yl[0])
        ymax = max(ymax,yl[1])
        #for sp in allspikes[nonOverlapIdx,:,:]:
        #    plt.plot(x.T,sp,'r')

        ax.set_title('Non-overlap spikes (%d)' %(nonOverlapIdx.shape[0],))
        ax = Subplot(fig,2,3,3)
        fig.add_axes(ax)
        formatAxis(ax)
        if len(overlapIdx)>0:
            m =  allspikes[:][overlapIdx,:,:].mean(0)
            s =  allspikes[:][overlapIdx,:,:].std(0)
            plt.plot(x.T,m,'k',lw=1.5)
            for i in xrange(x.shape[0]):
                plt.fill_between(x[i],m[:,i]-s[:,i],m[:,i]+s[:,i],color='b',alpha=0.5)
        #plt.plot(x.T,spikeForms[int(c)][:,ix-10:ix+22].T,'r')
        plt.plot(x.T,np.roll(spikeForms[int(c)],10-ix,axis=1)[:,:32].T,'r')
        yl = ax.get_ylim()
        ymin = min(ymin,yl[0])
        ymax = max(ymax,yl[1])
        #for sp in allspikes[~nonOverlapIdx,:,:]:
        #    plt.plot(x.T,sp,'g')
        ax.set_title('Overlap spikes (%d)' % ((overlapIdx).shape[0],))
        for a in fig.axes:
            a.set_ylim((ymin,ymax))
            a.set_xticks(xch)
            a.set_xticklabels(map(str,channels))
            a.set_xlabel('Channels')
        for a in fig.axes[1:]:
            a.set_yticklabels([])
        fig.axes[0].set_ylabel('Amplitude')
        """
        isi distribution
        """
        print "\t ISI distribution..."
        sys.stdout.flush()
        timepoints = qdata['unitTimePoints'][c][:]/(samplingRate/1000)
        if len(timepoints)<2:
            print "Too few spikes. Aborting..."
            continue 
        isi = np.log(np.diff(timepoints))
        n,b = np.histogram(isi,100)
        ax = Subplot(fig,2,3,4)
        fig.add_axes(ax)
        formatAxis(ax)
        ax.plot(b[:-1],n,'k')
        yl = ax.get_ylim()
        ax.vlines(0.0,0,yl[1],'r',lw=1.5)
        ax.set_xlabel('ISI [ms]')
        #get xticklabels
        xl,xh = int(np.round((b[0]-0.5)*2))/2,int(np.round((b[-1]+0.5)*2))/2
        xl = -0.5
        dx = np.round(10.0*(xh-xl)/5.0)/10
        xt_ = np.arange(xl,xh+1,dx)
        ax.set_xticks(xt_)
        ax.set_xticklabels(map(lambda s: r'$10^{%.1f}$' % (s,),xt_))

        """
        auto-correlogram
        """
        print "\t auto-correllogram..."
        sys.stdout.flush()
        if not 'autoCorr' in qdata:
            if isinstance(qdata,dict):
                qdata['autoCorr'] = {}
            else:
                qdata.create_group('autoCorr')
        if not c in qdata['autoCorr']:
            C = pdist_threshold2(timepoints,timepoints,50)
            qdata['autoCorr'][c] = C
            if not isinstance(qdata,dict):
                qdata.flush()
        else:
            C = qdata['autoCorr'][c][:]
        n,b = np.histogram(C[C!=0],np.arange(-50,50))
        ax = Subplot(fig,2,3,5)
        fig.add_axes(ax)
        formatAxis(ax)
        ax.plot(b[:-1],n,'k')
        ax.fill_betweenx([0,n.max()],-1.0,1.0,color='r',alpha=0.3)
        ax.set_xlabel('Lag [ms]')
        if tuning:
            print "\tPlotting tuning..."
            sys.stdout.flush()
            #attempt to get tuning for the current session, based on PWD
            stimCounts,isiCounts,angles,spikedata = gt.getTuning(sptrain=timepoints)        
            #reshape to number of orientations X number of reps, collapsing
            #across everything else
            #angles = np.append(angles,[angles[0]])
            C = stimCounts['0'].transpose((1,0,2,3))
            C = C.reshape(C.shape[0],C.size/C.shape[0])
            ax = plt.subplot(2,3,6,polar=True) 
            ax.errorbar(angles*np.pi/180,C.mean(1),C.std(1))

        if save:
            if not os.path.isabs(fname):
                fn = os.path.expanduser('~/Documents/research/figures/SpikeSorting/hmm/%s' % (fname.replace('.pdf','Unit%s.pdf' %(str(c),)),))
            else:
                fn = fname.replace('.pdf','Unit%s.pdf' %(str(c),))

            fig.savefig(fn,bbox='tight')

    if not save:
        plt.draw()
    """
Exemplo n.º 10
0
fig = plt.figure()
ax = Subplot(fig, 1, 1, 1, grid_helper=skew_grid_helper)
fig.add_subplot(ax)


def format_coord(x, y):
    """format ticks with physical values"""
    T, p = to_thermo(x, y)
    return "{0: 5.1f} C {1: 5.1f} mb".format(float(T), float(p))


ax.format_coord = format_coord

for yi in y_p_levels:
    ax.plot((x_min, x_max), (yi, yi), color=(1.0, 0.8, 0.8))

for x_T in x_T_levels:
    ax.plot(x_T, y_all_p, color=(1.0, 0.5, 0.5))

for x_theta in x_thetas:
    ax.plot(x_theta, y_all_p, color=(1.0, 0.7, 0.7))

for x_mixing_ratio in x_mixing_ratios:
    good = p_all >= 600  #restrict mixing ratio lines to below 600 mb
    ax.plot(x_mixing_ratio[good], y_all_p[good], color=(0.8, 0.8, 0.6))

n_moist = len(theta_ep_levels)
moist_colors = ((0.6, 0.9, 0.7), ) * n_moist
ax.contour(x_from_Tp(mesh_T + C_to_K, mesh_p),
           y_from_p(mesh_p),
Exemplo n.º 11
0
	np.arange(-60.0, T_levels.max()-C_to_K+0.1, 0.1), p_all)
theta_ep_mesh = Bolton.theta_ep_field(mesh_T, mesh_p)



# Plotting Code!

skew_grid_helper = GridHelperCurveLinear((from_thermo, to_thermo))


fig = plt.figure()
ax = Subplot(fig, 1, 1, 1, grid_helper=skew_grid_helper)
fig.add_subplot(ax)

for yi in y_p_levels: 
	ax.plot((x_min, x_max), (yi,yi), color = (1.0, 0.8, 0.8))

for x_T in x_T_levels: 
	ax.plot(x_T, y_all_p, color=(1.0, 0.5, 0.5))

for x_theta in x_thetas:
	ax.plot(x_theta, y_all_p, color=(1.0, 0.7, 0.7))

for x_mixing_ratio in x_mixing_ratios:
	good = p_all >= 600  # restrict mixing ratio lines to below 600 mb
	ax.plot(x_mixing_ratio[good], y_all_p[good], color = (0.8, 0.8, 0.6))

n_moist = len(theta_ep_mesh)
moist_colors = ((0.6, 0.9, 0.7),)*n_moist
ax.contour(x_from_Tp(mesh_T+C_to_K, mesh_p), y_from_p(mesh_p),
	theta_ep_mesh, theta_ep_levels, colors = moist_colors)
Exemplo n.º 12
0
def plot_univariate_inequality(xdata,
                               inclusive=False,
                               raycolor='blue',
                               bgcolor='white',
                               xlim=None,
                               figsize=(5, 0.5),
                               figure=None,
                               title=None,
                               **kwargs):
    """Plot a chart of a univariate inequality ray with matplotlib
    
    Args:
        xdata (list, tuple): endpoints of the ray: ``[start, ..., end]``
        
    Kwargs:
        inclusive (bool): if True, draw a filled circle; if False, draw a circle without fill
        raycolor (str): matplotlib color of the line and markers
        bgcolor (str): matplotlib color for the background and circle without fill
        xlim (None, True, or list/tuple): if True, calculate defaults for xmin and xmax of the x-axis
        figsize (tuple): matplotlib figsize
        figure (None or matplotlib.figure.Figure): Figure to add a plot to
        title (None or str): Title to add the the plot
        kwargs: all other kwargs will be passed to `plt.figure()`
        
    Returns:
        matplotlib.figure.Figure: inequality figure
    """

    _xdata = sorted(xdata)
    xstart = _xdata[0]
    xend = _xdata[-1]
    lefttoright = xstart <= xend
    lefttoright2 = xdata[0] <= xdata[-1]

    fig1 = figure or plt.figure(figsize=figsize, facecolor=bgcolor, **kwargs)
    ax1 = Subplot(fig1, 111)
    fig1.add_subplot(ax1)

    style = {}
    style['linewidth'] = 4
    style['linestyle'] = 'solid'
    style['color'] = raycolor
    style['marker'] = 'o'
    style['markersize'] = 12
    style['markevery'] = [0] if lefttoright else [-1]
    style['markerfacecolor'] = raycolor if inclusive else bgcolor
    style['markeredgecolor'] = raycolor
    style['markeredgewidth'] = 4

    arrowstyle = {}
    arrowstyle['marker'] = '>' if lefttoright2 else '<'
    arrowstyle['markersize'] = 12
    arrowstyle['markerfacecolor'] = raycolor
    arrowstyle['markeredgecolor'] = raycolor
    arrowy = xdata[-1] if lefttoright else xdata[0]

    ax1.set(ylim=(-0.5, 1))

    if xlim is True:
        xlim = (float(xstart - 1), float(xend + 0.5))
    if xlim:
        ax1.set(xlim=xlim)

    ax1.axis["left"].set_visible(False)
    ax1.axis["right"].set_visible(False)
    ax1.axis["top"].set_visible(False)

    #ax1.axis["bottom"].set_axisline_style(axisline_style="->", size=2)
    ax1.plot(1, -0.5, ">k", transform=ax1.get_yaxis_transform(), clip_on=False)
    ax1.plot(0, -0.5, "<k", transform=ax1.get_yaxis_transform(), clip_on=False)

    _x = [xval for xval in xdata]
    _y = [0 for xval in xdata]
    plt.plot(_x, _y, **style)
    if title:
        ax1.set_title(title)
    plt.plot(arrowy, 0, **arrowstyle)
    return fig1