Exemplo n.º 1
0
 def check_4(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,xb=None,xe=None,
           ia=0,ib=2*pi,dx=0.2*pi):
     if xb is None: xb=a
     if xe is None: xe=b
     x=a+(b-a)*arange(N+1,dtype=float)/float(N)    # nodes
     x1=a+(b-a)*arange(1,N,dtype=float)/float(N-1) # middle points of the nodes
     v,v1=f(x),f(x1)
     nk=[]
     put(" u = %s   N = %d"%(repr(round(dx,3)),N))
     put("  k  :  [x(u), %s(x(u))]  Error of splprep  Error of splrep "%(f(0,None)))
     for k in range(1,6):
         tckp,u=splprep([x,v],s=s,per=per,k=k,nest=-1)
         tck=splrep(x,v,s=s,per=per,k=k)
         uv=splev(dx,tckp)
         err1 = abs(uv[1]-f(uv[0]))
         err2 = abs(splev(uv[0],tck)-f(uv[0]))
         assert_(err1 < 1e-2)
         assert_(err2 < 1e-2)
         put("  %d  :  %s    %.1e           %.1e"%\
               (k,repr([round(z,3) for z in uv]),
                err1,
                err2))
     put("Derivatives of parametric cubic spline at u (first function):")
     k=3
     tckp,u=splprep([x,v],s=s,per=per,k=k,nest=-1)
     for d in range(1,k+1):
         uv=splev(dx,tckp,d)
         put(" %s "%(repr(uv[0])))
 def check_4(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,xb=None,xe=None,
           ia=0,ib=2*pi,dx=0.2*pi):
     if xb is None:
         xb = a
     if xe is None:
         xe = b
     x = a+(b-a)*arange(N+1,dtype=float)/float(N)    # nodes
     x1 = a + (b-a)*arange(1,N,dtype=float)/float(N-1)  # middle points of the nodes
     v,v1 = f(x),f(x1)
     put(" u = %s   N = %d" % (repr(round(dx,3)),N))
     put("  k  :  [x(u), %s(x(u))]  Error of splprep  Error of splrep " % (f(0,None)))
     for k in range(1,6):
         tckp,u = splprep([x,v],s=s,per=per,k=k,nest=-1)
         tck = splrep(x,v,s=s,per=per,k=k)
         uv = splev(dx,tckp)
         err1 = abs(uv[1]-f(uv[0]))
         err2 = abs(splev(uv[0],tck)-f(uv[0]))
         assert_(err1 < 1e-2)
         assert_(err2 < 1e-2)
         put("  %d  :  %s    %.1e           %.1e" %
               (k,repr([round(z,3) for z in uv]),
                err1,
                err2))
     put("Derivatives of parametric cubic spline at u (first function):")
     k = 3
     tckp,u = splprep([x,v],s=s,per=per,k=k,nest=-1)
     for d in range(1,k+1):
         uv = splev(dx,tckp,d)
         put(" %s " % (repr(uv[0])))
Exemplo n.º 3
0
def fitEdge(og,e,VERBOSE=False):
    path = og[e[0]][e[1]]['wpath']
    #pstart=og.node[e[0]]['wcrd']
    #pend = og.node[e[1]]['wcrd']
    #path.extend([pend])
    #p = [pstart]
    #p.extend(path)
    ae = np.array(path)
    
    if( ae.shape[0] > 3 ): # there are not enough points to fit with
        if( VERBOSE ): print("refitting edge with %d points"%len(path))

        s = ae.shape[0]/2.0

        fit2 = splprep(ae.transpose(),task=0,full_output =1, s=s)[0]
        u = np.array(list(range(ae.shape[0]+1))).\
                astype(np.float64)/(ae.shape[0])
        # location of spline points
        og[e[0]][e[1]]['d0'] = splev(u,fit2[0],der=0)
        # first derivative (tangent) of spline
        og[e[0]][e[1]]['d1'] =np.array( splev(u,fit2[0],der=1))
        # second derivative (curvature) of spline
        og[e[0]][e[1]]['d2'] = np.array(splev(u,fit2[0],der=2))
    else:
        if( VERBOSE ): print("no or insufficient points to fit")
        og[e[0]][e[1]]['d0'] = None
        og[e[0]][e[1]]['d1'] = None
        og[e[0]][e[1]]['d2'] = None
