Matlab:更改图例中条目的顺序
Matlab: change order of entries in Figure legend
我有一个图形文件,我想在其中更改条目的顺序(例如,将第一个条目放在第三个条目中)。我很久以前就保存了这个 Figure.fig 所以我不确定我是否可以恢复原始代码。
这里我给大家展示一下我的剧情:
我希望图例元素按降序排列(如图所示),但由于错误,我的第二个条目指的是错误的情节(它说“25 年”,但情节实际上是指最低趋势,对应“9年”趋势。
我可以直接从 Matlab 中图形的属性编辑器切换图例中条目的顺序吗?如果是,如何(我没有看到任何 "Order" 属性 或类似内容)?否则有没有其他简单的方法来切换图例中条目的顺序?
如果您的图形是在 R2014b 或更新版本中生成的,您可以利用未记录的 'PlotChildren'
属性 来操纵图例条目的顺序,而无需新的 legend
调用。
例如:
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
plot(x, y1, x, y2, x, y3, x, y4);
lh = legend('y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2');
产生:
然后你可以操作:
neworder = [3, 1, 4, 2];
lh.PlotChildren = lh.PlotChildren(neworder);
制作中:
如果您没有 legend
对象的句柄,它是 figure
object containing the axes
object your data is plotted on. You can find the handle to your legend
object using one of the following findobj
方法的子对象:
% Handle to figure object known
lg = findobj(figureobj, 'Type', 'legend');
% Handle to figure object unknown
lh = findobj(gcf, 'Type', 'legend');
请注意,gcf
通常 returns 用户单击的最后一个图形的句柄,但不一定总是如此。
自我推销编辑:该方法包含在 Whosebug MATLAB 社区的一组 legend manipulation tools maintained on GitHub 中。
对于那些使用早于 R2014b 版本的 MATLAB 的人来说,另一种选择是通过指定 plot
的输出来检索绘图对象的句柄。然后,您可以在将句柄传递给 legend
.
之前按照您想要的顺序重新排列句柄
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
hplots = plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};
% Indices specifying the order in which you want the legend entries to appear
neworder = [3 1 4 2];
legend(hplots(neworder), labels(neworder));
更新
为了在从文件加载时正确处理,您可以获取所有 Children
轴以获取绘图对象并获取当前图例以获取标签。然后,您可以按照上述方法对它们重新排序。
load('filename.fig');
labels = get(legend(), 'String');
plots = flipud(get(gca, 'children'));
% Now re-create the legend
neworder = [3 1 4 2];
legend(plots(neworder), labels(neworder))
我找到了一个 Matlab R2020 解决方案,可用于 re-order 图例条目,而不会弄乱它们在彼此之上绘制的顺序。我是从 https://matplotlib.org/1.3.1/users/legend_guide.html 找到的,其实很简单,你需要做的就是调用
legend([p2, p1], ["line 2", "line 1"])
p1 是绘图时创建的线对象
p1 = 图(...)
与 uistack 一起,我可以更改绘制在哪些对象之上的对象,然后重新排序图例以使其有意义。例子
uistack(psave_d,'top') % Brings certain line to front
legend([psave_a, psave_b, psave_g, psave_c, psave_d, psave_e, psave_f, psave_pde], ["k_y=0.000001 W/m/K","k_y=0.0001 W/m/K","k_y=0.001 W/m/K","k_y=0.01 W/m/K","k_y=0.1 W/m/K","k_y=1 W/m/K","k_y=10 W/m/K","Isothermal PDE Numerical Model"])
如果有人需要更多细节,我很乐意提供。干杯
根据我的经验和其他地方对 excaza 回答的评论,他们使用未记录函数的解决方案似乎在 R2017a 之后可能不再有效。
以下使用与 excaza 的原始答案相同的示例图,但不需要未记录的功能并且似乎可以使用(至少)R2021a。它利用指定 subset 图形对象的能力来添加图例标签。此功能似乎可以保留您传入这些图形对象的顺序。
例如,
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};
legend(labels)
生产,
检索图形句柄允许以不同的顺序重新创建图例,
neworder = [3, 1, 4, 2];
ax = gca;
children = ax.Children;
legend(children(neworder), labels(neworder))
修改之前的剧情制作,
请注意,与 another answer to a similar question 不同,这不需要在绘制图形句柄时显式返回图形句柄并跟踪它们。使用 ax.Children
.
从轴中简单地检索句柄
在2021b中,您可以重新排序Legend
对象的未记录PlotChildren
属性,但您必须将AutoUpdate
属性设置为'off'
第一:
hLegend = legend({'Group A', 'Group C', 'Group B'});
hLegend.AutoUpdate = 'off';
hLegend.PlotChildren = hLegend.PlotChildren([1,3,2]);
这不会影响绘图中图形对象的堆叠顺序。请注意:当 AutoUpdate
设置为 'off'
时,向坐标区添加新图形对象时将不再自动添加或删除图例项。
我有一个图形文件,我想在其中更改条目的顺序(例如,将第一个条目放在第三个条目中)。我很久以前就保存了这个 Figure.fig 所以我不确定我是否可以恢复原始代码。
这里我给大家展示一下我的剧情:
我希望图例元素按降序排列(如图所示),但由于错误,我的第二个条目指的是错误的情节(它说“25 年”,但情节实际上是指最低趋势,对应“9年”趋势。
我可以直接从 Matlab 中图形的属性编辑器切换图例中条目的顺序吗?如果是,如何(我没有看到任何 "Order" 属性 或类似内容)?否则有没有其他简单的方法来切换图例中条目的顺序?
如果您的图形是在 R2014b 或更新版本中生成的,您可以利用未记录的 'PlotChildren'
属性 来操纵图例条目的顺序,而无需新的 legend
调用。
例如:
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
plot(x, y1, x, y2, x, y3, x, y4);
lh = legend('y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2');
产生:
然后你可以操作:
neworder = [3, 1, 4, 2];
lh.PlotChildren = lh.PlotChildren(neworder);
制作中:
如果您没有 legend
对象的句柄,它是 figure
object containing the axes
object your data is plotted on. You can find the handle to your legend
object using one of the following findobj
方法的子对象:
% Handle to figure object known
lg = findobj(figureobj, 'Type', 'legend');
% Handle to figure object unknown
lh = findobj(gcf, 'Type', 'legend');
请注意,gcf
通常 returns 用户单击的最后一个图形的句柄,但不一定总是如此。
自我推销编辑:该方法包含在 Whosebug MATLAB 社区的一组 legend manipulation tools maintained on GitHub 中。
对于那些使用早于 R2014b 版本的 MATLAB 的人来说,另一种选择是通过指定 plot
的输出来检索绘图对象的句柄。然后,您可以在将句柄传递给 legend
.
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
hplots = plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};
% Indices specifying the order in which you want the legend entries to appear
neworder = [3 1 4 2];
legend(hplots(neworder), labels(neworder));
更新
为了在从文件加载时正确处理,您可以获取所有 Children
轴以获取绘图对象并获取当前图例以获取标签。然后,您可以按照上述方法对它们重新排序。
load('filename.fig');
labels = get(legend(), 'String');
plots = flipud(get(gca, 'children'));
% Now re-create the legend
neworder = [3 1 4 2];
legend(plots(neworder), labels(neworder))
我找到了一个 Matlab R2020 解决方案,可用于 re-order 图例条目,而不会弄乱它们在彼此之上绘制的顺序。我是从 https://matplotlib.org/1.3.1/users/legend_guide.html 找到的,其实很简单,你需要做的就是调用
legend([p2, p1], ["line 2", "line 1"])
p1 是绘图时创建的线对象 p1 = 图(...) 与 uistack 一起,我可以更改绘制在哪些对象之上的对象,然后重新排序图例以使其有意义。例子
uistack(psave_d,'top') % Brings certain line to front
legend([psave_a, psave_b, psave_g, psave_c, psave_d, psave_e, psave_f, psave_pde], ["k_y=0.000001 W/m/K","k_y=0.0001 W/m/K","k_y=0.001 W/m/K","k_y=0.01 W/m/K","k_y=0.1 W/m/K","k_y=1 W/m/K","k_y=10 W/m/K","Isothermal PDE Numerical Model"])
如果有人需要更多细节,我很乐意提供。干杯
根据我的经验和其他地方对 excaza 回答的评论,他们使用未记录函数的解决方案似乎在 R2017a 之后可能不再有效。
以下使用与 excaza 的原始答案相同的示例图,但不需要未记录的功能并且似乎可以使用(至少)R2021a。它利用指定 subset 图形对象的能力来添加图例标签。此功能似乎可以保留您传入这些图形对象的顺序。
例如,
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};
legend(labels)
生产,
检索图形句柄允许以不同的顺序重新创建图例,
neworder = [3, 1, 4, 2];
ax = gca;
children = ax.Children;
legend(children(neworder), labels(neworder))
修改之前的剧情制作,
请注意,与 another answer to a similar question 不同,这不需要在绘制图形句柄时显式返回图形句柄并跟踪它们。使用 ax.Children
.
在2021b中,您可以重新排序Legend
对象的未记录PlotChildren
属性,但您必须将AutoUpdate
属性设置为'off'
第一:
hLegend = legend({'Group A', 'Group C', 'Group B'});
hLegend.AutoUpdate = 'off';
hLegend.PlotChildren = hLegend.PlotChildren([1,3,2]);
这不会影响绘图中图形对象的堆叠顺序。请注意:当 AutoUpdate
设置为 'off'
时,向坐标区添加新图形对象时将不再自动添加或删除图例项。