2
votes

I have a surf figure plotting a two dimensional function. I have a loop which changes the z values at each point [x,y] in a meshgrid matrix, in order to animate my plot:

p = surf(x, y, z)
frames = 10/1000

for t = 0:frames:10
    newZ = updateZVal(someArgs)
    set(p, 'ZData', newZ)

This works fine for the most part. However, the color map does not update. Basically the colormap texture of the original z matrix just stays there. The x-y plane moves up and down with changes in newZ, but the color does not.

This exact code works in Matlab, and it works fine in Octave except for this color issue.

Edit: Minimal working example. Little moving gaussian type thing. You can see the color does not update

figure();

x_range = [-2:0.2:2];
y_range = [-2:0.2:2];
[x,y] = meshgrid(x_range, y_range);
frames = 500;
z = (x) .* y;

p = surf(x, y, z);

for t = [0:2/frames:2]
    z = exp(-((((x-t).^2)/2) + (((y-t).^2)/2)));
    set(p, 'ZData', z);
    drawnow;
end
2
That sounds like an interesting problem. If you'd like to provide a minimal working example I'd be happy to have a look. - Tasos Papastylianou
if I had to guess though, I'd say the colour data resides on the CData array. Have a look at the CData / CDataMode / CDataMapping / CDataSource properties - Tasos Papastylianou
How is this possible for t = 0:1000:10? - NKN
@NKN because that expression results in a vector t ranging from 0 to 10 with 1000 steps - pretzlstyle
@NKN woops you're right, I was thinking about it wrong and haven't touched this language in a few months. My problem still stands though, I just typed that wrong in the example here - pretzlstyle

2 Answers

3
votes

tl;dr: change

set(p, 'ZData', z);

to

set(p, 'ZData', z, 'CData', z);


Explanation

Thank you for the minimal working example!

The reason colours don't seem to get auto-updated in octave, is because in matlab the surf object seems to provide an extra property called cdatamode, where cdata is the colour data, and the default value for cdatamode is auto, i.e. automatically update the colour information from the zdata if this changes.

Unfortunately octave does not provide this property, so if you set zdata manually to something else, you also need to manually update the colour information yourself. But, since this is just based on z anyway, all you have to do is update CData with the same values as ZData.

Clearly if you plotted the object from scratch each time you wouldn't have this problem, but doing it your way is preferable because it's much faster and smoother to animate (a lot faster in octave in fact for some reason!), and you don't get redrawing side-effects from having to plot axes again etc, so this is a good question! Many thanks!

1
votes

The problem is that changing Z data does not change the color in the surf plot. Instead you should use a matrix C, assumed to be the same size as Z, to color the surface. See Coloring Mesh and Surface Plots for information on defining C.

Check this example:

[X,Y,Z] = peaks(25);
figure;
p = surf(X,Y,Z,gradient(Z));
for t = 0:1:10
    newZ = Z*rand(size(Z));
    p = surf(X,Y,newZ,gradient(newZ));
    pause(0.5);
end