Exemplo n.º 4
0
def fitEdge(og, e, VERBOSE=False):
    path = og[e[0]][e[1]]['wpath']
    #pstart=og.node[e[0]]['wcrd']
    #pend = og.node[e[1]]['wcrd']
    #path.extend([pend])
    #p = [pstart]
    #p.extend(path)
    ae = np.array(path)

    if (ae.shape[0] > 3):  # there are not enough points to fit with
        if (VERBOSE): print("refitting edge with %d points" % len(path))

        s = ae.shape[0] / 2.0

        fit2 = splprep(ae.transpose(), task=0, full_output=1, s=s)[0]
        u = np.array(list(range(ae.shape[0]+1))).\
                astype(np.float64)/(ae.shape[0])
        # location of spline points
        og[e[0]][e[1]]['d0'] = splev(u, fit2[0], der=0)
        # first derivative (tangent) of spline
        og[e[0]][e[1]]['d1'] = np.array(splev(u, fit2[0], der=1))
        # second derivative (curvature) of spline
        og[e[0]][e[1]]['d2'] = np.array(splev(u, fit2[0], der=2))
    else:
        if (VERBOSE): print("no or insufficient points to fit")
        og[e[0]][e[1]]['d0'] = None
        og[e[0]][e[1]]['d1'] = None
        og[e[0]][e[1]]['d2'] = None
Exemplo n.º 5
0
    def to_spline(self, smoothing=0, spacing_corrected=False):
        """Return the best-fit periodic parametric 3rd degree b-spline to the data points.

        The smoothing parameter is an upper-bound on the mean squared deviation between the
        data points and the points produced by the smoothed spline. By default it is 0,
        forcing an interpolating spline.

        The returned spline is valid over the parametric range [0, num_points+1], where
        the value at 0 is the same as the value at num_points+1. If spacing_corrected
        is True, then the intermediate points will be placed according to the physical
        spacing between them, which is useful in some situations like resampling.
        However, it means that the spline evalueated at position N will not necessarialy
        give the same point as contour.points[n], unless all of the points are exactly
        evenly spaced. Similarly, non-zero values of smoothing will disrupt this property
        as well.

        Two values are returned: tck and u. 'tck' is a tuple containing the spline c
        oefficients, the knots (two lists; x-knots and y-knots), and the degree of
        the spline. This 'tck' tuple can be used by the routines in scipy.fitpack.
        'u' is a list of the parameter values corresponding to the points in the range.
        """
        # the fitpack smoothing parameter is an upper-bound on the TOTAL squared deviation;
        # ours is a bound on the MEAN squared deviation. Fix the mismatch:
        l = len(self.points)
        smoothing = smoothing * l
        if spacing_corrected:
            interpoint_distances = self.interpoint_distances()
            last_to_first = interpoint_distances[0]
            interpoint_distances[0] = 0
            cumulative_distances = numpy.add.accumulate(interpoint_distances)
            u = numpy.empty(l + 1, dtype=float)
            u[:-1] = cumulative_distances
            u[-1] = cumulative_distances[-1] + last_to_first
            u *= l / u[-1]
        else:
            u = numpy.arange(0, l + 1)
        points = numpy.resize(self.points, [l + 1, 2])
        points[-1] = points[0]
        tck, uout = fitpack.splprep(x=points.transpose(),
                                    u=u,
                                    per=True,
                                    s=smoothing)
        return tck, uout
