# Need to make a 4D plot (3D + Colour)

212 views (last 30 days)
Mike on 31 Mar 2012
Commented: anysomeday on 18 Jun 2018
Hi,
I need to make a 3D surface where colour will represent the fourth variable. I know "surf" is SIMILAR to what I need, but that's not quite it. Basically, I have the following variables:
t = [1:m]
y = [1:n]
f = [1:o]
These should be the three Cartesian corodinate axes.
I also have a variable S that is of dimensions m x n x o. I want this to be represented by colour.
So to summarize, I need a graph of the form (t,y,f,S), where the first three variables are vectors of unequal sizes and the final variable is a multidimensional array whose dimensions are determined by the first three.
Thanks in advance. How do I create a

#### 1 Comment

Dahu on 26 Apr 2012
if i am understanding u right, slice should work perfectly for ur application.

Image Analyst on 31 Mar 2012
How about scatter3()? You can set the color and size of the data points that are plotted.
But how can you have unequal lengths of your 3 dimensions?

Image Analyst on 2 Apr 2012
Would TriScatteredInterp() work for your visualization?
Mike on 2 Apr 2012
Possibly. I'm looking into it now. It doesn't seem easy to use, though. The function seems to be more-or-less interchangeable with griddata3. I should summarize where I've come to this point:
First, I read in a set of signals, which are indexed according to space (from 1 to 4). Then, I define a set of scales (a = 1:100), and for each of the signals, I take the continuous wavelet transform using the "wscalogram()" function to yield a matrix of values for each signal: the rows represent time and the columns represent frequency/scales (or possibly vice-versa). These matrices are called sgram1, sgram2, sgram3, and sgram4 (i.e. one for each point in space). The actual values in each entry are the amplitudes. Since I have multiple signals, I index them according to space. I can then concatenate these four matrices into one to yield the multidimensional array "sgram", which is 4x7605x32.
And that's basically where I'm at. I'm also looking into those other programs you suggested in your other comments--hopefully I can easily export data from MATLAB to these programs. I'm also worried about the computations themselves--there's a lot of data to work with (even with very short signals), so the visualization itself is rather slow. =S If I do use these other programs then hopefully that issue should be resolved.
I really appreciate you helping me like this, Image Analyst. Thanks again, so much.
Image Analyst on 2 Apr 2012
MATLAB says this: "TriScatteredInterp is the recommended alternative to griddata as it is generally more efficient."

Jarrod Rivituso on 2 Apr 2012
I'm curious how slice doesn't fit your needs. I'm no data visualization expert so please take this as an honest "I'd like to know more" question :)
t = 1:100:7650;
scales = 1:10:100;
x = 1:4;
[T,SCALES,X] = meshgrid(t,scales,x);
tslice = [];
scalesslice = [];
xslice = 1:4;
SGRAM = T + SCALES + X;
surfHandles = slice(T,SCALES,X,SGRAM,tslice,scalesslice,xslice);
set(surfHandles,'FaceAlpha',0.4,'EdgeAlpha',0.1)
It can look so pretty...
I've always kinda been interested in 4D visualization, so please let us know whatever solution you find :)

