Как обновить данные графика и цветовую карту в Octave?

У меня есть фигура surf, отображающая двумерную функцию. У меня есть цикл, который изменяет значения z в каждой точке [x,y] в матрице meshgrid, чтобы оживить мой график:

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

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

Это отлично работает по большей части. Однако карта цветов не обновляется. По сути, текстура цветовой карты исходной матрицы z просто остается там. Плоскость x-y перемещается вверх и вниз при изменении newZ, а цвет - нет.

Этот точный код работает в Matlab и отлично работает в Octave, за исключением этой проблемы с цветом.

Изменить: минимальный рабочий пример. Маленькая движущаяся штука типа Гаусса. Вы можете видеть, что цвет не обновляется

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

person pretzlstyle    schedule 26.08.2016    source источник
comment
Это звучит как интересная проблема. Если вы хотите предоставить минимальный рабочий пример, я был бы рад взглянуть.   -  person Tasos Papastylianou    schedule 27.08.2016
comment
если бы мне пришлось угадывать, я бы сказал, что данные о цвете находятся в массиве CData. Взгляните на свойства CData/CDataMode/CDataMapping/CDataSource.   -  person Tasos Papastylianou    schedule 27.08.2016
comment
Как это возможно for t = 0:1000:10?   -  person NKN    schedule 27.08.2016
comment
@NKN, потому что это выражение приводит к вектору t в диапазоне от 0 до 10 с 1000 шагами   -  person pretzlstyle    schedule 27.08.2016
comment
@NKN упс, ты прав, я думал об этом неправильно и не прикасался к этому языку несколько месяцев. Моя проблема все еще остается в силе, я просто неправильно набрал это в примере здесь   -  person pretzlstyle    schedule 27.08.2016
comment
@TasosPapastylianou Смотрите мою правку   -  person pretzlstyle    schedule 27.08.2016
comment
Боже, ты создал мексиканскую волну! это потрясающе! сделайте так, чтобы петля начиналась с -2 и шла от края до края! \о/   -  person Tasos Papastylianou    schedule 27.08.2016
comment
@jphollowed просто из любопытства: вы хотите создать гифку или видео в конце?   -  person Andy    schedule 27.08.2016
comment
@jphollowed и действительно ли t = 0:1000:10 дает что-то еще, кроме 0 в Matlab?   -  person Andy    schedule 27.08.2016
comment
@ Энди Нет, как я уже сказал, это была ошибка. А можно гифку   -  person pretzlstyle    schedule 27.08.2016


Ответы (2)


tl;dr: изменить

set(p, 'ZData', z);

to

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


Пояснение:

Спасибо за минимальный рабочий пример!

Причина, по которой цвета не обновляются автоматически в октаве, заключается в том, что в Matlab объект серфинга, кажется, предоставляет дополнительное свойство, называемое cdatamode, где cdata — это данные цвета, а значение по умолчанию для cdatamode равно auto, т.е. автоматически обновляется информация о цвете из zdata, если это изменится.

К сожалению, octave не предоставляет этого свойства, поэтому, если вы установите zdata вручную на что-то другое, вам также потребуется вручную обновить информацию о цвете. Но, так как это в любом случае основано на z, все, что вам нужно сделать, это обновить CData теми же значениями, что и ZData.

Очевидно, что если бы вы рисовали объект с нуля каждый раз, у вас не было бы этой проблемы, но делать это по-своему предпочтительнее, потому что это намного быстрее и плавнее анимировать (на самом деле намного быстрее в октаве для некоторых причина!), и вы не получаете побочных эффектов перерисовки из-за необходимости снова рисовать оси и т. д., так что это хороший вопрос! Большое спасибо!

person Tasos Papastylianou    schedule 27.08.2016
comment
Команда octave обычно рассматривает такие отклонения от Matlab как ошибки, поскольку они стремятся к тому, чтобы язык был полностью совместимым, поэтому я рекомендую вам заявить об ошибке :) - person Tasos Papastylianou; 27.08.2016

Проблема в том, что изменение данных Z не меняет цвет на графике серфинга. Вместо этого вы должны использовать матрицу C, предположительно того же размера, что и Z, для окрашивания поверхности. См. раздел Раскрашивание сетки и графики поверхности. сведения об определении С.

Проверьте этот пример:

[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
person NKN    schedule 26.08.2016