0
votes

I am trying to make a plot with an intensity that varies over time:

[X,Y] = meshgrid(-30:.1:30);
figure;
colormap(bone);


for t = 0:0.1:2*pi
    R = sqrt(X.^2 + Y.^2);
    Z = cos(t)*abs(besselj(2,R));
    surf(Z,'EdgeColor','None');
    view(90,90);
    axis([0 600 0 600 -0.5 0.5])
    pause(0.1);
end

I want to look at this from the top, such that as the Z value changes, the color changes. The problem is that rather than having an absolute scale (black = -0.5, white = 0.5), the color scale is relative to the maximum and minimum values, such that the colors only change when the sign flips change. How can I set an absolute scale for the color map?

Thank you.

2
No, I want to have a gradient. So, it moves from black to white as the value increases. But I want the maximum and minimum values to be fixed. The way it is set up right now, I can see no color change as the intensity decreases. I want to say "at -5, black. At 5, white. In between, a gradient." - Max

2 Answers

1
votes

You have to use scaled colour mapping mode and set the limits of the scaling by using the caxis command.

Now the problem with your current code is that you call surf at each iteration of the loop, essentially destroying the current plot and generating a new plot each time. This will reset a lot of properties, including the caxis limits to auto. To overcome that, simply create your plot only once before the loop, then in the loop you only change the properties which are modified (the Z values in this case). This way everything else stays the same in the figure.

So you code becomes:

%% // Prepare and initialize the surface plot
[X,Y] = meshgrid(-30:.1:30);
R = sqrt(X.^2 + Y.^2) ;         %// this doesn't need to be in the loop

Z = cos(0)*abs(besselj(2,R)) ;                  %// calculate initial value to create the surface
surfHandle = surf( Z , 'EdgeColor','None' ) ;   %// create a first surface, and save the handle to the surface object
colormap(bone);
colorbar                        %// this is optional, just to make sure the colorbar does not vary
caxis([-5 5 ] ) ;               %// this is what sets the color scaling to what you want
view(90,90);
axis([0 600 0 600 -0.5 0.5]) ;  %// this doesn't need to be in the loop anymore

%% // Modify and update the surface plot
for t = 0:pi/100:2*pi
    Z = cos(t)*abs(besselj(2,R));
    set( surfHandle , 'ZData' , Z )
    drawnow
    pause(0.01);
end

Read coloring-mesh-and-surface-plots for more info on how surfaces can be colored.

1
votes

If you just want white for values less than 0 and black for values greater than 0, you ca simply do:

surf(Z,sign(Z),'EdgeColor','None');

which uses the optional C argument to surf, telling Matlab to colour the plot depending on the values of C, not Z. sign(Z) is a matrix that has 1's where Z>0, 0's where Z=0, and -1's where Z<0.