Linear Curve Fit Function

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Linear Curve Fit Function

Post by Hans Wolfgang » Sat Oct 24, 2009 11:49 pm

My tFastLineSeries has an associated series with curve fit function and another tFastLineSeries as data source. For some reason first-dgree polynomial plots as a constant, and the second degree does a much better fitting job. Not clear what is going on. Note the y axis has a log scale. My graphs are attached. This discussion board rejected the text file containing source data. Data are pasted below. I used a tab-delimited format in order to allow easy copy/paste of blocks of data from Excel.

First column is x values; second is y values. Just noticed the (x,y) pairs are in descending order of x. Reordered the points, tried again, and results were unchanged. Also tried linear Y axis, no change.

280 85
260 130
240 280
210 840

Now I'm curious about the shape of the parabolic fit. The curve fitter apparently did not notice the inverted nature of the parabola traced by this dataset. One would expect an inverted parabola in the fitted curve as well.

I went to a linear Y-axis again, tried a 2nd degree polynomial, and that gave a straight line. Also attached

If any of this has been corrected in v. 8, please let me know.

I have a deadline Monday at 8:00 AM Would be very helpful to have this resolved by that time. earlier if possible.
Attachments
LinearY-2ndDegree.jpg
Second degree fit to linear y axis
LinearY-2ndDegree.jpg (94.55 KiB) Viewed 21411 times
PolyDegree2.jpg
Results of second-degree polynomial fit
PolyDegree2.jpg (94.09 KiB) Viewed 21318 times
PolyDegree1.jpg
Results of first-degree polynomial fit
PolyDegree1.jpg (91.68 KiB) Viewed 21322 times

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Mon Oct 26, 2009 11:14 am

Hi Hans,

I think it works in the same way in v8 but I don't think that's a bug.

First of all note that changing the Y axis from linear to logarithmic, it affects the axis, but not the series' values neither the curve fitting calculations so a line that describes an inverted parabola, changing the Y axis to logarithmic can change the line to describe a different parabola.

And to understand how that function works, please take a look at the following topics:
http://www.teechart.net/support/viewtop ... 77&p=17447
http://www.teechart.net/support/viewtop ... f=3&t=5812
http://www.teechart.net/support/viewtop ... 777#p42818
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Mon Oct 26, 2009 1:05 pm

Thanks Yeray. What I get from this is that I need a new series S1 in which the y values are the log of the y values of the original series, and do a linear fit to S1. Since there is no built-in function, I will try to use the Calculate() method to create the logs of original y values. Looks OK?

Also, for your wish list, suggest that you add an item to change the default tic values of log axis to 1,2,5,10,20,50,100,200,500, etc.

===================

(Added) I am still at sea on this. I do not believe that the scheme described above can work, because the numbers will become smaller and will bear no relationship to the y values that I am trying to fit.

Would you please have a look at the source code package sent in the "Text File Data Source" thread, and show me how to create a linear fit when the y axis is logarithmic. Use the following dataset rather than the text files in the package. The variables are in order x, y. Make y axis logarithmic.

2.07 840
1.95 280
1.88 130
1.81 85

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Tue Oct 27, 2009 9:26 am

Hi Hans,

I'm not sure to understand you.
Could you please attach here the example you mention adapted or another simple example project we can run as-is to reproduce the problem here?
Could you also please explain what's the exact problem you are having with it?
Thanks in advance.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Tue Oct 27, 2009 1:24 pm

Solved the hard part.

Trick is to leave left axis linear, and convert my series y values to log10. Linear fit with polydegree=2, works fine.

Remaining task is to create a log scale at left axis. That is, create value labels, gridlines that can be hidden or shown, and tics at 10, 20, 50, 100, 200, 500, 1000, etc. I suppose CustomDraw method is what is needed here. Searched the forum and read the tutorial, but did not find much that pertained to this problem. If you can provide a working example of CustomDraw that I can start from, would be very helpful.

Procedure has to be versatile. Tics will vary depending upon the number of decades from Ymin to Ymax. I think I begin to see how this is done. Any assistance by way of a "head start" or "running start" (American metaphors) would be much appreciated.

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Tue Oct 27, 2009 3:19 pm

Hi Hans,

Probably you should use custom labels. Take a look at this:

Code: Select all

  with Chart1.Axes.Left do            //10, 20, 50, 100, 200, 500, 1000
  begin
    Logarithmic:=true;
    Items.Clear;
    Items.Add(1);
    Items.Add(10);
    Items.Add(20);
    Items.Add(50);
    Items.Add(100);
    Items.Add(200);
    Items.Add(500);
    Items.Add(1000);
  end;
Of course this is not variable but if you know a relation you could use to decide what are the values where you would like to draw the labels, you could create them dynamically.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Tue Oct 27, 2009 3:54 pm

Does not work with TC v. 5. I have to use chart1.LeftAxis, Logarithmic is ok but "Items" does not compile.

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Tue Oct 27, 2009 4:31 pm

Hi Hans,

Yes, Custom labels were a new feature in TeeChart v6. So here I think you have two options, upgrade to TeeChart v8 or, as you've said, custom drawing your lines and text. Something like this:

