How to create this kind of plot

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
X-Ray
Newbie
Newbie
Posts: 49
Joined: Fri Jan 27, 2012 12:00 am

How to create this kind of plot

Post by X-Ray » Mon Oct 26, 2015 8:05 am

Hello,

I would like to create this kind of plot with TChart:
SurfaceCapture.PNG
SurfaceCapture.PNG (220.65 KiB) Viewed 15394 times
unfortunately I can't attach the text file with the XYZ data (sph-strain.txt) !?

In Matlab / Octave the graphics is created like this:

m = 60
n = 60
strain = load ("sph-strain.txt"); # sequence of float. i.e: x,y,z …
X = reshape(strain (:,1),m,n); # reshape column1 into matrix 60x60
Y = reshape(strain (:,2),m,n); # .. 2
Z = reshape(strain (:,3),m,n); # .. 3
mesh(X,Y,Z); # call mesh, meshc, surf or surfc with X,Y,Z

I tried to use TTriSurfaceSeries but then I get this:
TChartTTriSurfaceSerieTest.png
TChartTTriSurfaceSerieTest.png (69.58 KiB) Viewed 15391 times
Any Hint what I need to do or how I can upload the text file with the XYZ data ?

best regards,

X-ray

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

Re: How to create this kind of plot

Post by Yeray » Tue Oct 27, 2015 3:54 pm

Hello X-ray,

Have you tried setting the WireFrame property to True as in the Surface example?
surface.png
surface.png (222.33 KiB) Viewed 15418 times
X-Ray wrote:Any Hint what I need to do or how I can upload the text file with the XYZ data ?
Try putting the .txt into a zip.
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

X-Ray
Newbie
Newbie
Posts: 49
Joined: Fri Jan 27, 2012 12:00 am

Re: How to create this kind of plot

Post by X-Ray » Tue Oct 27, 2015 5:42 pm

Hello Yeray,

a TSurfaceSeries doesn't show up at all when adding all the XYZ data and TTriSurfaceSeries doesn't have a WireFrame property.
Here is the XYZ text file put in a ZIP file:
sph-strain.zip
(36.75 KiB) Downloaded 713 times
Maybe you have an idea how to get any decent surface picture from this data using TChart ?

Thank's and best regards,

X-ray

X-Ray
Newbie
Newbie
Posts: 49
Joined: Fri Jan 27, 2012 12:00 am

Re: How to create this kind of plot

Post by X-Ray » Fri Oct 30, 2015 9:33 am

Hello Yeray,

could it be that this data is not suitable for the requirements of TSurfaceSeries?
This is not clear to me, further maybe I can resort the data to make it suitable for this
kind of series, whatever the requirements may be.

best regards,

X-ray

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

Re: How to create this kind of plot

Post by Yeray » Fri Oct 30, 2015 11:46 am

Hello,

Using a TPoint3DSeries gives a better approach for me here with your data:

Code: Select all

uses Series, TeePoin3;

var Series1: TPoint3DSeries;

procedure TForm1.FormCreate(Sender: TObject);
var SeriesTextSource1: TSeriesTextSource;
begin
  Chart1.Legend.Visible:=false;
  Chart1.Aspect.Orthogonal:=false;
  Chart1.Aspect.Zoom:=80;
  Chart1.Chart3DPercent:=100;

  Series1:=Chart1.AddSeries(TPoint3DSeries) as TPoint3DSeries;
  Series1.UseColorRange:=false;
  Series1.UsePalette:=true;
  Series1.OnGetPointerStyle:=Series1GetPointerStyle;

  SeriesTextSource1:=TSeriesTextSource.Create(Self);
  SeriesTextSource1.Automatic:=False;
  SeriesTextSource1.AddField('X',1);
  SeriesTextSource1.AddField('Y',3);
  SeriesTextSource1.AddField('Z',2);
  SeriesTextSource1.FieldSeparator:=#9;
  SeriesTextSource1.FileName:='F:\tmp\sph-strain\sph-strain.txt';
  SeriesTextSource1.Series:=Series1;
  SeriesTextSource1.Active:=true;
end;

function TForm1.Series1GetPointerStyle(Sender:TChartSeries; ValueIndex:Integer):TSeriesPointerStyle;
begin
  Series1.LinePen.Color:=Series1.ValueColor[ValueIndex];
  Result:=psNothing;
end;
Note the SurfaceSeries expects the data to be in a specific format. See the post 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

X-Ray
Newbie
Newbie
Posts: 49
Joined: Fri Jan 27, 2012 12:00 am

Re: How to create this kind of plot

Post by X-Ray » Fri Oct 30, 2015 12:56 pm

Hello Yeray,

That looks great, thank you very much!
The next question is of course if there is any way to show that plot as a surface.
Could I re-order the data somehow (with increasing X, for example) and then put it into a TSurfaceSeries ?

best regards,

X-Ray

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

Re: How to create this kind of plot

Post by Yeray » Fri Oct 30, 2015 4:30 pm

