Filter löschen
Filter löschen

Show text on line in a legend

37 Ansichten (letzte 30 Tage)
Amit Kallush
Amit Kallush am 21 Aug. 2022
Bearbeitet: dpb am 21 Aug. 2022
Hi,
I have this graph, that contains multiple lines, each line represent diffrent standard deviation.
I added a text to describe each line on the plot, but I want the legend to present the line and number together, and not just the line.
Something like this: "-----30---- Standard deviation"
Is anyone know how to do that?
Thanks!
s = [5 10 20 30 40 50];
r = linspace(1,50);
N=[];
for i=1:length(r)
for j=1:length(s)
N(i,j) = (2*s(j)./r(i)).^2;
end
end
k = [20,5,3,4,2,4];
for j=1:6
plot (N(:,j),r)
xlim([0 75])
xticks(0:5:75)
xlabel('Number of Gauges')
ylabel('Standard Error (mm)')
% Define position to display the text
i = round(numel(N(:,j))/k(j));
% Get the local slope
d = (r(i+1)-r(i))/(N((i+1),j)-N((i),j));
X = diff(get(gca, 'xlim'));
Y = diff(get(gca, 'ylim'));
p = pbaspect;
a = atan(d*p(2)*X/p(1)/Y)*180/pi;
% Display the text
text(N(i,j), r(i), num2str(s(j)), 'BackgroundColor', 'w', 'rotation', a);
hold on
end
leg = legend('Standard Deviation');
leg.Box = 'off';
leg.FontSize = 10;
  2 Kommentare
Dyuman Joshi
Dyuman Joshi am 21 Aug. 2022
Like this?
s = [5 10 20 30 40 50];
r = linspace(1,50);
N=[];
for i=1:length(r)
for j=1:length(s)
N(i,j) = (2*s(j)./r(i)).^2;
end
end
k = [20,5,3,4,2,4];
for j=1:6
plot (N(:,j),r)
xlim([0 75])
xticks(0:5:75)
xlabel('Number of Gauges')
ylabel('Standard Error (mm)')
% Define position to display the text
i = round(numel(N(:,j))/k(j));
% Get the local slope
d = (r(i+1)-r(i))/(N((i+1),j)-N((i),j));
X = diff(get(gca, 'xlim'));
Y = diff(get(gca, 'ylim'));
p = pbaspect;
a = atan(d*p(2)*X/p(1)/Y)*180/pi;
% Display the text
text(N(i,j), r(i), num2str(s(j)), 'BackgroundColor', 'w', 'rotation', a);
hold on
end
leg = legend(rmmissing(split(sprintf('-----%d---- Standard deviation\n',s'),newline)));
leg.Box = 'off';
leg.FontSize = 10;
Amit Kallush
Amit Kallush am 21 Aug. 2022
Thanks but this is not what I meant.
I want my legend to have only one entry, which is a line with a number in the middle, like the lines in the graph.
I dont matter the exact line color and number that will be presented in the legend, just that they coorespond to the number and color on the graph.
for expamle a blue line with number 5 in the middle.
Thanks!

Melden Sie sich an, um zu kommentieren.

Antworten (1)

dpb
dpb am 21 Aug. 2022
Bearbeitet: dpb am 21 Aug. 2022
Can't use legend to do that -- the text is not part of the linestyle but a separate object you've added independently.
You'll have to draw another set of lines in the location of the legend and label them similarly as what you did with data lines to simulate the legend manually. Unfortunately, TMW has now "locked down" the internals of the legend object so tightly, there's not a lot than can do with it anymore, even poking at it with Yair Altman's FEX submission.
Try using
hLg=legend(compose('%2d',s));
and see if you can't live with that as a first approximation...if you think you absolutely must have the second half of the line segment, you'll have to figure out the positions and draw more lines matching the line colors; unfortunately, no longer is the legend just a simple axis object drawn into; now they've packaged it as its own object and closed it down to user intervention.
Or, forego using legend altogether and just draw four more horizontal lines in the northeast corner and write text over them same as you drew the originals and call them a legend.
  2 Kommentare
Amit Kallush
Amit Kallush am 21 Aug. 2022
Thanks!
I endded up just using annotate over the existing legend, probably not the most efficient way, but it works:
leg = legend('Standard Deviation');
leg.Box = 'off';
leg.FontSize = 10;
leg.ItemTokenSize = [40,40];
dim = [.475 .605 .3 .3];
h = annotation('textbox',dim,'String','5','FitBoxToText','on','FontSize',9,'HorizontalAlignment','center');
h.BackgroundColor = 'w';
h.LineStyle = "none";
dpb
dpb am 21 Aug. 2022
Bearbeitet: dpb am 21 Aug. 2022
Given what TMW has done to emasculate legend it probably is the most efficient way...while I eventually did find the location where the legend text is stored for each, I was unable after a fair amount of digging to find where those text objects' position property is stored to be able to find the locations at which to draw an additional line past the text to simulate the line on the plot.
Similarly, I could not locate a position of the lines inside the legend that could be used to annotate() on their locations as in the axes on each of those lines.
Most frustrating that it isn't still just a normal axis with pieces; it's undoubtedly a clever and highly data-centrically designed object that meets great metrics about modern code design, but it makes end-user customization nearly impossible. The idea the designer can foresee every possible user need seems to be taking over the general mindset of development more and more.

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by