Exemplo n.º 6
0
 def fitPath(self,maxiter=40, s=20000):
     """fits a least squares spline through the path
     find descriptions of maxiter and s from scipy documentation"""
     try:
         pth = path.getCrds()
         pp = [pth[:,0],pth[:,1],pth[:,2]]
         if( len(pp[0]) <= 3 ): # there are not enough points to fit with
             self.splinePoints = pp
             self.splineTangents = None
             self.splineCurvature = None
             return 
         else:
             s = len(pp[0])/2.0
             cont = 1
             j=0
             while( j < maxiter ):
                 fit2 = splprep(pp,task=0,full_output =1, s=s)[0]
                 u = na.array(range(pp[0].shape[0]+1)).\
                         astype(na.float64)/(pp[0].shape[0])
                 # location of spline points
                 self.splinePoints = splev(u,fit2[0],der=0)
                 # first derivative (tangent) of spline
                 valsd = splev(u,fit2[0],der=1)
                 self.splineTangents = na.array(valsd).astype(na.float64)
                 # second derivative (curvature) of spline
                 valsc = splev(u,fit2[0],der=2)
                 self.splineCurvature = na.array(valsc).astype(na.float64)
                 success = 1 # this doesn't make much sense
                 if( success ): # how should I be determining success?
                     break
                 else:
                     s = s*0.9
                 j += 1
             return True
     except Exception, error:
         print "failed in fitPath()",error
Exemplo n.º 7
0
 def fitPath(self, maxiter=40, s=20000):
     """fits a least squares spline through the path
     find descriptions of maxiter and s from scipy documentation"""
     try:
         pth = path.getCrds()
         pp = [pth[:, 0], pth[:, 1], pth[:, 2]]
         if (len(pp[0]) <= 3):  # there are not enough points to fit with
             self.splinePoints = pp
             self.splineTangents = None
             self.splineCurvature = None
             return
         else:
             s = len(pp[0]) / 2.0
             cont = 1
             j = 0
             while (j < maxiter):
                 fit2 = splprep(pp, task=0, full_output=1, s=s)[0]
                 u = na.array(range(pp[0].shape[0]+1)).\
                         astype(na.float64)/(pp[0].shape[0])
                 # location of spline points
                 self.splinePoints = splev(u, fit2[0], der=0)
                 # first derivative (tangent) of spline
                 valsd = splev(u, fit2[0], der=1)
                 self.splineTangents = na.array(valsd).astype(na.float64)
                 # second derivative (curvature) of spline
                 valsc = splev(u, fit2[0], der=2)
                 self.splineCurvature = na.array(valsc).astype(na.float64)
                 success = 1  # this doesn't make much sense
                 if (success):  # how should I be determining success?
                     break
                 else:
                     s = s * 0.9
                 j += 1
             return True
     except Exception, error:
         print "failed in fitPath()", error
