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

Posted 10 years ago
19125 Views
|
10 Replies
|
12 Total Likes
|
 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!
10 Replies
Sort By:
Posted 10 years ago
 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 // LengthOut[] = 6867Now 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 10 years ago
 Import your datadata = 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 plotGraphics3D[{Opacity[Rescale[#[[4]], {0, 2340.438}]], Point[#[[1 ;; 3]]]} & /@ data, Axes -> True, BoxRatios -> Automatic]
Posted 10 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 10 years ago
 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 10 years ago
 I have uploaded one of the dat files onto dropbox - https://www.dropbox.com/s/r6jbko4elemeofk/ana1Tdel1_scan65_391_511.dat
Posted 10 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 10 years ago
 @Anna, You can also use customized bubble chart to visualize a 5-dimensional data. Example: The following function works for data points likepoint = {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 radiiCustomizedBubble /@ 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 10 years ago
 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 10 years ago
 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:ListContourPlot3DIf it is just a single values for each x,y position then you could use ListContourPlot or ListDensityPlot or ListPlot3D.Regards --SH
Posted 10 years ago
 You can do the Import with using :data = Import["file.dat","Table"]