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!
You can do the Import with using :
data = Import["file.dat","Table"]
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
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] ]
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[%]
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.
I have uploaded one of the dat files onto dropbox - https://www.dropbox.com/s/r6jbko4elemeofk/ana1Tdel1_scan65_391_511.dat
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]
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?
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]




