Matlab: изменить порядок записей в легенде рисунка

У меня есть файл рисунка, в котором я хотел бы изменить порядок записей (например, поставить первую запись как третью). Я сохранил этот Figure.fig давным-давно, поэтому не уверен, смогу ли я восстановить исходный код.

Здесь я показываю вам свой сюжет:

Мой сюжет

Я хочу, чтобы элементы легенды располагались в порядке убывания (как на картинке), но из-за ошибки моя вторая запись относится к неправильному графику (там написано «25 лет», но на самом деле график относится к самой низкой тенденции, соответствующей к тренду «9 лет»).

Могу ли я изменить порядок записей в легенде непосредственно из редактора свойств рисунка в Matlab? Если да, то как (я не видел свойства "Заказ" или аналогичного)? В противном случае, есть ли другой простой способ изменить порядок записей в легенде?


person Patapunfate    schedule 23.08.2016    source источник
comment
Если вы загрузите рисунок, не могли бы вы просто снова выполнить legend с новым порядком записей?   -  person Sembei Norimaki    schedule 23.08.2016
comment
Какая версия MATLAB?   -  person excaza    schedule 23.08.2016
comment
Это Matlab R2015b   -  person Patapunfate    schedule 23.08.2016
comment
Эта цифра также была получена в R2015b?   -  person excaza    schedule 23.08.2016
comment
Да, я почти уверен, что это было   -  person Patapunfate    schedule 23.08.2016


Ответы (4)


Если ваша фигура была создана в R2014b или новее, вы можете использовать недокументированное свойство 'PlotChildren' для управления порядком записей легенды, не требуя нового _ 2_ вызов.

Например:

x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;

plot(x, y1, x, y2, x, y3, x, y4);
lh = legend('y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2');

Производит:

start

Чем вы затем можете манипулировать:

neworder = [3, 1, 4, 2];
lh.PlotChildren = lh.PlotChildren(neworder);

Производство:

ура

Если у вас нет дескриптора объекта legend, это дочерний элемент figure, содержащий объект axes, на котором отображаются ваши данные . Вы можете найти дескриптор вашего legend объекта, используя один из следующих findobj подходы:

% Handle to figure object known
lg = findobj(figureobj, 'Type', 'legend');

% Handle to figure object unknown
lh = findobj(gcf, 'Type', 'legend');

Обратите внимание, что gcf обычно возвращает дескриптор для последняя цифра, на которую щелкнул пользователь, но это не всегда так.


Редактирование саморекламы: этот метод включен в набор инструментов для работы с легендой, поддерживаемых на GitHub сообществом StackOverflow MATLAB.

person excaza    schedule 23.08.2016
comment
Есть ли особая причина избегать повторного вызова legend и вместо этого использовать недокументированную функцию? - person Sembei Norimaki; 23.08.2016
comment
@SembeiNorimaki, потому что он поддерживает связь между линейной серией и записью легенды. - person excaza; 23.08.2016
comment
Отлично! Однако мне не удается заставить это работать в R2017a или b. Назначение дочерних элементов в новом порядке ничего не делает (также при использовании метода set). Он по-прежнему отлично работает в R2016b. Любые идеи? - person Emil; 12.07.2017
comment
Привет, @Emil, к сожалению, улучшения графического движка, представленные в R2017a нарушили большую часть этой функциональности. Одна из опасностей работы с недокументированным функционалом; К сожалению, у меня еще не было времени исследовать альтернативные методы. - person excaza; 12.07.2017

Другой альтернативой для тех, кто использует версию MATLAB, более раннюю, чем R2014b, является получение дескрипторов объектов графика путем указания вывода на plot. Затем вы можете переставить маркеры в желаемом порядке перед их передачей в legend.

x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;

hplots = plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};

% Indices specifying the order in which you want the legend entries to appear
neworder = [3 1 4 2];
legend(hplots(neworder), labels(neworder));

Обновить

Для правильной обработки при загрузке из файла вы можете получить все Children осей, чтобы получить объекты графика, и получить текущую легенду, чтобы получить метки. Затем вы можете изменить их порядок, как описано выше.

load('filename.fig');

labels = get(legend(), 'String');
plots = flipud(get(gca, 'children'));

% Now re-create the legend
neworder = [3 1 4 2];
legend(plots(neworder), labels(neworder))
person Suever    schedule 23.08.2016

Я нашел решение Matlab R2020, которое можно использовать для изменения порядка записей легенды без нарушения порядка, в котором они отображаются друг на друге. Я нашел его в https://matplotlib.org/1.3.1/users/legend_guide.html, и это действительно просто, все, что вам нужно сделать, это позвонить

legend([p2, p1], ["line 2", "line 1"])

с p1 - это линейный объект, созданный при построении p1 = plot (...), и вместе с uistack я могу изменить, какие объекты будут отображаться поверх которых, но затем переупорядочить легенду, чтобы она имела смысл. Пример

uistack(psave_d,'top') % Brings certain line to front
legend([psave_a, psave_b, psave_g, psave_c, psave_d, psave_e, psave_f, psave_pde], ["k_y=0.000001 W/m/K","k_y=0.0001 W/m/K","k_y=0.001 W/m/K","k_y=0.01 W/m/K","k_y=0.1 W/m/K","k_y=1 W/m/K","k_y=10 W/m/K","Isothermal PDE Numerical Model"])

Если кому-то понадобится более подробная информация, я с радостью могу ее предоставить. Ваше здоровье

person Kyle Marquis    schedule 19.09.2020

Основываясь на моем опыте и комментариях в другом месте к ответу excaza, кажется, что их решение с использованием недокументированной функции может больше не работать за пределами R2017a.

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

Например,

x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};
legend(labels)

Производит,  График с исходным порядком легенды

Получение графических дескрипторов позволяет воссоздать легенду в другом порядке,

neworder = [3, 1, 4, 2];
ax = gca;
children = ax.Children;
legend(children(neworder), labels(neworder))

Изменяет предыдущий сюжет, производя,

График с измененным порядком легенды

Обратите внимание, что в отличие от другого ответа на аналогичный вопрос, это не требует явного возврата дескрипторов графики по мере их построения и отслеживания их. Ручки просто снимаются с осей с помощью ax.Children.

person JMikes    schedule 17.03.2021