Matlab中图例标记的高级自定义 [英] advanced customization of legend markers in matlab
问题描述
在matlab图例中对标记添加基本修改相对简单.以下代码段产生的图例():
It is relatively simple to add basic modifications to markers in matlab legends. The legend produced by the following code snippet ():
hold on
h = plot(inf,inf,'ob',inf,inf,'r+');
legend(h,'Data1','Data2');
hold on
h = plot(inf,inf,'ob',inf,inf,'r+');
legend(h,'Data1','Data2');
可以轻松修改为:,使用以下代码:
Can be easily modified to: using the following code:
[~,~,icons,~] = legend(h,'Data1','Data2');
set(icons(1),'LineStyle','-')
set(icons(2),'LineStyle','-')
[~,~,icons,~] = legend(h,'Data1','Data2');
set(icons(1),'LineStyle','-')
set(icons(2),'LineStyle','-')
但是,如果我想正确地说明诸如(圆圈不在一行中间)或(多种颜色一行上带有"+"标记的行).我没有找到任何属性或变通办法来修改图例框中标记的位置,或在一个图例组中添加多个标记.
However things become fairly complicated if I want to correctly legend objects such as (circle is not in the middle of a line) or (several colors for one line with '+' markers on it). I have not found any property or workaround that allows to modify the position of the markers in the legend box, or add several markers in one legend group.
有人知道包含用于图例自定义的高级信息的文档吗?还是如何更好地利用matlab提供的图形对象的众多属性来实现上述功能?
Does anyone know of a document that contains advanced information for legend customization? Or how to better use the numerous properties of graphic objects provided by matlab to achieve what is described above?
推荐答案
在R2014a
之前的MatLab版本中,legend
框实际上是axes
,因此通过其句柄修改其内容相对容易.
In the MatLab version up to R2014a
the legend
box is actually an axes
so it is relatively easy to modify its content through its handle.
从版本R2014b
开始,legend
是graphics object
,似乎无法访问轴句柄(请参考
From version R2014b
the legend
is a graphics object
and seems there is no way to access to the axes handle (ref. to this post on undocumentedmatlab).
至R2014a
给出图例中两行的图例:
Given the legend for two lines in a plot:
h = plot((0:.1:2*pi),sin((0:.1:2*pi)),'ob',(0:.1:2*pi),cos((0:.1:2*pi)),'r+');
[a,b,icons,c] = legend(h,'Data1','Data2');
- a是图例axex的句柄
- b是一个handels数组:
- b(1):第一个字符串的句柄
- b(2):第二个字符串的句柄
- b(3):第一行的句柄
- b(4):第一行标记的句柄
- b(5):第二行的句柄
- b(6):第二行标记的句柄
- a is the handle of the legend axex
- b is an array of handels:
- b(1): handle of the first string
- b(2): handle of the second string
- b(3): handle of the first line
- b(4): handle of the marker of the first line
- b(5): handle of the second line
- b(6): handle of the marker of the second line
- 获取行的
XData
(存储在b(3)
中):它是(1x2)数组 - 将
marker
的XData
(存储在b(4)
中)设置为在上述步骤中获得的数组的最后一个值 - get the
XData
of the line (stored inb(3)
): it is an (1x2) array - set the
XData
of themarker
(stored inb(4)
) to the last value of the array obtained on the above step - 获取该行的
XData
和YData
(存储在b(5)
中)
通过拆分 - 生成
x coord
- 使用
YData
值作为y coord
绘制 - get the
XData
andYData
of the line (stored inb(5)
) - generate the
x coord
by splitting theXData
array - plot the the segments in a
for
loop using theYData
value asy coord
如果要将第一行上的
marker
移动到该行的末尾,则可以:if you want to move the
marker
on the first line to, for example, the end of the line, you can:如果要添加更多
marker
并让第二行由更多具有不同颜色的线段组成,则可以:If you want to add more
marker
and have the second line made of more segments with different colours, you can:XData
数组for
循环中的线段此方法已在以下代码中实现,其中,图例框也已进行了放大,以提高可读性".
This approach has been implemented in the following code in which, the legend box has been also enlarged to make in more "readable".
代码中的注释应说明不同的步骤.
The comments in the code should explain the different steps.
% Plot something h = plot((0:.1:2*pi),sin((0:.1:2*pi)),'ob',(0:.1:2*pi),cos((0:.1:2*pi)),'r+'); % Add trhe legend [a,b,icons,c] = legend(h,'Data1','Data2'); % % a ==> handle of the legend axes % b(1) ==> handle of the first string % b(2) ==> handle of the second string % b(3) ==> handle of the first line % b(4) ==> handle of the marker of the first line % b(5) ==> handle of the second line % b(6) ==> handle of the marker of the second line % % Get positin and size of the legend box ax_p=get(a,'position') % Enlarge the legend box set(a,'position',[ax_p(1)-.2 ax_p(2) ax_p(3)+.2 ax_p(4)]) % Set the linestyle of the first element on the legend set(b(3),'linestyle','-') % Get the XData of the first line xl_1=get(b(3),'xdata') % Move the marker of the first line to the end of the line set(b(4),'xdata',xl_1(2)) % Get the position of the first string xs_1=get(b(1),'position') % Move the first string set(b(1),'position',[xs_1(1)+.2 xs_1(2) xs_1(3)]) % Get the position of the second string xs_2=get(b(2),'position') % Move the second string set(b(2),'position',[xs_2(1)+.2 xs_2(2) xs_2(3)]) % Split the second line in multi-color segment and add more marker on the % second line % % Define the number of segments n=4; % Get the XData of the first line xl_2=get(b(5),'xdata') % Get the YData of the first line yl_2=get(b(5),'ydata') % Define the segments len=linspace(xl_2(1),xl_2(2),n+1); % Plot the segments of the second line in different colours for i=1:n plot(a,[len(i) len(i+1)],[yl_2(1) yl_2(2)], ... 'marker',get(b(6),'marker'),'markeredgecolor', ... get(b(6),'markeredgecolor'),'markerfacecolor',get(b(6),'markerfacecolor'), ... 'color',rand(1,3),'linewidth',2) end
这是结果:
从R2014b起
由于似乎无法访问图例axex,因此可以找到一种解决方案(如上述
Since it seems not possible to access to the legend axex, a solution could be(as suggested in the above mentoined post to add an
axes
and superimpose it to the legend.您可以创建图例:
h = plot((0:.1:2*pi),sin((0:.1:2*pi)),'o-',(0:.1:2*pi),cos((0:.1:2*pi)),'r+-'); [a,b,icons,c] = legend(h,'Data1','Data2');
- a是
matlab.graphics.illustration.Legend
的对象(尝试class(a)
) - b是
matlab.graphics.primitive.Data
个对象的数组(尝试class(b)
) - a is an object of
matlab.graphics.illustration.Legend
(tryclass(a)
) - b is an array of
matlab.graphics.primitive.Data
objects (tryclass(b)
) - b(1):第一个字符串
- b(2):第二个字符串
- b(3):第一行
- b(4):第一行的标记
- b(5):第二行
- b(6):第二行的标记
以与旧版本类似的方式,
b
指的是:in a similar way to the older versions, the
b
refers to:您可以通过
legend
对象a
获得legend
的position
和size
.You can get the
position
andsize
of thelegend
through thelegend
objecta
.然后您可以应用上述相同的方法来绘制更新的"图例.
You can then apply the same approach described above in order to plot the "updated" legend.
此方法已在以下代码中实现(注释应说明不同的步骤).
This approach has been implemented in the following code (the comments should explains the different steps).
% Plot something h = plot((0:.1:2*pi),sin((0:.1:2*pi)),'o-',(0:.1:2*pi),cos((0:.1:2*pi)),'r+-'); % Add the legend [a,b,icons,c] = legend(h,'Data1','Data2'); % Add an axes to the figure ax=axes; % Enlarge the legend, then set the axes position and size equal to the % legend box %Get the legend's position and size ax_p=a.Position; a.Position=[ax_p(1)-.2 ax_p(2) ax_p(3)+.2 ax_p(4)]; ax.Position=a.Position; ax.Units='normalized'; ax.Box='on'; % Plot the firt line in the axes plot(ax,b(3).XData,b(3).YData,'color',b(3).Color); hold on % Add the marker of the first line at the end of the line plot(ax,b(3).XData(end),b(3).YData(end), ... 'marker',b(4).Marker, ... 'markeredgecolor',b(4).Color, ... 'markerfacecolor',b(3).MarkerFaceColor); % Get second line XData and YData x=b(5).XData; y=b(5).YData; % Define the number of line sections n=5; % Update the XData and YData by defning intermediate values len=linspace(x(1),x(2),n); % Plot the set of line with different colours for i=1:n-1 plot(ax,[len(i) len(i+1)],[y(2) y(2)], ... 'marker',b(6).Marker,'markeredgecolor',b(6).Color, ... 'markerfacecolor',b(6).MarkerFaceColor, ... 'color',rand(1,3),'linewidth',1.5); end % Get the legend texts position pt1=b(1).Position; pt2=b(2).Position; % Add the legend text text(pt1(1)+.1,pt1(2),a.String{1}); text(pt2(1)+.1,pt2(2),a.String{2}); % Remove the axes ticks ax.XTick=[]; ax.YTick=[]; % Set the axes limits ax.XLim=[0 1]; ax.YLim=[0 1];
希望这会有所帮助.
Qapla'
这篇关于Matlab中图例标记的高级自定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!