Recent

Author Topic: Contour plots with TAChart  (Read 8228 times)

wp

  • Hero Member
  • *****
  • Posts: 7552
Contour plots with TAChart
« on: December 31, 2012, 05:46:17 pm »
A happy new year to everybody reading this...

After having found the "last" bug I am posting a little component which allows to create contour plots (iso-lines) for gridded 3D data with TAChart. Since TAChart currently does not support 3D data I did not create a new series type for this purpose, but decided to delegate the contour tracing task to a new "TContourFinder" class and use a standard TListChartSource for storing the contour line coordinates and a TLineSeries for drawing the contour lines.

See the header of the unit TAContour.pas for a description how to apply the TContourFinder. And, of course, see the attached demo and screenshot.

The contour lines are traced by means of the "Moore neighborhood algorithm" which is described in http://en.wikipedia.org/wiki/Moore_neighborhood, or http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html -- the latter with some animations showing how the algorithm works.

While developing and debugging this component I came across some issues with TAChart (or my still limited understanding of this library):
  • In the demo you can show the data grid which is used to construct the contour lines. I tried to give the grid points different colors for function values below and above the requested contour level by modifying the "Color" of the TChartDataItem stored in the ListSource, but this was not successful. -- See comment in "TForm1.UserDefinedChartSource1GetChartDataItem")
  • Trying to activate marks of the contour line series ("TForm1.DrawContours") crashes the program with a SIGFPE.
  • In principle it should be possible to draw the contour lines with splines instead of line series; this would produce smooth contours even at low grid resolution. But again the demo crashes with a SIGFE.
  • In the demo I am constructing the contours from bottom to top, this means that the contour lines are ordered lowest value first in the legend -- it would be better if the legend would start with the highest contour level and go down to the lowest value. Of course, I could construct the contours in the opposite order (top to bottom), but I thought there was a way to flip the legend...
I am sure the solution to these issues must be very easy...

EDIT: Sorry for the incomplete zip archive -- see the third posting in this thread for the complete contour.zip
« Last Edit: January 01, 2013, 01:22:52 am by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

howardpc

  • Hero Member
  • *****
  • Posts: 3526
Re: Contour plots with TAChart
« Reply #1 on: December 31, 2012, 07:58:08 pm »
Unfortunately I could not find TAContour.pas in the .zip attachment.

wp

  • Hero Member
  • *****
  • Posts: 7552
Re: Contour plots with TAChart
« Reply #2 on: January 01, 2013, 01:21:12 am »
Sorry...
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Contour plots with TAChart
« Reply #3 on: January 01, 2013, 04:25:30 am »
That is a nice New Year present, thank you!

I am now somewhat overwhelmed by various celebration activities, but here is a few quick points:
1) I like your general modular approach, where contouring is independent of any specific series.
2) I suggest giving some thought to the modularity of contouring algorithms, my experience suggests that different algorithms give very different results on real data.
3) Your implementation is scale-dependent, i.e. zooming requires contour re-calculation. This has both upsides and downsides, so perhaps should be made an option.
4) Ideally, color map, contouring and your recent interpolation unit should work well together -- for example, how will contours over color map look?

Quote
I tried to give the grid points different colors
This is because item color determines brush color, not pen color.
If you set Pointer.Style = psCircle, you will see the effect.
Since r39704 I have added Pointer.OverrideColor property to control this behavior.

Quote
I thought there was a way to flip the legend
Use Legend.Order property.

Quote
SIGFPE
Both problems are because of incomplete support of NaNs.
I have partially fixed the first one in r39705, but there is still work to do.

wp

  • Hero Member
  • *****
  • Posts: 7552
Re: Contour plots with TAChart
« Reply #4 on: January 01, 2013, 05:46:19 pm »
Thanks for the fixes.

Now that the series marks are working with NaN's I am posting an updated version of the ContourFinder and the demo which allows to position the values of the contour levels along the contour lines. This is done by the parameter AMarksPosition passed to the main method, TraceContourAtLevel. I did not put too much effort into avoiding overlapping of marks, but the "random" setting is fine in many cases.

I also was thinking of rotating the marks along the direction of the contour curve. But unfortunately all marks must have the same orientation so far.

Quote
Ideally, color map, contouring and your recent interpolation unit should work well together
Yes, they can be combined - see the new demo. A few things to mention: The ZPosition of the ColorMapSeries must be "below" that of the contour series to avoid overpainting the contours by the colormap. And the Sender parameter of the OnNeedXXXX events should be TObject for both contour finder and interpolation -- this allows to use these events for both components.

As you can see in the attached screen shot there are some minor deviations between contour and color map here and there, but this is due to the different interpolation procedures used in both cases. The contour finder always performs a simple linear interpolation between "above" and "below" points to find the intersection with the plane at the contour level. The interpolation unit on the other hand considers also the neighboring points. It would be an idea to apply these more complex interpolations also in the contour finder, but this would require a major design of the algorithm because the connectivity of the neighboring points needs to be known in advance before performing the interpolation. I don't know if this is worth the effort.

