How do I color points from scatter3 (3D scalar field), in accordance with their scalar values?

18 visualizzazioni (ultimi 30 giorni)
Assume BB matrix is a 3D scalar field containing only {-1,1} The piece of code is (not working..) -
BB = reshape(last,[3*nthroot(cubes,3),3*nthroot(cubes,3),3*nthroot(cubes,3)]);
BB(~BB)=-1;
BBB = abs(fftn(BB)).^2;
[row,col,zz]=ind2sub(size(BBB),find(BBB));
map = [1 0 0
1 1 0];
figure
scatter3(col,row,zz,10,'filled','s');
colormap(map)
  3 Commenti
uri iger
uri iger il 7 Ago 2018
Modificato: Stephen23 il 7 Ago 2018
Thanks for the VERY fast reply. I did post the code out of context..
But you got it exactly, I have problems implementing the BBB(,,) value mapping to different colors.
I've "normalized" the BBB matrix to be with values between 0 and 1, and I would like, using scatter3 (maybe using 3 for loops) to map 1 to red, 0 to yellow, and all values in between accordingly.
BBB = abs(fftn(BB)).^2;
BBBB = BBB - min(BBB(:,:,:));
BBBB = BBBB ./ max(BBBB(:,:,:));
figure
for a=1:3*nthroot(cubes,3)
for b=1:3*nthroot(cubes,3)
for c=1:3*nthroot(cubes,3)
g=BBBB(a,b,c);
scatter3(a,b,c,10,colormap(g),'filled','s');
hold on
end
end
end
I understand colormap(g) wont work, and the format is [R,G,B] ? What can I do?
Thanks a lot in advance!! Uri
Adam
Adam il 7 Ago 2018
Modificato: Adam il 7 Ago 2018
Your code was definitely less confusing first time round! Anything that is doing a scatter plot inside 3 nested for loops is almost certain to not be the best way (or a way at all) to do what you want.
If you just want to apply a colourmap to points you may be better off using plot3 with markers and no lines.
But personally I would just create my colourmap of however many points I want between red and yellow (I assume you mean RGB-space interpolation from red to yellow - i.e. green-scale interpolation).
Then there are numerous ways you could map your data onto it. Using
doc histcounts
would do it probably, using the same number of bins as you created elements in your colourmap. This will bin your data giving indices into the colourmap for each point. Then you can just combine these to give the colour argument in RGB for your scatter3 call.

Accedi per commentare.

Risposta accettata

Adam
Adam il 7 Ago 2018
Modificato: Adam il 7 Ago 2018
I don't have time to give full code, but the first option gives you what you need - i.e a single scatter3 instruction, not a massive nested loop. The 5th argument is an n*3 array of colours where n must be the same size as the number of points in your col, row, zz arrays.
Here is some example code you can hopefully adapt to your case:
e.g.
x = rand( 10,1);
y = rand( 10,1);
z = x.^2 + y.^2;
c = rand( 10, 3 ); % 10 random colours
figure; scatter3( x, y, z, [], c, 'filled' )
will give you a simple scatter plot with different coloured points.
Now all you need to do is, instead of creating 10 random colours as I did there, create a colourmap of the required size e.g.
cmap = [ ones( 256, 1 ), linspace( 0, 1, 256 )', zeros( 256, 1 ) ];
Now you have 256 colours between red and yellow. Your data needs to be binned to index into this colourmap though. This is doable by e.g.
a = rand( 1, 100000 ); % Lots of random continuous data
idx = discretize( a, 256 ); % discretise your data into 256 bins;
(In my original comment above I was going to suggest discretize, but missed that it had an option to supply number of bins rather than explicit edges so this is easier than histcounts which doesn't actually bin your data, it just gives the histogram counts as totals).
Then you have all your data in 256 bins and can use those indices into your colourmap.
c = cmap( idx, : );
should do this for you, and then you can use this as 'c' in my above scatter3 line instead of random colours.
  2 Commenti
uri iger
uri iger il 7 Ago 2018
Thanks a lot! Now I even begin t understand what you gave me here.
So I took what you did, and made
cmap = [ ones( 256, 1 ), linspace( 0, 1, 256 )', zeros( 256, 1 ) ];
idx = discretize( BBB(:,:,:), 256 );
colur = cmap( idx, : );
[row,col,zz]=ind2sub(size(BBB),find(BBB));
figure
scatter3(col,row,zz,10,colur,'filled','s');
256 colors seems perfect for my needs. I got the main matrix to hold values inside {1,256}, but still it does not work :/
Any thoughts? Did I misinterpret something? Many thanks again, Uri
Adam
Adam il 7 Ago 2018
Your row, coll and zz values come from the locations where BB is non-zero ( find( BBB ) ) whereas you appear to be discretizing the whole of BBB.
You probably need to pass
BBB(:)
to discretize though to end up with a column vector of indices to pass to the colourmap, rather than a 3d result which will likely not work.

Accedi per commentare.

Più risposte (1)

uri iger
uri iger il 7 Ago 2018
Ok, first - thanks a lot for your help. Second - I'm very confused, and have little (to none) knowledge about matlab and programming.
Could you (or anyone else) please direct me a bit more to the syntax that I need to use? I will simplify the code -
for a=1:knownsize
for b=1:knownsize
for c=1:knownsize
scatter3(a,b,c,10, ??? ,'filled','s');
end
end
end
Previously the scatter3 wasn't in three loops, but it also didnt give me any option as to deal with individual points and their colors (or am I wrong?).
To simplify - I want a 3D scalar field (represented as a 3D matrix) with values between 0 and 1 tobe colored between red and yellow respectively. Would very much appreciate the right syntax in the "scatter3" arguments.
About plot3 - The goal if to show a 3D cube constructed by different colored 1x1x1 small cubes, and I found how to do so with scatter3 and not plot3. am I wrong? is there a simpler way?
Thanks a bunch! Uri

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by