Динамическая легенда (обновляется при каждой рекурсии)

Я получил for i=1:15. Внутри я генерирую переменную d=1:0.01:10, которая представляет собой ось x'x, и на ее основе я создаю непрерывную функцию F(d), которая имеет 2 уникальные переменные шага и рыскания. Затем я рисую это, используя разные цвета в каждой рекурсии, используя cmap = hsv(15);. Итак, это:

d=1:0.01:10;
cmap = hsv(15);

for i=1:15
    pitch = unidrnd(10);
    yaw   = unidrnd(10);

    for j=1:length(d)
        F(j) = d(j)*3*pitch*yaw; %// some long calculation here
    end

    p1 = plot(d,F,'Linewidth', 1.0);
    title ('blah blah')
    set(p1, 'Color', cmap(i,:));
    hold on;
    legend (['pitch,yaw:', num2str(pitch) num2str(yaw)]) 
end 
hold off;

Этот код обновляет уникальные значения шага и рыскания в каждой рекурсии (без пробела между ними, что немного раздражает), но не может:

  1. Примените правильный цвет, видимый на рисунке.
  2. Удерживайте цвет из предыдущей итерации и значения pitch,yaw.

person Kots    schedule 10.02.2014    source источник
comment
Не уверен, что вы хотите сделать, но drawnow в конец каждой итерации может быть полезен   -  person Luis Mendo    schedule 10.02.2014
comment
К сожалению, drawnow ничего не меняет.   -  person Kots    schedule 10.02.2014


Ответы (3)


Полудокументированное решение

Добавление строк в легенду в цикле может быть выполнено с помощью «динамических легенд», как описано на undocumentedmatlab.com.

Идея состоит в том, чтобы заменить команду legend на:

legend('-DynamicLegend');

Затем обновите команду plot с параметром DisplayName:

plot(d,F,'Linewidth',1.0,'DisplayName',sprintf('pitch,yaw: %d,%d',pitch,yaw));

Затем в легенду добавляются графики, добавленные к осям:

введите здесь описание изображения

Если вам не нравятся полудокументированные функции, используйте трюк DisplayName и просто включите/выключите legend. То есть вместо -DynamicLegend:

legend('off'); legend('show');

другой вариант, который не использует ни DisplayName, ни -DynamicLegend, заключается в удалении и воссоздании легенды с массивом сохраненных строк.

Официальное решение

официальное решение, рекомендованное MathWorks, поэтому возьмите существующие дескрипторы строк легенды и вручную обновите легенду с помощью этих дескрипторов. Это довольно болезненно по сравнению с решением динамической легенды выше:

% Get object handles
[LEGH,OBJH,OUTH,OUTM] = legend;

% Add object with new handle and new legend string to legend
legend([OUTH;p1],OUTM{:},sprintf('pitch,yaw: %d,%d',pitch,yaw))
person chappjc    schedule 10.02.2014
comment
Потрясающее использование .gif! - person jerad; 10.02.2014
comment
Это работает с цветами, но я не могу добавить нужные значения вместо слова data%d. +1 за .gif, хотя! - person Kots; 10.02.2014
comment
Для этого есть метод ('DisplayName), обновленный. - person chappjc; 10.02.2014
comment
Отлично. Также обратите внимание, что вы можете указать цвет в команде plot: p1=plot(d,F,'Linewidth', 1.0,'DisplayName', sprintf('pitch,yaw: %d,%d',pitch,yaw), 'Color', cmap(i,:)); - person chappjc; 10.02.2014
comment
Святые $*!(#*!. Я не знал, что в MATLAB есть динамические легенды. Также +1 за использование .gif. - person rayryeng; 15.05.2014
comment
Приведенная выше ссылка mathworks.com/support/solutions/en/data/ 1-181SJ не работает. :-( - person Danijel; 22.09.2016
comment
Я расширил дело о динамической легенде одного графика здесь stackoverflow.com/q/39807194/54964 - person Léo Léopold Hertz 준영; 01.10.2016

В качестве альтернативы HG2 (по умолчанию в R2014+) официальному решению MW @chappjc можно воспользоваться повторной реализацией легенды как собственного класса, а не кучей других графических объектов. Это немного очистило вещи, поэтому с ними проще взаимодействовать.

Хотя эти новые legend объекты не имеют ссылки на открытое свойство элементы легенды к нанесенным объектам, у них есть такое свойство, 'PlotChildren', которое представляет собой массив дескрипторов объекта.

Например:

x = 1:10;
y1 = x;
y2 = x + 1;

figure
plot(x, y1, 'ro', x, y2, 'bs');
lh = legend({'Circle', 'Square'}, 'Location', 'NorthWest');

pc = lh.PlotChildren

Возвращает:

pc = 

  2x1 Line array:

  Line    (Circle)
  Line    (Square)

шаг1

Чтобы обновить наш объект legend без повторного вызова legend, мы можем изменить свойства 'PlotChildren' и 'String' нашего существующего объекта legend. Пока для каждого объекта в 'PlotChildren' есть запись 'String', она будет отображаться в легенде.

Например:

y3 = x + 2;
hold on
plot(x, y3, 'gp');

% To make sure we target the right axes, pull the legend's PlotChildren 
% and get the parent axes object
parentaxes = lh.PlotChildren(1).Parent;

% Get new plot object handles from parent axes
newplothandles = flipud(parentaxes.Children); % Flip so order matches

% Generate new legend string
newlegendstr = [lh.String 'Pentagram'];

% Update legend
lh.PlotChildren = newplothandles;
lh.String = newlegendstr;

Что возвращает:

ура


Эта функциональность может быть заключена в общую вспомогательную функцию для поддержки добавления одной или нескольких записей легенды. Мы сделали это с помощью legtools на GitHub.

person excaza    schedule 22.09.2016

По состоянию на MATLAB 2017a легенды обновляются автоматически при добавлении или удалении графических объектов.

Таким образом, ничего конкретного сейчас делать не нужно. Создается легенда, затем в цикле можно добавить линии к осям, и они автоматически появятся в легенде.

person Cris Luengo    schedule 04.08.2019