Show 1 older comment
Jarrod Rivituso on 3 Apr 2012
Thanks Mike.
Good luck with those other tools (I've never used them).
Also, since you mentioned you were "interested in an object made from the slices", this makes me think scatter3 is more along the lines of what you want. Here's a concrete example for you (see below). Also, it's nice to have someone as responsive as you've been asking questions :)
%Scaled vectors
t = linspace(-3,3,7650);
scales = linspace(-3,3,100);
x = linspace(-3,3,4);
%Decimate
t = t(1:100:7650);
scales = scales(1:10:100);
x = x(1:4);
%Expand independent vectors into 3 dimensional arrays
[T,SCALES,X] = meshgrid(t,scales,x);
%Calculate some fake data
SGRAM = T.^2 + SCALES.^2 + X.^2;
%Remove data that is not within some threshold
SGRAM(SGRAM > 15) = NaN;
SGRAM(SGRAM < 7) = NaN;
%Perform scatter
scatter3(T(:), SCALES(:), X(:), 5*ones(size(X(:))), SGRAM(:))
grid off
bym on 3 Apr 2012
@mike -
Have you checked out isosurface? If you are interested in shapes it may suit your needs
anysomeday on 18 Jun 2018
I met the similar problem, and the data is as follows, the four variables of t, y, f, S all are descrete,and the S is determined by t,y,f,how could I plot them in one gragh? Thank you very much!
t y f S
0.0000001 3600 52000000 0.76
0.000001 3600 52000000 0.76
0.00001 3600 52000000 0.76
0.0001 3600 52000000 0.76
0.001 3600 52000000 0.76
0.01 3600 52000000 0.76
0.1 3600 52000000 0.76
1 3600 52000000 0.76
10 3600 52000000 0.77
100 3600 52000000 0.81
400 3600 52000000 0.82
1000 3600 52000000 0.81
10000 3600 52000000 0.80
100000 3600 52000000 0.80
1000000 3600 52000000 0.79
10000000 3600 52000000 0.79
400 0.0000001 52000000 0.58
400 0.000001 52000000 0.58
400 0.00001 52000000 0.58
400 0.0001 52000000 0.58
400 0.001 52000000 0.58
400 0.01 52000000 0.58
400 0.1 52000000 0.57
400 1 52000000 0.55
400 10 52000000 0.64
400 100 52000000 0.76
400 1000 52000000 0.81
400 3600 52000000 0.82
400 10000 52000000 0.81
400 100000 52000000 0.72
400 1000000 52000000 0.66
400 10000000 52000000 0.62
400 3600 0.0000001 0.00
400 3600 0.000001 0.00
400 3600 0.00001 0.00
400 3600 0.0001 0.00
400 3600 0.001 0.00
400 3600 0.01 0.00
400 3600 0.1 0.00
400 3600 1 0.00
400 3600 10 0.00
400 3600 100 0.22
400 3600 1000 0.66
400 3600 10000 0.67
400 3600 100000 0.72
400 3600 1000000 0.78
400 3600 10000000 0.80
400 3600 52000000 0.82

bym on 31 Mar 2012
have a look at
slice()

#### 1 Comment

Mike on 1 Apr 2012
Hmm, it doesn't seem to be what I need. Thanks anyway, though!

Mike on 1 Apr 2012
I just thought of an idea. What if I scaled the variables appropriately so that their sizes can fit into a function like surf or scatter3D? So currently, the variables are like 32x76050x4. Using linspace or something along those lines, I should be able to make thse guys line up.
Let me give this a try.

Mike on 1 Apr 2012
To add to my previous thought, I was thinking of using the function decimate() to help me. Basically, the initial "amplitude" is a signal that I read in, so it's not automatically "parameterized", so to speak. It's 76050 samples, and using the sampling rate, I can convert that into seconds. I think I can significantly reduce the size of the signal which will definitely speed up computations and file I/O (though obviously it won't be as detailed), but more importantly, if I use that for the amplitude variable combined with "linspace" for some of the other variables then I might be able to "get the sizes of the inputs to agree"--either to the surf function (unlikely), or scatter3 (more likely). Though I'd prefer the surf, really.
I'm mostly thinking aloud at this point. What do you guys think? Seem like a good idea?

Aaditya Kalsi on 1 Apr 2012
I think you may be able to use SURF to get the 3-D data, (use interpolated 't', 'y', 'f', by using TriScatteredInterp) in SURF and then use the fourth dimension (scale appropriately) to set the 'CData' (Color data property) of the resulting SURF object. This may need to be interpolated as well. You may that way plot the points as appropriate and set color using your dataset pretty much as you wanted. Small example:
nPoints = 20;
t = rand(nPoints, 1);
y = rand(nPoints, 1);
f = rand(nPoints, 1);
clr = rand(nPoints, 1);
% to make it compatible with 'CData', replicate columns to give G, B values
clr = repmat(clr, 1, 3);
scatHand = scatter3(t, y, f);
set(scatHand, 'CData', clr);

#### 1 Comment

Mike on 1 Apr 2012
But in this example, don't you have t,y, and f all the same size vector? In my case that's not the reality, and so I'm not sure if I can do this. I'll give it a try, though, and let you know the results.
By the way, I crossposted this question to StackOverflow, and they suggested using scatter3:
http://stackoverflow.com/questions/9960456/matlab-need-to-make-a-4d-plot-3d-colour-color
I still have to try that last suggestion as well.
Thank you for your suggestion, though! Again, I will try it out.

Mike on 1 Apr 2012
I'm not sure if it's exactly the same thing that I want, though. It kind of sucks to know that MATLAB simply can't do what I want (if it is true--and if so, I wish I knew this before), but I'm downloading Amira now, so hopefully this will help. We'll see.

Image Analyst on 1 Apr 2012
MATLAB's 3D visualization capabilities are relatively weak. If you want to do true 3D volume visualization, you'll need Amira or Avizo. They're very powerful.
Mike on 2 Apr 2012
OK, I downloaded the trial versions of both of those programs, and it seems to be working fine, including the integration with MATLAB.
The problem is that I'm not familiar with these programs (which actually seem to be quite similar to each other), so I'm still not sure exactly how to get what I want. Still, I feel like I'm very close to the solution! In my pool right now I have the following variables:
t (1 x 76050 x 1)
scales (1 x 100 x 1)
x (1 x 4 x 1)
sgram1 (100 x 76050 x 1)
sgram2 (100 x 76050 x 1)
sgram3 (100 x 76050 x 1)
sgram4 (100 x 76050 x 1)
sgram (100 x 76050 x 4)
So, I want "t", "x", and "scales" to define the axes and "sgram's" coordinates to be the colour. Basically, the same as before, except I have these powerful new tools under my belt--I'm just not sure how to use them.

Kye Taylor on 3 Apr 2012
I take it that the four dimensions are the four different indices you are using to index your signals? If so, why would you treat these as coordinates in space. Typically, energy densities, such as that returned by wscaleogram, are visualized as images. In your case, you would want to look at four different images. What am I missing?
Check out Jarrod Rivituso's code above for an interesting way to display 4 such images.
Furthermore, I would double check how you're arriving at the dimensions 7605x32. (32 is likely scales, not 100, and 7605 is likely the length of your longest signal) No?

Mike on 3 Apr 2012
Yeah, sorry, I keep going back and forth between 100 scales and 32 scales. For now I am keeping it 32 scales and 7605 time samples (I just truncated it by a factor of 10--with a sampling rate of 480 Hz, it's now about 15 seconds rather than 150), because I need to minimize the amount of data for practical computations.
But yeah, that's basically it. You get a typical scaleogram from wscaleogram, which consists of time on the x-axis and scales on the y-axis, with color representing amplitude. Now I have that, in addition to a spatial dimension to index each individual signal that gets fed into the scaleogram function.
I'll take another look at his code. For now I've been playing around with Avizo, though I'm running into problems here as well due to my unfamiliarity with the software.
Image Analyst on 3 Apr 2012
I think he has 3 independent variables: time, scale, and space, and one dependent variable: "value of the amplitude" so it's a 3D array. See the first two comments to my answer.