Quote
I suggest giving some thought to the modularity of contouring algorithms
To be honest I am happy that I got this one working. What might be interesting is to put more emphasis on the similarity of the ContourFinder and the Interpolation because of the same data handling. Maybe I should extract a "TChartDataManager" class which interfaces to any data by means of events.

Quote
zooming requires contour re-calculation
No. Having experimental data in mind the contours are calculated only once. Zooming is done by the standard TAChart technology. Of course, the segments of the line series will soon become visible, this is the reason why I had the idea with the spline series.

If you think of theroretical data, it might be an idea to redo the grid layout and the contour calculation when zoom extent changes; but I think this can be done within the standard TAChart events.

Quote
added Pointer.OverrideColor property
If it can be achieved simply it would be fine to have that property also for the font of the Marks texts. Then the contour labels could be drawn with the same color as the contour lines which would be more catchy.

Quote
Use Legend.Order property
I was thinking of something like TChart's "Inverted" which draws all legend items in the order last to first. But, of course, this is not very essential since the effect can be achieved easily.
« Last Edit: January 01, 2013, 05:51:55 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Contour plots with TAChart
« Reply #5 on: January 03, 2013, 05:11:39 pm »
Quote
I am posting an updated version of the ContourFinder and the demo which allows to position the values of the contour levels along the contour lines.

Below is my version of AddMarks procedure, which fixes out-of-bounds access, reduces logic duplication and contains a few style fixes:
Code: [Select]
procedure TContourFinder.AddMarks;
var
  curveStart: Integer = 0;
  curveEnd: Integer = -2;

  function NextCurve: Boolean;
  begin
    curveStart := curveEnd + 2;
    with FListSource do begin
      while (curveStart < Count) and IsNan(Item[curveStart]^.Point) do
        curveStart += 1;
      curveEnd := curveStart;
      while (curveEnd + 1 < Count) and not IsNan(Item[curveEnd + 1]^.Point) do
        curveEnd += 1;
      Result := curveStart < Count;
    end;
  end;

var
  i: Integer;
  s: String;
begin
  for i := 0 to FListSource.Count - 1 do
    FListSource[i]^.Text := '';
  if FContourMarksPosition = cmpNone then exit;

  s := Format(FContourMarksFormat, [FLevel]);
  while NextCurve do begin
    case FContourMarksPosition of
      cmpFirst: i := curveStart;
      cmpLast: i := curveEnd;
      cmpCenter: i := (curveStart + curveEnd) div 2;
      cmpRandom: i := RandomRange(curveStart, curveEnd);
    end;
    FListSource[i]^.Text := s;
  end;
end;

I have added NaN support to B-Spline series in r39752.
Now your demo can draw spline contours
(after a minor fix in DrawContours procedure: use TBSplineSeries instead of TCubicSplineSeries and set Pointer.Visible := false).

Quote
it would be fine to have that property also for the font of the Marks texts. Then the contour labels could be drawn with the same color as the contour lines which would be more catchy.
Just use Marks.LabelFont.Color -- it is enough in this case.

I'll address other points later.

wp

  • Hero Member
  • *****
  • Posts: 7552
Re: Contour plots with TAChart
« Reply #6 on: January 03, 2013, 05:31:26 pm »
Wonderful. Thank you.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

ThB

  • Newbie
  • Posts: 3
Re: Contour plots with TAChart
« Reply #7 on: February 13, 2013, 10:10:22 pm »
Absolutely great !
I'm using Delaunay interpolation on my experimental data and just wanted to start the programming of contour lines. Fortunately you present the solution - thank you both.

wp

  • Hero Member
  • *****
  • Posts: 7552
Re: Contour plots with TAChart
« Reply #8 on: February 13, 2013, 10:50:27 pm »
Would you consider sharing the code for the Delaunay interpolation?
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

stephanweber

  • New Member
  • *
  • Posts: 37
Re: Contour plots with TAChart
« Reply #9 on: August 21, 2015, 10:42:53 am »
Hi,

I have downloaded the contour demo program (project1 + unit1) and it works fine under Linux for me (only on loading there was a warnung - but it seems that you can ignore it).
Now I want to work on it and extend it.
Actually I have many math programs, and used already the delauney algorithm for other applications.

Currently I see contour lines, but can I also get a a true gradient-like plot (without gaps)?
I have many high-dimensional data (like 10 dimensions coming from an optimization) and such contour plotting program would give great insights!!!

Has anybody already made extensions? :)
The jpg in this post seems to indicate this....

Bye Stephan

wp

  • Hero Member
  • *****
  • Posts: 7552
Re: Contour plots with TAChart
« Reply #10 on: August 21, 2015, 11:59:26 am »
You mean filling the chart area by shades of colors according to the data values? If I remember correctly this should be covered in the attachment "Contour & Interpolation.zip" a few posts above.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

 

TinyPortal © 2005-2018