I searched in many places and didn't find a way to do what I would like to achieve using MATLAB which is this: putting the keys (text labels) to the left of the color lines in the legend in MATLAB.
I would like to achieve this result that is the default result using gnuplot for instance (cf link above) and that is apparently doable using MATLAB's cousin Octave (see Octave's legend
) that has an option to do legend("left")
that "place[s] label text to the left of the keys."
Is it possible to do so using MATLAB?
Updated slightly using the second output of legend
mentioned by @nirvana-msu.
We can adjust the positions of the text and plot object in the legend by retrieving their current position and altering it. The position units of all items in the legend are normalized data units between 0 and 1.
Something like the following should work.
%// Create some random data and display
figure;
p = plot(rand(2,3));
[L, handles] = legend({'one', 'two', 'three'});
%// Get the text handles
texts = findall(handles, 'type', 'text');
%// Get the line handles
lines = findall(handles, 'type', 'line');
%// Get the XData of all the lines
poslines = get(lines, 'XData');
%// Subtract 1 from all the positions and take the absolute value
%// this will shift them to the other side as the xlims are [0 1]
set(lines, {'XData'}, cellfun(@(x)abs(x - 1), poslines, 'uni', 0))
%// Get the position of all of the text labels
postext = get(texts, 'Position');
%// Figure out where the lines ended up
xd = get(lines, 'xdata');
xd = cat(2, xd{:});
%// Have the labels be next to the line (with 0.05 padding)
positions = cellfun(@(x)[min(xd) - 0.05, x(2:3)], postext, 'uni', 0);
set(texts, {'Position'}, positions, ...
'HorizontalAlignment', 'right');
Here's a solution that works on HG1 and HG2 alike.
The idea is somewhat similar to that in @Suever's answer - we want to flip around all text, lines and markers inside the legend, however there are some notable differences:
line
and text
handles using findall
- they are available as the second output of legend
function.XData
with both start and end points. With text it's a bit more tricky since you need to control Position
, i.e. left edge, but you need to know text width to calculate symmetrical transformation. Extent
property gives us what we're missing.Code:
hFig = figure();
axh = axes('Parent', hFig);
plot(axh, randn(100,2), '-*');
[~, hObjs] = legend(axh, {'first','second-some-long-text'});
for i = 1:length(hObjs)
hdl = hObjs(i);
if strcmp(get(hdl, 'Type'), 'text')
pos = get(hdl, 'Position');
extent = get(hdl, 'Extent'); % we need text x-position and width
pos(1) = 1-extent(1)-extent(3); % symmetrical relative to center
set(hdl, 'Position', pos);
else % 'line'
xData = get(hdl, 'XData');
if length(xData) == 2 % line
xDataNew = [1-xData(2), 1-xData(1)];
else % length(xData)==1, i.e. marker
xDataNew = 1-xData;
end
set(hdl, 'XData', xDataNew);
end
end
I've decided to take a slightly different approach for the HG2 case. Although admittedly somewhat silly, it could actually be useful if the figure ends up being exported.
What we do is pretty much rotate every conceivable thing by 180°:
function q37286345
%// Define some functions:
f = {'sin(x)','cos(x)','-2E-3.*x.^3'};
figure(); hold on;
for ind1 = 1:numel(f)
ezplot(f{ind1}, [-10 10]);
end
title(''); %// Just because I find the default annoying :)
%// Rotate stuff:
[L,H] = legend(f{:},'Location','SouthWest');
[H(1:3).Rotation] = deal(180);
[H(1:3).HorizontalAlignment] = deal('right');
set(gca,'XTickLabelRotation',180,'YTickLabelRotation',180,...
'XAxisLocation','top','YAxisLocation','right');
The result looks approximately like this:
There are several easily-remedied side effects:
Children
of Legend
are reordered.We can explore the Legend metaclass ('matlab.graphics.illustration.Legend'
) to learn more about HG2:
%% // Exploring.....
mc = metaclass(L);
pl = {mc.PropertyList.Name}.'; %'
ml = {mc.MethodList.Name}.'; %'
s = struct(L);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With