DMelt:DataAnalysis/7 Fitting Shapes
Fitting data with shapes
DataMelt offers classes to fit 2D data using shapes. Typically, shapes can be specified using equations (for example, parametric). In this section we will show how to fit data using ellipses and circles.
Fitting data with circles
Let us perform a least-squires minimisation of points with the goal to determine a circle that best fits the collection of points. The fit determines the circle position and radius. In addition, it calculates how well points distributed around the circle. In this approach we use parametric equations.
Here is a visual example:
This plot was made using the following script:
# Fit data in the form of random circle from java.awt import * from jhplot import * from jhplot.shapes import * from java.util import Random from math import * from jhpro.fit import * c1 =HPlot("Canvas",500,500) c1.setAntiAlias(1) c1.setLegend(0) c1.setRange(-10.0,10.0,-10,10.0) c1.visible(1) p1=P1D("Random ellipse") rand = Random() # a, b are the radius on the x and y axes respectively a=5 # semi-major axis b=5 # semi-minor exis xshift=0 # (X,Y) position yshift=-1 theta=3.14/1 # rotation step=0.04 ra=[v*step for v in range(0,int(6.28/step))] for t in ra: # fill random ellipse. x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift p1.add(x+0.4*rand.nextGaussian(), y+0.3*rand.nextGaussian()) efit= FitCircle2D(p1) # initialize fitter print "Average distance=", efit.getDistance() ele1= efit.getCircle() ele1.setFill(0) ele1.setColor(Color.red) ele1.setTransparency(0.6) c1.add(ele1) # now show all objects c1.draw(p1) # export to some image (png,eps,pdf,jpeg...) # c1.export(Editor.DocMasterName()+".png");
You can access the fit quality as described by the jhpro.fit.FitCircle2D class.
Fitting data with ellipses
This approach also uses the algorithm of Fitzgibbon et al and by Halir et al, to find the ellipse which best approximates a collection of points.
As before, let's try to fit random points distributed around a theoretical ellipses, and the let us find this ellipse using input points.
# fit data in the form of random ellipse from java.awt import * from jhplot import * from jhplot.shapes import * from java.util import Random from math import * from jhpro.fit import * c1 =HPlot("Canvas",500,500) c1.setAntiAlias(1) c1.setLegend(0) c1.setRange(-10.0,10.0,-10,10.0) c1.visible(1) p1=P1D("Random ellipse") rand = Random() # a, b are the radius on the x and y axes respectively a=8 # semi-major axis b=3 # semi-minor axis xshift=0 # (X,Y) position yshift=-1 theta=3.14/1 # rotation step=0.04 ra=[v*step for v in range(0,int(6.28/step))] for t in ra: # fill random ellipse. x= a*cos(t)*cos(theta) - b*sin(t)*sin(theta)+xshift y = b*cos(theta)*sin(t) + a*sin(theta)*cos(t)+yshift p1.add(x+0.4*rand.nextGaussian(), y+0.3*rand.nextGaussian()) efit= FitEllipse2D(p1) # initialize fitter print "Average distance=", efit.getDistance() ele1= efit.getEllipse() ele1.setFill(0) ele1.setColor(Color.red) ele1.setTransparency(0.6) c1.add(ele1) # now show all objects c1.draw(p1) # export to some image (png,eps,pdf,jpeg...) # c1.export(Editor.DocMasterName()+".png");
Look at the API of the jhpro.fit.FitEllipse2D class.
The above code also computes the quality of the fit. In this case, this is the average distance of points to the ellipse.