Exemplo n.º 8
0
def distribution_plot(data_groups, filename, axis_title = None, plot_title = None,
        colors = default_colors, names = None, axes_at_origin = True, plot_points = False,
 	fix_xrange = (None, None), scale_factors = None):
    """Plot the 1D distributions of several collections of points to a SVG file.

    The distributions of the 1D points in 'data_groups' are estimated with kernel
    density estimation, fit to splines, and plotted on numerical axes with an
    optional legend.

    Parameters:
        data_groups -- a list of grouped data points. Each group is a list of numbers,
            the distribution of which will be estimated and plotted.
        filename -- file to write the SVG out to.
        axis_title -- Title for the x-axis.
        plot_title -- title for the plot.
        colors -- the colors to fill the contours of each group with. Either color
            names that are defined in the SVG specification or (r,g,b) triplets are
            acceptable. This parameter must be an iterable; if there are not enough
            elements for the groups, they will be cycled.
        names -- the name of each group. Must be a list as long as contour_groups.
            If names is None, then there will be no legend in the output SVG.
        axes_at_origin -- if True, then the plot axes will intersect at the origin
            (or the nearest point to it in the data plot). Otherwise the axes will
            be at the bottom and left of the plot.
	    plot_points -- if True, dots will be plotted at the location of each
	        sample.
        fix_xrange, fix_yrange -- (min, max) tuples. If either or both values are
            None, then the best-fit range given the contours and their positions is
            chosen. Setting either or both forces the axis to have that minimum or
            maximum point.
        scale_factors -- If not None, a list of values by which to scale the heights
            of each distribution.
    """
    from scipy.interpolate import fitpack
    data_groups = [numpy.asarray(data_group, dtype=numpy.float32) for data_group in data_groups]
    if not numpy.alltrue([data_group.ndim == 1 for data_group in data_groups]):
        raise ValueError('Can only plot distributions in one dimension.')
    data_groups = [numpy.asarray(data_group) for data_group in data_groups]
    data_ranges = [(g.min(), g.max()) for g in data_groups]
    kd_estimators = [kde.gaussian_kde(data_group) for data_group in data_groups]
    min = numpy.min([m for m, x in data_ranges])
    max = numpy.max([x for m, x in data_ranges])
    extra = 0.05*(max - min)
    min -= extra
    max += extra
    #min, max, data_ranges = _kde_range(kd_estimators, data_ranges, 5e-6)
    # pin the values to those of fix_xrange, if specified
    if fix_xrange[0] is not None:
        min = fix_xrange[0]
    if fix_xrange[1] is not None:
        max = fix_xrange[1]

    height = 0
    beziers = []
    err = numpy.seterr(under='ignore')
    # ignore underflow -- KDE can underflow when estimating regions of very low density
    if scale_factors is None:
        scale_factors = [1]*len(kd_estimators)
    for (range_min, range_max), estimator, scale_factor in zip(data_ranges, kd_estimators, scale_factors):
        if fix_xrange[0] is not None and range_min < min: range_min=min
        if fix_xrange[1] is not None and range_max > max: range_max=max
        eval_points = list(numpy.linspace(range_min, range_max, 100, True))
        kde_points = estimator.evaluate(eval_points) * scale_factor
        data_height = kde_points.max()
        if data_height > height: height = data_height
        #s = 0.0005 * numpy.min([range_max - range_min, data_height]) / 100
        s = 0
        spline = fitpack.splprep([eval_points, kde_points], u=eval_points, s=s)[0]
        beziers.append(utility_tools.b_spline_to_bezier_series(spline))
    numpy.seterr(**err)

    data_xrange = [min, max]
    data_yrange = [0, height]
    equal_axis_spacing = False
    plot = plot_class.Plot(_CANVAS_WIDTH, _CANVAS_HEIGHT, data_xrange, data_yrange,
        equal_axis_spacing, _LEFT_PAD, _RIGHT_PAD, _TOP_PAD, _BOTTOM_PAD)
    legend = True
    if names is None:
        legend = False
        names = ['distribution-%d'%d for d in range(len(data_groups))]
    else:
        names = [name.replace(' ', '_') for name in names]
    if plot_points:
    	point_radius = 0.005 * (data_xrange[1] - data_xrange[0])
    	plot.style.add_selector('[class~="point"]', fill='black', stroke=None)
    for name, bezier, data_group, estimator, color in zip(names, beziers, data_groups, kd_estimators, itertools.cycle(colors)):
        plot.add_bezier(bezier, id=name, svg_class='data density', layer=name)
        plot.style.add_selector('[class~="density"][id="%s"]'%name, fill='none', stroke=color)
        plot.style.add_selector('[class~="legend"][id="%s"]'%name, fill='none', stroke=color)
        if plot_points:
        	values = numpy.unique(data_group)
        	for point in zip(values, estimator(values)):
        	    plot.add_circle(point, point_radius, id=None, svg_class="data point", layer=name, in_data_coords=True)
    if legend:
        legend_x = _CANVAS_WIDTH - _PAD - 80
        legend_y = _FONT_SIZE_SMALL * plot_class._TOP_TO_BASELINE + _PAD
        line_length = 50
        plot.add_legend(legend_x, legend_y, line_length, names, _FONT_SIZE_SMALL)
    if plot_title is not None:
        plot.add_title(plot_title, _FONT_SIZE)
    if axes_at_origin:
        positions = (-1,0)
    else:
        positions = (-1,-1)
    plot.add_axes(positions = positions, titles = (axis_title, None), ticsize = _TICSIZE, font_size = _FONT_SIZE_SMALL)
    plot.to_svg(filename, plot_title)
    return plot
