Динамична легенда (Актуализации при всяка рекурсия)

Имам for i=1:15. Вътре генерирам променлива d=1:0.01:10, която е оста x'x и въз основа на това създавам непрекъсната функция F(d), която има 2 уникални променливи pitch и yaw. След това начертавам това, използвайки различни цветове във всяка рекурсия, използвайки 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

В случай, че някой има същия проблем, следните стъпки коригираха проблема

  1. Деинсталирайте Anaconda
  2. Инсталирайте Anaconda
  3. Инсталирайте pystan с помощта на pip

Нямам идея защо това работи.

- 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 като свой собствен клас, а не като набор от други графични обекти. Това малко изчисти нещата, така че взаимодействието с тях е по-лесно.

Въпреки че тези нови 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)

step1

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

Например:

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