Hello,
X-Ray wrote:The next question is of course if there is any way to show that plot as a surface.
Could I re-order the data somehow (with increasing X, for example) and then put it into a TSurfaceSeries ?
I don't think so. Have you read Narcís' explanation?
Yeray wrote:Note the SurfaceSeries expects the data to be in a specific format. See the post here.
The TSurfaceSeries is drawn using grid (4 point planes) so it requires data to follow a minimum structure.
The TriSurfaceSeries uses triangles (3 point planes) so it's more versatile than the TSurfaceSeries but it doesn't give a good result with your data either.

I see there are 60 points for each segment so it shouldn't be difficult to find what 4 points should be used to draw each cell.
And here it is!
point3D.png
point3D.png (63.39 KiB) Viewed 15305 times
Here the code I used:

Code: Select all

uses Series, TeePoin3, TeeGLCanvas, TeCanvas;

var Series1: TPoint3DSeries;

procedure TForm1.FormCreate(Sender: TObject);
var SeriesTextSource1: TSeriesTextSource;
begin
  Chart1.Canvas:=TGLCanvas.Create;

  Chart1.Legend.Visible:=false;
  Chart1.Aspect.Orthogonal:=false;
  Chart1.Aspect.Zoom:=50;
  Chart1.Chart3DPercent:=100;
  Chart1.Walls.Visible:=false;

  Chart1.Axes.Depth.Visible:=true;
  Chart1.Axes.Bottom.Inverted:=true;
  Chart1.Axes.Depth.Inverted:=true;
  Chart1.Axes.Depth.Increment:=1000;
  Chart1.Axes.Left.Increment:=2000;
  Chart1.Axes.Bottom.Increment:=2000;
  Chart1.Axes.Left.SetMinMax(-6000, 6000);
  Chart1.Axes.Bottom.SetMinMax(-4000, 4000);
  Chart1.Axes.Depth.Grid.Style:=psDash;
  Chart1.Axes.Left.Grid.Style:=psDash;
  Chart1.Axes.Bottom.Grid.Style:=psDash;

  Series1:=Chart1.AddSeries(TPoint3DSeries) as TPoint3DSeries;
  Series1.UseColorRange:=false;
  Series1.UsePalette:=true;
  Series1.OnGetPointerStyle:=Series1GetPointerStyle;

  SeriesTextSource1:=TSeriesTextSource.Create(Self);
  SeriesTextSource1.Automatic:=False;
  SeriesTextSource1.AddField('X',1);
  SeriesTextSource1.AddField('Z',2);
  SeriesTextSource1.AddField('Y',3);
  SeriesTextSource1.FieldSeparator:=#9;
  SeriesTextSource1.FileName:='F:\Downloads\sph-strain\sph-strain.txt';
  SeriesTextSource1.Series:=Series1;
  SeriesTextSource1.Active:=true;
end;

function TForm1.Series1GetPointerStyle(Sender:TChartSeries; ValueIndex:Integer):TSeriesPointerStyle;
var p: array of TPoint3D;
    offset: Integer;
begin
  Series1.LinePen.Color:=Series1.ValueColor[ValueIndex];

  offset:=60;
  if ValueIndex<Sender.Count-offset-2 then
  begin
    SetLength(p, 4);
    p[0].x:=Series1.CalcXPos(ValueIndex);
    p[0].y:=Series1.CalcYPos(ValueIndex);
    p[0].z:=Series1.CalcZPos(ValueIndex);
    p[1].x:=Series1.CalcXPos(ValueIndex+1);
    p[1].y:=Series1.CalcYPos(ValueIndex+1);
    p[1].z:=Series1.CalcZPos(ValueIndex+1);
    p[2].x:=Series1.CalcXPos(ValueIndex+offset+1);
    p[2].y:=Series1.CalcYPos(ValueIndex+offset+1);
    p[2].z:=Series1.CalcZPos(ValueIndex+offset+1);
    p[3].x:=Series1.CalcXPos(ValueIndex+offset);
    p[3].y:=Series1.CalcYPos(ValueIndex+offset);
    p[3].z:=Series1.CalcZPos(ValueIndex+offset);
    Chart1.Canvas.Brush.Color:=clWhite;
    Chart1.Canvas.Pen.Visible:=false;
    Chart1.Canvas.Polygon3D(p);

    Chart1.Canvas.Pen.Visible:=true;
    Chart1.Canvas.Pen.Color:=Series1.LinePen.Color;
    Chart1.Canvas.MoveTo3D(p[0].x, p[0].y, p[0].z);
    Chart1.Canvas.LineTo3D(p[3].x, p[3].y, p[3].z);
  end;

  Result:=psNothing;
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

X-Ray
Newbie
Newbie
Posts: 49
Joined: Fri Jan 27, 2012 12:00 am

Re: How to create this kind of plot

Post by X-Ray » Mon Nov 02, 2015 8:38 am

Hello Yeray,

Great, that piece of code is very useful for other data and cases too.
Thank you very much!

best regards,

X-Ray

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

Re: How to create this kind of plot

Post by Yeray » Mon Nov 02, 2015 9:07 am

Hello,

You're welcome.
I'm glad to hear you find it useful!
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

Post Reply