Exemplo n.º 9
0
def line_plot(data_groups, filename, axis_titles = (None, None), plot_title = None,
        colors = default_colors, names = None, axes_at_origin = True,
        fix_xrange = (None, None), fix_yrange = (None, None), bezier=None):
    """Plot smooth lines connecting at given x, y locations to an SVG file.

    The resulting SVG will have numerical axes (either centered at the origin, or
    placed on the left and bottom of the plot) and optionally a legend.

    Parameters:
        data_groups -- a list of polylines to be plotted, where each polyline is
            placed in a different SVG group and colored differently. Each polyline
            is itself a list of [x, y] pairs.
        filename -- file to write the SVG out to.
        line_width -- Pixel width of the lines to be plotted.
        axis_titles -- pair of titles for the x and y axes, respectively.
        plot_title -- title for the plot.
        colors -- the colors to fill the contours of each group with. Either color
            names that are defined in the SVG specification or (r,g,b) triplets are
            acceptable. This parameter must be an iterable; if there are not enough
            elements for the groups, they will be cycled.
        names -- the name of each group. Must be a list as long as contour_groups.
            If names is None, then there will be no legend in the output SVG.
        axes_at_origin -- if True, then the plot axes will intersect at the origin
            (or the nearest point to it in the data plot). Otherwise the axes will
            be at the bottom and left of the plot.
        fix_xrange, fix_yrange -- (min, max) tuples. If either or both values are
            None, then the best-fit range given the contours and their positions is
            chosen. Setting either or both forces the axis to have that minimum or
            maximum point.
    """
    from scipy.interpolate import fitpack
    all_points = numpy.array([p for dg in data_groups for p in dg])

    plot_width = _CANVAS_WIDTH - _LEFT_PAD - _RIGHT_PAD
    plot_height = _CANVAS_HEIGHT - _TOP_PAD - _BOTTOM_PAD
    data_xrange, data_yrange = numpy.transpose([all_points.min(axis=0), all_points.max(axis=0)])
    fmin, fmax = fix_xrange
    if fmin is not None: data_xrange[0] = fmin
    if fmax is not None: data_xrange[1] = fmax
    fmin, fmax = fix_yrange
    if fmin is not None: data_yrange[0] = fmin
    if fmax is not None: data_yrange[1] = fmax
    equal_axis_spacing = False
    plot = plot_class.Plot(_CANVAS_WIDTH, _CANVAS_HEIGHT, data_xrange, data_yrange,
        equal_axis_spacing, _LEFT_PAD, _RIGHT_PAD, _TOP_PAD, _BOTTOM_PAD)
    legend = True
    if names is None:
        legend = False
        names = ['group-%d'%d for d in range(len(data_groups))]
    else:
        names = [name.replace(' ', '_') for name in names]
    for name, data_group, color in zip(names, data_groups, itertools.cycle(colors)):
        if bezier is not None:
            spline = fitpack.splprep(numpy.transpose(data_group), s=bezier)[0]
            curve = utility_tools.b_spline_to_bezier_series(spline)
            plot.add_bezier(curve, id=name, svg_class='data line', layer=name)
        else:
            plot.add_polyline(data_group, id=name, svg_class='data line', layer=name)
        plot.style.add_selector('[id="%s"]'%name, fill='none', stroke=color)
    if legend:
        legend_x = _CANVAS_WIDTH - _PAD - 80
        legend_y = _FONT_SIZE_SMALL * plot_class._TOP_TO_BASELINE + _PAD
        line_length = 50
        plot.add_legend(legend_x, legend_y, line_length, names, _FONT_SIZE_SMALL, box=False)
    if plot_title is not None:
        plot.add_title(plot_title, _FONT_SIZE)
    if axes_at_origin:
        positions = (0,0)
    else:
        positions = (-1,-1)
    plot.add_axes(positions = positions, titles = axis_titles, ticsize = _TICSIZE, font_size = _FONT_SIZE_SMALL)
    plot.to_svg(filename, plot_title)
    return plot