Recent

Author Topic: [SOLVED] Looking for a line chart defined by a math function  (Read 1622 times)

wittbo

  • Full Member
  • ***
  • Posts: 150
[SOLVED] Looking for a line chart defined by a math function
« on: December 11, 2019, 03:35:24 pm »
I want to draw a line, which is not defined by some data Points (line diagram), but by its mathematical formula
y = m*x + b
and I want this line be drawn within a (clipping) area in the chart defined by (Xmin/Ymin) and (XMax/YMax).
I found a series type "Function diagram / Funktionsdiagramm" TFuncSeries, which needs a calculation formula; that would work. There is another series type to choose "Math. function/Math. Funktion" without any calculation (TexpressionSeries) and some mystic parameters in the object inspector. Does anyone know something about this type?
« Last Edit: December 11, 2019, 05:05:05 pm by wittbo »
-wittbo-
MBAir with MacOS 10.14.6 / Lazarus 2.2.4
MacStudio with MacOS 13.0.1 / Lazarus 2.2.4

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Looking for a line chart defined by a math function
« Reply #1 on: December 11, 2019, 03:54:06 pm »
Right, TFuncSeries draws a function which is defined by the OnCalculate event: whenever the series needs a value it fires this event, passes the x value of the point to be drawn and you return the corresponding y value. I once wrote a tutorial for it: https://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Function_Series

TExpressionSeries goes a step further. Here the function is defined by a string, like your "m*x+b" (you must drop the "y ="), and it employs the FPExpressionParser to evaluate this formula (https://wiki.lazarus.freepascal.org/How_To_Use_TFPExpressionParser).
The symbol "x" is pre-defined to identify the variable to be plotted along the x axis.
"m" and "b" are user-defined parameters. After adding the series to the chart, select it in the object inspector, go to property Params. Click the "..." button and add two parameters. Select the first parameter and define its Name to be "m" and set the Value to what you need. Then select the other parameter and repeat with "b". Type the formula "m*x+c" in the property Expression. The chart draws the curve, but this is not yet very satisfying because you also must tell the x range: go to the series' Extent and set XMin and XMax as needed, and activate the range by setting UseXMin and UseXMax to true. And you should also set ExtentAutoY to true so that the y data range is found automatically (otherwise you must do the same with the y Extent). Now the series should be plotted correctly without writing any line of code.
« Last Edit: December 11, 2019, 04:01:23 pm by wp »

wittbo

  • Full Member
  • ***
  • Posts: 150
Re: Looking for a line chart defined by a math function
« Reply #2 on: December 11, 2019, 04:21:38 pm »
Thanks a lot for your precise answer and help.

I made some experiments with TExpression series and its quite good. I expect the line by TExpressionSeries to be a little bit faster than that with the TFuncSeries, because no OnCalculation event is needed, which gets called every ... pixel.
And, if I use the domain clause (... < x < ...), no extent definitions are necessary. Really exactly that what I was looking for.
The functionality needed in general is to have an "infinite" line, which can be modified at runtime by dragging 2 points on this line. I would use one line of type TLineSeries containing only 2 points (for dragging purposes), parameter ShowLines = False; the coordinates of those 2 points are used to compute the parameters m and b of the mathematical defined line in TExpressionLine and to set them while dragging. I expect, that the "infinite" line can be moved by dragging the two points of the TLineSeries. Hope this will work (with sufficient performance).
-wittbo-
MBAir with MacOS 10.14.6 / Lazarus 2.2.4
MacStudio with MacOS 13.0.1 / Lazarus 2.2.4

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Looking for a line chart defined by a math function
« Reply #3 on: December 11, 2019, 04:52:36 pm »
Thanks a lot for your precise answer and help.

I made some experiments with TExpression series and its quite good. I expect the line by TExpressionSeries to be a little bit faster than that with the TFuncSeries, because no OnCalculation event is needed, which gets called every ... pixel.
And, if I use the domain clause (... < x < ...), no extent definitions are necessary. Really exactly that what I was looking for.
The functionality needed in general is to have an "infinite" line, which can be modified at runtime by dragging 2 points on this line. I would use one line of type TLineSeries containing only 2 points (for dragging purposes), parameter ShowLines = False; the coordinates of those 2 points are used to compute the parameters m and b of the mathematical defined line in TExpressionLine and to set them while dragging. I expect, that the "infinite" line can be moved by dragging the two points of the TLineSeries. Hope this will work (with sufficient performance).
You may also want to have a look a TConstantLine series which draws an "infinite" vertical line (when LineStyle is lsVertical) at the Position value. And at the DataPointDragTool which offers the possibility to drag data points. See https://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Chart_Tools, there is not tutorial about the DragTool, yet. Have a look at the demo project in folder components/demo/datapointtools of your Lazarus installation,

wittbo

  • Full Member
  • ***
  • Posts: 150
Re: Looking for a line chart defined by a math function
« Reply #4 on: December 11, 2019, 05:03:25 pm »
Found, coded and tested. It really works! Thank you.
The essential coding s.b.; good performance, nearly smooth. :-)

