将不存在的条目添加到图例
Add non-existent entry to legend
我想手动添加一个条目到 MATLAB 图例中。此图例可以预先存在并包含其他图形元素的条目,但不一定。
我制作了一个散点图,但没有使用例如scatter(x,y)
,我使用
绘制它
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
这会生成数字 1 到 x
(和 y
中的元素数)的散点图,因为它们的大小相同。我想为这些数字添加图例条目。
我尝试使用
添加或编辑图例
[h,icons,plots,s] = legend(___)
如 legend
documentation page 所述。我不知道如何添加图例条目,而不必绘制某些东西(例如实际的散点图或常规图)。我希望图例中常用的线条或标记符号是数字或字符,例如'n'
,表示图中的数字。这可能吗?如何实现?
埃里克编辑
我的答案低于 zelanix 的答案,因为我的答案是基于它的。
原回答
一个相当可行的解决方案可能如下:
x = rand(10, 1);
y = rand(10, 1);
figure;
text(x,y,num2str(transpose(1:numel(x))),'HorizontalAlignment','center')
% Create dummy legend entries, with white symbols.
hold on;
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
hold off;
% Create legend with placeholder entries.
[h_leg, icons] = legend('foo', 'bar');
% Create new (invisible) axes on top of the legend so that we can draw
% text on top.
ax2 = axes('position', get(h_leg, 'position'));
set(ax2, 'Color', 'none', 'Box', 'off')
set(ax2, 'xtick', [], 'ytick', []);
% Draw the numbers on the legend, positioned as per the original markers.
text(get(icons(4), 'XData'), get(icons(4), 'YData'), '1', 'HorizontalAlignment', 'center')
text(get(icons(6), 'XData'), get(icons(6), 'YData'), '2', 'HorizontalAlignment', 'center')
axes(ax1);
输出:
这样做的诀窍在于,新轴是在与图例完全相同的位置创建的,icons
元素的坐标是标准化坐标,现在可以在新坐标中使用轴直接。当然,您现在可以自由使用任何字体大小/颜色/任何您需要的东西。
缺点是只有在您的图例被填充和定位后才能调用它。移动图例或添加条目不会更新自定义标记。
埃里克的回答
基于 zelanix 上面的回答。这是一个正在进行中的答案,我正在尝试为此提供一个非常灵活的功能。目前,它只是一个脚本,您需要根据自己的情况进行调整。
% plot some lines and some text numbers
f = figure;
plot([0 1],[0 1],[0 1],[1 0])
x = rand(25,1);
y = rand(25,1);
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
hold on
% scatter(x,y) % used to test the number positions
scatter(x,y,'Visible','off') % moves the legend location to best position
% create the dummy legend using some dummy plots
plot(0,0,'o','Visible','off')
[l,i] = legend('some line','some other line','some numbers','location','best');
l.Visible = 'off';
% create empty axes to mimick legend
oa = gca; % the original current axes handle
a = axes;
axis manual
a.Box = 'on';
a.XTick = [];
a.YTick = [];
% copy the legend's properties and contents to the new axes
a.Units = l.Units; % just in case
a.Position = l.Position;
i = copyobj(i,a);
% replace the marker with a red 'n'
s = findobj(i,'string','some numbers');
% m = findobj(i(i~=s),'-property','YData','marker','o');
m = findobj(i(i~=s),'-property','YData');
sy = s.Position(2);
if numel(m)>1
dy = abs(m(1).YData - sy);
for k = 2:numel(m)
h = m(k);
dy2 = abs(h.YData - sy);
if dy2<dy
kbest = k;
dy = dy2;
end
end
m = m(kbest);
end
m.Visible = 'off';
mx = m.XData;
text(mx,sy,'n','HorizontalAlignment','center','color',[1 0 0])
% reset current axes to main axes
f.CurrentAxes = oa;
结果:
我想手动添加一个条目到 MATLAB 图例中。此图例可以预先存在并包含其他图形元素的条目,但不一定。
我制作了一个散点图,但没有使用例如scatter(x,y)
,我使用
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
这会生成数字 1 到 x
(和 y
中的元素数)的散点图,因为它们的大小相同。我想为这些数字添加图例条目。
我尝试使用
添加或编辑图例[h,icons,plots,s] = legend(___)
如 legend
documentation page 所述。我不知道如何添加图例条目,而不必绘制某些东西(例如实际的散点图或常规图)。我希望图例中常用的线条或标记符号是数字或字符,例如'n'
,表示图中的数字。这可能吗?如何实现?
埃里克编辑
我的答案低于 zelanix 的答案,因为我的答案是基于它的。
原回答
一个相当可行的解决方案可能如下:
x = rand(10, 1);
y = rand(10, 1);
figure;
text(x,y,num2str(transpose(1:numel(x))),'HorizontalAlignment','center')
% Create dummy legend entries, with white symbols.
hold on;
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
plot(0, 0, 'o', 'color', [1 1 1], 'visible', 'off');
hold off;
% Create legend with placeholder entries.
[h_leg, icons] = legend('foo', 'bar');
% Create new (invisible) axes on top of the legend so that we can draw
% text on top.
ax2 = axes('position', get(h_leg, 'position'));
set(ax2, 'Color', 'none', 'Box', 'off')
set(ax2, 'xtick', [], 'ytick', []);
% Draw the numbers on the legend, positioned as per the original markers.
text(get(icons(4), 'XData'), get(icons(4), 'YData'), '1', 'HorizontalAlignment', 'center')
text(get(icons(6), 'XData'), get(icons(6), 'YData'), '2', 'HorizontalAlignment', 'center')
axes(ax1);
输出:
这样做的诀窍在于,新轴是在与图例完全相同的位置创建的,icons
元素的坐标是标准化坐标,现在可以在新坐标中使用轴直接。当然,您现在可以自由使用任何字体大小/颜色/任何您需要的东西。
缺点是只有在您的图例被填充和定位后才能调用它。移动图例或添加条目不会更新自定义标记。
埃里克的回答
基于 zelanix 上面的回答。这是一个正在进行中的答案,我正在尝试为此提供一个非常灵活的功能。目前,它只是一个脚本,您需要根据自己的情况进行调整。
% plot some lines and some text numbers
f = figure;
plot([0 1],[0 1],[0 1],[1 0])
x = rand(25,1);
y = rand(25,1);
for n = 1:numel(x)
text(x(n),y(n),num2str(n), ...
'HorizontalAlignment','center','color',[1 0 0])
end
hold on
% scatter(x,y) % used to test the number positions
scatter(x,y,'Visible','off') % moves the legend location to best position
% create the dummy legend using some dummy plots
plot(0,0,'o','Visible','off')
[l,i] = legend('some line','some other line','some numbers','location','best');
l.Visible = 'off';
% create empty axes to mimick legend
oa = gca; % the original current axes handle
a = axes;
axis manual
a.Box = 'on';
a.XTick = [];
a.YTick = [];
% copy the legend's properties and contents to the new axes
a.Units = l.Units; % just in case
a.Position = l.Position;
i = copyobj(i,a);
% replace the marker with a red 'n'
s = findobj(i,'string','some numbers');
% m = findobj(i(i~=s),'-property','YData','marker','o');
m = findobj(i(i~=s),'-property','YData');
sy = s.Position(2);
if numel(m)>1
dy = abs(m(1).YData - sy);
for k = 2:numel(m)
h = m(k);
dy2 = abs(h.YData - sy);
if dy2<dy
kbest = k;
dy = dy2;
end
end
m = m(kbest);
end
m.Visible = 'off';
mx = m.XData;
text(mx,sy,'n','HorizontalAlignment','center','color',[1 0 0])
% reset current axes to main axes
f.CurrentAxes = oa;
结果: