Message Boards Message Boards

2
|
20296 Views
|
10 Replies
|
12 Total Likes
View groups...
Share
Share this post:

How to plot {x,y,z,i} data?

Posted 11 years ago
Hello there, I have data (in a .dat file) which consists of four columns. x, y, z are coordinates in 3D and i which is the measured intensity at the point defined by xyz. The data is continuous and should give some form of a 3D peak type shape. Thanks!
POSTED BY: Anna Regoutz
10 Replies
I just realized that your data have 500,000 points and most of them cary no meaningful information because of almost zero "background" intensity. I would suggest filtering data based on higher intensity - and plotting only those. Something like the following.
filt = Select[data, 100 < #[[4]] &];

filt // Length
Out[] = 6867

Now for better rescaling of opacity and color find min-max range only this filtered data set:
rng = {Min[#], Max[#]} &@filt[[All, 4]]
Out[] = {100.053, 2340.44}

Now plot:
Graphics3D[{PointSize[.02], ColorData["Rainbow"][Rescale[#[[4]], rng]],
    Opacity[Rescale[#[[4]], rng]], Point[#[[1 ;; 3]]]} & /@ filt, Axes -> True, BoxRatios -> 1]

POSTED BY: Darya Aleinikava
Import your data
data = Import["ana.dat"][[2 ;; -1]];

- we dropped 1st line because it is empty. Find max and min for intensity
{Min[#], Max[#]} &@data[[All, 4]]
Out[] = {0., 2340.44}

Associate it with Opacity and plot
Graphics3D[{Opacity[Rescale[#[[4]], {0, 2340.438}]], Point[#[[1 ;; 3]]]} & /@ data, Axes -> True, BoxRatios -> Automatic]

POSTED BY: Darya Aleinikava
Posted 11 years ago
Thank you! This looks really good. One more question: Is there any way to colour the dots depending on the density? Like a temperature map where blue is low intensity, red is high intensity?
POSTED BY: Anna Regoutz
Anna without actual data file that you use it is hard to figure out the best strategy. Could you upload the file somewhere and give us the URL? You could use Dropbox to upload the full file or for example Gist to simply paste the data. Any of these or similar services would work. 
POSTED BY: Moderation Team
Posted 11 years ago
I have uploaded one of the dat files onto dropbox - https://www.dropbox.com/s/r6jbko4elemeofk/ana1Tdel1_scan65_391_511.dat
POSTED BY: Anna Regoutz
Posted 11 years ago
Thanks for all your ideas! I tried ListContourPlot3D and it gives me the following error message "ListContourPlot3D::gmat1: -- Message text not found --". The other plots look very nice but don't work for what I want to show. To give some more detail: The data I have is X-ray diffraction data in reciprocal space. We map the area around a Bragg reflection and want to plot the peak as a 3D coloured map. x, y, and z are the Miller indizes h, k, and l, and i is the intensity the detector measures at a certain hkl point in reciprocal space. So it would be nice to have a surface of all the points and colour it in according to the intensity.
POSTED BY: Anna Regoutz
@Anna, 

You can also use customized bubble chart to visualize a 5-dimensional data. Example: The following function works for data points like
point = {0.86882, 1.9605, 1.82299, 0.222908, 1.09061}

The first two elements are the x-y coordinates; the third element is the radius of a bubble; the fourth element is the hollowness of a bubble; the last element determines the color scale. CustomizedBubble is a sample implementation. Note that the last three values are nomalized in visualization.  An option is added so I can toggle between two bubble styles: disk and ring
 CustomizedBubble::optf = "the option value is not defined";
 Options[CustomizedBubble]={"BubbleStyle"-> "Disk"};
 CustomizedBubble[ls_,opts:ptionsPattern[]]:=Module[
    {minVal3,maxVal3,minVal4,maxVal4,minVal5,maxVal5,r3,r4,hue5,res,p,bstyle},
    (*Normalize the 3rd, 4th and 5th element in a list*)
    {minVal3,maxVal3}=Through[{Min,Max}[data[[All,3]]]];
    {minVal4,maxVal4}=Through[{Min,Max}[data[[All,4]]]];
    {minVal5,maxVal5}=Through[{Min,Max}[data[[All,5]]]];
    r3=(ls[[3]]-minVal3)/(maxVal3-minVal3)*0.2;
   r4=(ls[[4]]-minVal4)/(maxVal4-minVal4)*r3;
   hue5=(ls[[5]]-minVal5)/(maxVal5-minVal5);
   (*check the style*)
   bstyle=OptionValue["BubbleStyle"];
   Which[
      bstyle==="Disk",
      r4=r4*0.8;
      {
        {Hue[hue5,1,.7,.9],Disk[{ls[[1]],ls[[2]]},r3]},{White,Disk[{ls[[1]],ls[[2]]},r4]}
      },
      bstyle==="Ring",
      r4=r4*0.4;
      {Hue[hue5,0.8,.9,0.8],Thickness[r4],Circle[{ls[[1]],ls[[2]]},r3]},
      True, Message[CustomizedBubble::optf];{}
   ]
];

I generate some random data (for instance, a set of 60 "5-d" points) and apply the above function onto the points:
data = RandomReal[{0, 2}, {60, 5}];

I put a Sort function here to make sure that smaller circles are always atop the larger ones. Otherwise I can not see the circles with small radii
CustomizedBubble /@ Sort[data, (#1[[3]] > #2[[3]]) &];
Graphics[%]

The result is quite charming: 

I can draw a similar graph with rings (the center is transparent) with "BubbleStyle" -> "Rings" option. This time the fourth element determines the thickness of a ring. 
CustomizedBubble[#, "BubbleStyle" -> "Ring"] & /@ Sort[data, (#1[[3]] > #2[[3]]) &];
Graphics[%]

POSTED BY: Shenghui Yang
Adding the fourth dimension is usually done with color. That is hard to incorporate in the {x,y,z}-type plots.

Sample Data (as if already Imported):
dat = Table[ {x,y, 1./(1+x^2+y^2), RandomInteger[4]}, {x,-2,2},{y,-2,2}];
dat = Flatten[dat ,1];

ListPlot3D or ListPointPlot works for the {x,y,z} coordinates. They have lots of options.

Here I write a function that turns each 4-tuple into a colored point.  First, get the range of the intensities.
{minInt, maxInt} = Through[{Min, Max}[dat[[All, 4]] ] ]

toPoint[{x_, y_, z_, int_}] := {
  ColorData["Rainbow"][(int - minInt)/(maxInt - minInt)],
  PointSize[0.04], Point[{x, y, z}]}

Run the toPoint function over the data to make the list of Points.
Then show the points embedded in a surface.
pts = Map[ toPoint, dat] ;

Show[ ListPlot3D[ dat[[All, 1 ;; 3]],
  ColorFunction -> Function[{x, y, z}, {Gray, Opacity[0.2]}] ],
Graphics3D[pts] ]
POSTED BY: Bruce Miller
Anna,

Depending on how your data is: if the data completely fills the domain (multiple z for every x,y position), then you should try:
ListContourPlot3D

If it is just a single values for each x,y position then you could use ListContourPlot or ListDensityPlot or ListPlot3D.

Regards --SH
POSTED BY: Sander Huisman
You can do the Import with using :
data = Import["file.dat","Table"]
POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract