MATLAB Answers

Detox
0

Ignoring markers and lines in legend

Asked by Detox
on 28 Jun 2018
Latest activity Commented on by dpb
on 2 Jul 2018
Accepted Answer by dpb
I want to ignore markers in my legend but do not know how to do this properly. k in this code is the variable in the for loop that is being incremented.
C = {'k','b','r','g','y',[.5 .6 .7],[.8 .2 .6]};
Plot1 = loglog(Discret,L2err,'.r', 'MarkerSize',15);
hold on
Plot2 = loglog(Discret,L2err,'color',C{k}, 'LineWidth', 2);
legendInfo{k} = ['Factor = ' num2str(k)];
legend(Plot2,legendInfo)
legend(legendInfo)
triang_x = [Discret(2), Discret(5)];
triang_y = interp1(Discret, L2err, triang_x);
hold on
z = loglog(triang_x([1,2,2]), triang_y([1,1,2]), 'k', 'LineWidth', 2);
grid on
Problem is also that the lines of the triangle also goes into the legend. Any ideas on how to fix this? Really appreciate it!

  0 Comments

Sign in to comment.

2 Answers

Answer by dpb
on 28 Jun 2018
Edited by dpb
on 29 Jun 2018
 Accepted Answer

...
legendInfo{k} = ['Factor = ' num2str(k)];
legend(Plot2,legendInfo)
legend(legendInfo)
...
If you want only certain lines to be in the legend, then use the first form but with the subset array of only the line handles (and labels to match) in the call to legend.
figure
hold on
...
legendInfo={num2str([1:N].','Factor = %d')};
for k=1:N
...
hL1(k) = loglog(Discret,L2err,'.r', 'MarkerSize',15);
hL2(k) = loglog(Discret,L2err,'color',C{k}, 'LineWidth', 2);
triang_x = [Discret(2), Discret(5)];
triang_y = interp1(Discret, L2err, triang_x);
hLz = loglog(triang_x([1,2,2]), triang_y([1,1,2]), 'k', 'LineWidth', 2);
end
grid on
legend(hL2,legendInfo)
should come close if I interpret what you want correctly.
ADDENDUM
To emulate your loop with fake data but to only label the lines...salt to suit.
% dummy data to emulate lines on plot
x=[1:10];
y=-0.1*x+2; y=repmat(y,5,1)+linspace(0,-0.8,5).';
x=x.'; y=y.';
nc=size(y,2);
C = {'k','b','r','g','y',[.5 .6 .7],[.8 .2 .6]};
legendInfo=num2str([1:nc].','Factor = %d');
hL=zeros(nc,1);
figure, hold on
for k=1:nc
hL(k)= plot(x,y(:,k), 'color',C{k}, 'LineWidth', 2, ...
'markeredgecolor','r', 'markerfacecolor','r', ...
'marker','.', 'MarkerSize',15);
tx=[x(2), x(5)];
ty=interp1(x,y(:,k),tx);
plot(tx([1,2,2]), ty([1,1,2]), 'k', 'LineWidth',0.5);
end
legend(hL,legendInfo)
grid on
The chosen data makes the triangles overlap but the effect is what is shown in your figure and note there are no labels excepting for the lines...I did combine the characteristics into the one line object so it does reflect the marker as well as color; if you don't want that effect, then you can revert to the two lines but again, just pass the one set of handles to legend and those are all you'll get.
Also notice there's a fair amount of stuff that can be moved out of the loop and vectorized and done before/afterwards to simplify the loop itself...
ADDENDUM 2
tx=[x(2), x(5)];
ty=interp1(x,y(:,k),tx);
plot(tx([1,2,2]), ty([1,1,2]), 'k', 'LineWidth',0.5);
If the points are going to be existing ones, there's no need for interp1 here;, just build ty the same was as tx. Perhaps began or will be going to use other points???
i1=2; i2=5; % Set the desired points; could be variable...
itx=[i1 i2 i2]; % Build the addressing vector from them
plot(x(itx), y(itx), 'k', 'LineWidth',0.5); % and use the indexing vector

  19 Comments

dpb
on 2 Jul 2018
Again I showed that above...to work inside the loop, it's better to store the legend text for the line in the 'DisplayName' property; then when the loop is done call
legend('show')
hL(i)=plot(x,y, ...
'DisplayName',legendInfo(k,:), ...
...);
Use the above syntax to build the legend including the factor.
Thanks again. I got what you mean but writing it outside the loop does not make much sense to me because the file will be called inside the loop as the factors and values will all be extracted from the file I sent you ergo writing it outside the loop would not work in my case as the factors change.
dpb
on 2 Jul 2018
Of course it will with the simple expedient of just saving the single factor required while going through the loop or, more expeditiously, building the info array.
Saving a half-dozen floating point values in the day of many-GBytes of memory is nothing if it simplifies other code; you're already reading it, just make it an array. There appears to be a lot of unnecessary machinations on the data that cleaning up could probably also make things "much more simpler" than they now seem.
But, again, if inside the loop, I'd recommend the 'DisplayName' property to your attention vs legend() multiple times in the loop.

Sign in to comment.


Answer by Ameer Hamza
on 28 Jun 2018
Edited by Ameer Hamza
on 28 Jun 2018

From legend documentation, it appears that MATLAB does not support direct control over legend markers. They are decided automatically by the corresponding plot() markers shape. However, you can get the required effect by making two plots, one with markers and another without the marker and displaying only one in the legend. For example, try this
hold on
p1 = plot(1:10, '+-', 'Color', 'r');
p2 = plot(1:10, '-', 'Color', 'r');
l = legend(p2, {'legend without marker'});
p2 is a dummy plot, just for displaying the legend. You might consider plotting only a few points if the dataset is large to save space.

  2 Comments

Detox
on 28 Jun 2018
Thanks for the answer! Sounds good and that's what I have done so far but it will be in a for-loop so I have to find a workaround for this. Very unfortunate I wasted 3 days already trying to play with the settings :/
Oh! I failed to notice that you are already doing this in your code. For code with for-loop please refer to dbp's answer.

Sign in to comment.