0
$\begingroup$

How can I plot 4d data from a csv, using a slider for the 4th variable? I would like to use var1 and var2 as x-y corrdinates, var3 as surface height, and var4 as the time slider.

If I have a csv dat.csv like this:

x y z t
1.2 2.2 3.0 -3.2
2.1 -1.0 3.1 2.3
3.1 -2.0 3.2 0.1
...

How can I plot this data as a 3-d surface plot with the 4th variable as a time slider? Here is an analogous example I found for a defined function: Manipulate[Plot3D[f[x, y, z], {x, 1, 10}, {y, 1, 10}], {z, 1, 10}]

$\endgroup$
4
  • $\begingroup$ This is two separate questions. First you need to have the csv data parsed into a Mathematica array (List, or some other data structure). Look here and here. Then you might use something like Manipulate[ListPlot3D[data],{z,zmin,zmax}]. $\endgroup$ – Jess Riedel Jun 1 '16 at 4:28
  • $\begingroup$ Whoops, in that example, data should have z dependence. If z is something besides the positive integers, use an integer k Manipulate[ListPlot3D[ data[[k]] ],{k,kmin,kmax}]. I suggest structuring the data as data=Table[{{x,y,f[x,y,z[k]]},{k,kmin,kmax}]. $\endgroup$ – Jess Riedel Jun 1 '16 at 4:41
  • $\begingroup$ Thanks @JessRiedel! I updated my example to have negatives and decimals. $\endgroup$ – kilojoules Jun 1 '16 at 5:48
  • $\begingroup$ Kilojoules, would you please expand further on what exactly you mean by using "the 4th variable as a slider"? Perhaps you could explain why the answer you received is not yet satisfactory, and provide a larger data set for people to play with as they attempt to answer your question. $\endgroup$ – MarcoB Jun 3 '16 at 21:43
4
+50
$\begingroup$

This is dummy data that I hope is illustrative.

data = Flatten[
   Table[{i, j, Sin[m i] Cos[m j ], m}, {i, 0, 2 Pi, 0.1}, {j, 0, 
     2 Pi, 0.1}, {m , 0, 1, 0.01}], 2];
g = #[[All, 1 ;; 3]] & /@ GatherBy[data, #[[4]] &];
lp = ListPlot3D[##, Mesh -> None, Boxed -> False, 
     Background -> Black,Axes -> False, PlotRange -> {-1, 1}] & /@ g;

lp was exported as animated gif:

enter image description here

You could use Interpolation for the slider:

ip = Interpolation[{{#1, #2, #4}, #3} & @@@ data]
Manipulate[
 Plot3D[ip[x, y, t], {x, 0 , 2 Pi}, {y, 0, 2 Pi}, 
  PlotRange -> {-1, 1}, Mesh -> False], {t, 0, 1}]

enter image description here

This dummy data uses regular intervals. I do not know the context or the data but perhaps this may be helpful.

$\endgroup$
2
$\begingroup$

It's difficult to tell what your data actually look like e.g. are z values unique etc. But here's a crack at it:

(*Generate some fake data based on a function of x,y,z*)
f[x_, y_, z_] := {Re@Exp[I*z]*Sin[x]*Cos[y]*100, x, y, z*100};
d = f[##] & @@@ RandomReal[{-1, 1}, {10, 3}];

(*Export it to a CSV file with a header.*)
Export[
  FileNameJoin@{$TemporaryDirectory, "test.txt"},
  Prepend[d, {"f", "x", "y", "z"}],
  "CSV"
  ];

(*Import it, telling MMA that it's a CSV file.*)
d = Import[
   FileNameJoin@{$TemporaryDirectory, "test.txt"}
   , "CSV"
   ];
d = Rest@d; (*Drop the header.*)
d = {#2, #3, #1, #4} & @@@ d;(* Re-order data as: {x,y,f[x,y,z],z} *)
(*Get the plot limits.*)
limits = {Min@#, Max@#} & /@ (Transpose@d);

Since I don't know if your data have unique z values, I just sort by z then gather by z. The entire dataset is now split into sublists each with the same z value. I then plot all the points for a given z, as {x,y,f}, and provide a slider to move through the sublists. The plot title tells you the z value.

 Manipulate[
 Module[
  {dnew = GatherBy[SortBy[d, Last], Last]},
  Show[
   ListPointPlot3D[
    Most[#] & /@ dnew[[z]]
    , PlotRange -> Most@limits
    , Filling -> Bottom
    , PlotLabel -> 
     "z = " <> ToString[First@DeleteDuplicates[Last /@ dnew[[z]]]]
    ]
   ]
  ]
 , {z, 1, Length@dnew, 1}
 ]

enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you. This is not quite what I meant. I want to make this data into a 3-d surface plot with a time slider. I also want to read the data from an external file dat.csv. $\endgroup$ – kilojoules Jun 3 '16 at 23:43
  • $\begingroup$ 1) You can't make a 3D surface plot unless you have many points at the same time, but this will approximate that if your file does end up having many points at the same time; you can always replace ListPointPlot3D with ListPlot3D, but that will complain if you only have one point at some time step. 2) Just change the file name under 'Import', I made my own file since you didn't give us anything to work with. $\endgroup$ – N.J.Evans Jun 6 '16 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.