2017-02-13 15 views
4

Следующий код самый Minimal, Complete, and Verifiable example, который я мог найти. Мое истинное дело намного сложнее:Настройка заголовка для легенды в Matlab

x = 1:0.1:10; 
y = sin(x); 

subplot 211 
plot(x,y) 
[leg,att] = legend('show'); 
title(leg,'my title') 
leg.Title.Visible = 'on'; 

subplot 212 
plot(x,y) 
leg = legend('show'); 
title(leg,'my title') 

Это приводит к:

legend title

Как вы можете ясно видеть, что-то не так с верхним названием легенды. Каким-то образом, просящий att результат легенды вмешивается в его «титул». Во-первых, по какой-то причине он делает его невидимым, но это уже разрешено в коде выше.

Основная проблема заключается в ее положении - у него нет такого свойства, поэтому после установки я не могу его переместить.

Я читал this post in Undocumented Matlab, и я могу думать о некоторых подобных хаках (например, используя text с положением легенды), но моя ситуация очень сложная, и я уже много настраиваю легенду и имею несколько осей в каждом фигура. Таким образом, я предпочитаю простое и рабочее решение, основанное на первоначальной функциональности названия легенды.

Я использую Matlab 2016a.

+0

Вы читали эту записку в [документации] (https://mathworks.com/help/matlab/ref/legend.html) для '[LGD, иконки, графики, TXT] = легенда (___) 'перегрузка? * Примечание. Этот синтаксис не рекомендуется. Он создает легенду, которая не поддерживает все графические функции. Вместо этого используйте синтаксис * 'lgd = legend (__)' * для возврата объекта легенды и установки свойств легенды. * – codeaviator

+0

@Cebri, но мне нужен доступ к значкам, чтобы манипулировать легендой по моим потребностям. Как я могу изменить свои свойства в противном случае? – EBH

+0

Как вы писали, ваш лучший выбор будет использовать текст с позицией легенды. Вы можете создать функцию, если вам нужно сделать это несколько раз. – oro777

ответ

1

Внимание! Этот ответ использует недокументированные функции, результат был протестирован на версиях 2016a и 2017a и может отличаться в других версиях.
Дайте мне знать в комментариях, если это также работает для других версий Matlab.


Я нашел ответ после некоторого исследования undocumented properties легенды. Самый прямой ответ на проблему в этом вопросе - вернуть положение легенды на свое место. Это можно сделать с помощью имущества Position, то есть части скрытыхNodeChildren, название легенды.

Легендарный блок фактически представляет собой небольшой объект осей, поэтому единицы положения нормализуются относительно оси. Если мы посмотрим на это только после создания легенды мы получаем:

[hleg,att] = legend('show'); 
title(hleg,'my title') 
hleg.Title.NodeChildren.Position 

ans = 
    0  0  0 

Что, где мы видим, легенда в этом вопросе. Теперь мы можем переместить его обратно в правильное место с:

hleg.Title.NodeChildren.Position = [0.5 1.5 0]; 

Здесь я поместил его в центре горизонтальной оси (х = 0,5), выше вертикальной оси (у = 1,5), а ось глубины не имеет значения, так что нулевая (г = 0):

correct place

Если вы не обеспокоены возможностью, что легенда будет мешать с данными (например, ваша легенда вне осей данных), то вы можете Остановись здесь. Если нет, продолжайте читать ...


Мы могли бы установить цвет фона на белый:

hleg.Title.NodeChildren.BackgroundColor = 'w'; 

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

x = 1:0.1:10; 
plot(x,sin(x),x,cos(x)) 
[hleg,icons,plots] = legend('show'); 
title(hleg,'my title') 
hleg.Title.Visible = 'on'; 
% the addition in height needed for the title: 
title_hight = hleg.Position(4)/numel(plots); 
hleg.Position([2 4]) = [hleg.Position(2)-title_hight hleg.Position(4)+title_hight]; 
% calculate new position for the elements in the legeng: 
new_pos = fliplr(0.5/(numel(plots)+1):1/(numel(plots)+1):1); 
hleg.Title.NodeChildren.Position = [0.5 new_pos(1) 0]; 
% set the text to the right position: 
leg_txt = findobj(icons,'Type','Text'); 
txt_pos = cell2mat({leg_txt.Position}.'); 
txt_pos(:,2) = new_pos(2:end); 
set(leg_txt,{'Position'},mat2cell(txt_pos,[1 1],3)); 
% set the icons to the right position: 
leg_att = findobj(icons,'Type','Line'); 
set(leg_att,{'YData'},mat2cell(repmat(repelem(new_pos(2:end).',... 
    numel(plots)),1,2),ones(numel(plots)*2,1),2)) 

Код выше, также обобщается для получения дополнительной серии один данных, хотя я предположим, что бывают случаи, когда это не даст правильного решения и потребует тонких настроек.

large box