Code: Select all

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var Value: Integer;
begin
  with Chart1.Canvas do
  begin
    Pen.Style:=psDot;
    Pen.Color:=clGrayText;
    Font.Size:=Chart1.Axes.Left.LabelsFont.Size;

    Value:=20;
    Line(Chart1.Axes.Left.PosAxis - 4,Chart1.Axes.Left.CalcPosValue(Value),Chart1.Axes.Bottom.IEndPos,Chart1.Axes.Left.CalcPosValue(Value));
    TextOut(Chart1.Axes.Left.PosAxis - 20, Chart1.Axes.Left.CalcPosValue(Value) - 6, InttoStr(Value));

    Value:=50;
    Line(Chart1.Axes.Left.PosAxis - 4,Chart1.Axes.Left.CalcPosValue(Value),Chart1.Axes.Bottom.IEndPos,Chart1.Axes.Left.CalcPosValue(Value));
    TextOut(Chart1.Axes.Left.PosAxis - 20, Chart1.Axes.Left.CalcPosValue(Value) - 6, InttoStr(Value));

    Value:=200;
    Line(Chart1.Axes.Left.PosAxis - 4,Chart1.Axes.Left.CalcPosValue(Value),Chart1.Axes.Bottom.IEndPos,Chart1.Axes.Left.CalcPosValue(Value));
    TextOut(Chart1.Axes.Left.PosAxis - 28, Chart1.Axes.Left.CalcPosValue(Value) - 6, InttoStr(Value));
  end;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Tue Oct 27, 2009 4:57 pm

Thanks again but does not paint on chart axis. Cannot see any output from the new procedure. Debugger traces through it OK. Project zip file is attached.

In dmChartCommon.pas you can see where I am headed with this. There will be a varying number of decades in the log axis, and max/min points need to conserve all data points but not waste space. If you can correct/add to my code (procedure DrawNewLogAxis), I would be grateful.
Last edited by Hans Wolfgang on Sun Nov 01, 2009 7:21 pm, edited 1 time in total.

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Tue Oct 27, 2009 5:10 pm

Hi Hans,

You have to use Chart's OnAfterDraw event to custom draw. Could you please verify that you've created the event correctly?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Tue Oct 27, 2009 6:01 pm

OnAfterDraw event is now hooked up (sorry I missed that). However, no axis labels are drawn. Here is the added code, in ChartInterface01.pas:

procedure TChartDisplay.Chart1AfterDraw(Sender: TObject);
begin
if Chart1.BottomAxis.inverted then
chartcom.ModifyAxis(Chart1, serLifeTempC );
end;

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Wed Oct 28, 2009 11:26 am

Hi Hans,

After modifying several paths in your project I arrive at an error that says that ChartDisplay and TempDataSrc aren't declared.
Could you please arrange a simple example project we can run as-is to reproduce the problem here? Thanks in advance.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Wed Oct 28, 2009 12:51 pm

A bit of progress. I created a custom axis. See AfterDraw event. I now have exactly one tic on my vertical log axis. In dmChartUtils.pas you can see some code for writing tics at 1,2,5,etc. But maybe you have a better, simpler method.

At the end of Chart1AfterDraw() I added one new line of code. I included existing code to show you where the new line was added:

yMin := ChartCommon.GetRoundLog( MinYValue, false );
yMax := ChartCommon.GetRoundLog( MaxYValue, true )
end;
With NewAxis do begin
DrawAxisLabel( 75, 300, 0, '55' );
end;

75 and 300 appear to be pixels from top left of chart panel. After adding that line, if you press "Convert", the number 55 will show up. If you press "Linear Fit", the left side of chart moves left, and 55 is closer to where it should be. See screen shot attached.

Can you relate the pixels of the chart to the reference of the panel, so that I can efficiently program the axis labels. And then there is the shift when I press "Linear Fit". That is probably the custom axis, which probably means I need to do the drawing later? Or maybe you have a better way of doing all of this? We also need grid lines for the y axis.

Hope you see the number 2 axis label near bottom of vertical axis. How is that written, and can that method be overridden with the scheme shown at bottom of block, commented, together with ChartCommon.GetNextTic()"? But I am hoping that you can show me an easier method, either with v. 5 or v. 8. If v. 8, could you send some documentation.

Call to your procedure is commented out in the AfterDraw method.

The runtime chart editor does not appear to change any properties on my custom Y axis. Maybe that is expected behavior, or some setting is wrong?

Thanks for your help in this.
Attachments
CustomDraw.jpg
CustomDraw.jpg (47.87 KiB) Viewed 21222 times
Last edited by Hans Wolfgang on Sun Nov 01, 2009 7:22 pm, edited 1 time in total.

Yeray
Site Admin
Site Admin
Posts: 9601
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Linear Curve Fit Function

Post by Yeray » Fri Oct 30, 2009 3:25 pm

Hi Hans,

- The OnAfterDraw event is not the best place to create objects. Note that the code in this event will be called every time the chart will be repainted (each scrolled pixel, each zoom, each added point, change some settings through the editor,...).

- In the application you've just sent, the code you mention to draw the ticks I think is commented and I'm not sure to understand what is trying to do.

- I'm not able to find where is the code you mention that calls DrawAxisLabel.

- To obtain relative positions to the chart, you should use axes' CalcPosValue method as in the code suggested above.

Please, try to reproduce each single and concrete question in a separate simple example project we can run as-is to reproduce them here.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Hans Wolfgang
Newbie
Newbie
Posts: 58
Joined: Fri Nov 15, 2002 12:00 am
Location: Naples, FL
Contact:

Re: Linear Curve Fit Function

Post by Hans Wolfgang » Mon Nov 02, 2009 1:30 pm

Here is a new, smaller demo project. It is a linear curve fit to the same four points as in previous example. Graph shows the data as a point series and two fitting series as fastline. The second fit is the result of applying the answer vector of the fitting function to the math.poly() function. There is a displacement between the two series graphs. I could renormalize at the first point and add a constant to every computed y value. Can you explain why this bias is happening, and hopefully fix this without the renormalization.
Attachments
ENW-Test.zip
(6.55 KiB) Downloaded 741 times

Post Reply