Page 1 of 1
How to create this kind of plot
Posted: Mon Oct 26, 2015 8:05 am
by 16561419
Hello,
I would like to create this kind of plot with TChart:
- SurfaceCapture.PNG (220.65 KiB) Viewed 16961 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 (69.58 KiB) Viewed 16958 times
Any Hint what I need to do or how I can upload the text file with the XYZ data ?
best regards,
X-ray
Re: How to create this kind of plot
Posted: Tue Oct 27, 2015 3:54 pm
by yeray
Hello X-ray,
Have you tried setting the
WireFrame property to True as in the Surface example?
- surface.png (222.33 KiB) Viewed 16985 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.
Re: How to create this kind of plot
Posted: Tue Oct 27, 2015 5:42 pm
by 16561419
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:
Maybe you have an idea how to get any decent surface picture from this data using TChart ?
Thank's and best regards,
X-ray
Re: How to create this kind of plot
Posted: Fri Oct 30, 2015 9:33 am
by 16561419
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
Re: How to create this kind of plot
Posted: Fri Oct 30, 2015 11:46 am
by yeray
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.
Re: How to create this kind of plot
Posted: Fri Oct 30, 2015 12:56 pm
by 16561419
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
Re: How to create this kind of plot
Posted: Fri Oct 30, 2015 4:30 pm
by yeray
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 (63.39 KiB) Viewed 16872 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;
Re: How to create this kind of plot
Posted: Mon Nov 02, 2015 8:38 am
by 16561419
Hello Yeray,
Great, that piece of code is very useful for other data and cases too.
Thank you very much!
best regards,
X-Ray
Re: How to create this kind of plot
Posted: Mon Nov 02, 2015 9:07 am
by yeray
Hello,
You're welcome.
I'm glad to hear you find it useful!