Code: Pascal  [Select][+][-]
  1. procedure TfrmAnalyse.ChartToolset1DataPointDragTool1Drag(ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint);
  2. begin
  3.    SetGeradenParameter
  4. end;
  5.  
  6. procedure TfrmAnalyse.SetGeradenParameter;
  7. var fSteigung       : Double;
  8.     fAchsenabschnitt: Double;
  9.     x1, x2, y1, y2  : Double;
  10. begin
  11.    with clsDragLine do begin
  12.       x1 := GetXValue(0);
  13.       x2 := GetXValue(1);
  14.       y1 := GetYValue(0);
  15.       y2 := GetYValue(1)
  16.    end;
  17.    fSteigung        := (y2 - y1) / (x2 - x1);
  18.    fAchsenabschnitt := y1 - fSteigung * x1;
  19.    clsInfiniteLine.Params.ValueByName['m'] := fSteigung;
  20.    clsInfiniteLine.Params.ValueByName['b'] := fAchsenabschnitt
  21. end;
  22.  
-wittbo-
MBAir with MacOS 10.14.6 / Lazarus 2.2.4
MacStudio with MacOS 13.0.1 / Lazarus 2.2.4

wittbo

  • Full Member
  • ***
  • Posts: 150
Re: [SOLVED] Looking for a line chart defined by a math function
« Reply #5 on: December 11, 2019, 05:09:49 pm »
In addition:
the goal is some kind of manually simulating data from measurements by linear regression:
Step 1:  plot the data points
Step 2:  compute linear regression parameters
Step 3:  show the regression line
Step 4:  modify the regression line manually slightly
Step 5:  Check the parameters, which are derived from the regression line.
-wittbo-
MBAir with MacOS 10.14.6 / Lazarus 2.2.4
MacStudio with MacOS 13.0.1 / Lazarus 2.2.4

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [SOLVED] Looking for a line chart defined by a math function
« Reply #6 on: December 11, 2019, 05:25:10 pm »
For curve fitting you may save some time by using a TFitSeries where, in your case, you'd select FitEquation to be feLinear and the FitRange (xmin, xmax) (see https://wiki.lazarus.freepascal.org/TAChart_documentation#Fit_series, https://wiki.lazarus.freepascal.org/TAChart_Tutorial:_ListChartSource,_Logarithmic_Axis,_Fitting, or the demo in folder components/tachart/demo/fit.

There is also an interactive fit demo based on a TDistanceTool in folder components/tachart/demo/distance

wittbo

  • Full Member
  • ***
  • Posts: 150
Re: [SOLVED] Looking for a line chart defined by a math function
« Reply #7 on: December 11, 2019, 08:56:26 pm »
Thanks, WP, a lot for your tips and hints.
In a few days I will have more time and then will spend some time with checking and testing more of those TAChart tools. It's such a mighty package.
-wittbo-
MBAir with MacOS 10.14.6 / Lazarus 2.2.4
MacStudio with MacOS 13.0.1 / Lazarus 2.2.4

 

TinyPortal © 2005-2018