Легенда;текст / описание перед ключом / цветом? - PullRequest
0 голосов
/ 23 января 2019

По умолчанию MATLAB помещает текстовую часть записи легенды после образца того, что используется на графике. Есть ли способ изменить это? Например, используя приведенный ниже код, первая запись в легенде представляет собой темно-синий прямоугольник, за которым следует текст I'm; Я бы хотел, чтобы все было наоборот (то есть текст I'm, за которым следует темно-синий прямоугольник). Я использую R2017b

Пример кода:

test_values = [ 12, 232, 22, 44, 67, 72, 123, 35, 98 ];
test_text   = [ "I'm", "sorry", "Dave", "I'm", "afraid", "I", "can't", "do", "that" ];

Pie = pie( test_values );

legend( test_text );

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Вот еще один вариант использования некоторых недокументированных функций :

test_values = [ 12, 232, 22, 44, 67, 72, 123, 35, 98 ];
test_text   = {'I''m'; 'sorry'; 'Dave'; 'I''m';'afraid';'I';'can''t';'do';'that'};
Pie = pie( test_values );
leg = legend(test_text,'Location','eastoutside');
drawnow % without this you can't accsses the legend entries
icons = [leg.EntryContainer.NodeChildren.Icon]; % an array with all the legend icons
leg.ItemTokenSize(1) = 0; % set the relative position of the text in the legend to x=0

% the following will probably need some fine tuning for a specific
% figure. It shifts the icons positions horizontally (i.e. only the first
% row has values other than zeros):
shift = [10    10     17     17
         0     0     0     0
         0     0     0     0];
for k = 1:numel(icons)
    % move the icon (patch) border:
    icons(k).Transform.Children.Children(1).VertexData = ...
    icons(k).Transform.Children.Children(1).VertexData+shift;
    % move the icon (patch) fill:
    icons(k).Transform.Children.Children(2).VertexData = ...
    icons(k).Transform.Children.Children(2).VertexData+shift;
end

% the following will probably need some fine tuning for a specific
% figure. It expands the legend box horizontally:
shift = [0    0     1     1
         0     0     0     0
         0     0     0     0];
leg.BoxEdge.VertexData = leg.BoxEdge.VertexData+shift; % the box border
leg.BoxFace.VertexData = leg.BoxFace.VertexData+shift; % the box face

enter image description here

0 голосов
/ 23 января 2019

Это альтернативное решение, основанное на подходе, использованном EBH в его решении.

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

Предлагаемое мной решение не использует никаких недокументированных функций и было протестировано на R2015b; Я не знаю, будет ли это работать в более поздних версиях.

Идея такова:

  • вызывает функцию legend, требуя все выходные параметры
  • работа со вторым выходным параметром
  • первая половина данных в этом параметре относится к text легенды
  • вторая половина - адта patch легенды (коробки)
  • цикл по этому параметру
  • Получить исходную позицию текстового элемента
  • Получить оригинал согласованных вершин патча
  • Установить позицию текста в исходную координату первого X патча
  • Установите координаты «X» патча в исходное положение «X» текста и масштабируйте его

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

Кроме того, я изменил определение текста легенды, поскольку R2015b не обрабатывает строку в соответствии с вопросом.

test_values = [ 12, 232, 22, 44, 67, 72, 123, 35, 98 ];
test_text   = { 'I''m', 'sorry', 'Dave', 'I''m', 'afraid', 'I' 'can''t', 'do', 'that' };

Pie = pie( test_values );
% get all the output from the legend function
[lgd,icons,plots,txt]=legend( test_text );
% Get the number of elements in the legend
n_items=length(icons)/2
% Loop over the legend's items
for i=1:n_items
   % Get the original position of the text item
   orig_txt=icons(i).Position
   % Get the original coordinated of the Vertices of the patch
   orig_mark=icons(i+n_items).Vertices
   % Set the position of the text to the original coordinate of the first
   % "X" of the patch
   icons(i).Position=[orig_mark(1) orig_txt(2)]
   % Set the "X" coordinates of the patch to the original "X" position of
   % the text and scale it
   icons(i+n_items).Vertices(:,1)=icons(i+n_items).Vertices(:,1)+orig_txt(1)*.7
end

enter image description here

0 голосов
/ 23 января 2019

Я не думаю, что это возможно, но вы можете обойти это, если дадите легенду пустой текст, а затем отобразите текст снаружи, что-то вроде этого:

figure;
Pie = pie( test_values );
emptyLegend = repmat({''},9,1);
h = legend( emptyLegend );
text(repmat(0.8,9,1),[0.8:-0.1:0]',test_text)
set(h,'Position',[0.9 0.5 0.05 0.35])
...