线组的图例

时间:2010-01-26 17:48:18

标签: matlab plot

我喜欢在同一个情节中绘制两组线。每组有两条颜色相同的线,我必须按照一组又一组的顺序绘制它们。我尝试只显示组的图例而不是线条。我怎样才能做到这一点?这是我错误代码的简化:

plot(x1, y1, color1); hold on;
plot(x2, y2, color1); hold on;

plot(x3, y3, color2); hold on;
plot(x4, y4, color2); hold on;

legend({color1, color2})

谢谢!


更新:

一个新问题,有没有办法在每一行之后编写图例而不覆盖上一个图例但是附加到它上面?即类似于“坚持”但适用于传奇的东西。

6 个答案:

答案 0 :(得分:25)

有几种方法可以做到这一点。最简单的方法是获取每个组的第一个绘制线的句柄,并将其作为第一个参数传递给LEGEND

h1 = plot(x1, y1, color1);
hold on;
plot(x2, y2, color1);

h2 = plot(x3, y3, color2);
plot(x4, y4, color2);

legend([h1 h2],{'label1', 'label2'});

答案 1 :(得分:10)

您可以使用NaN拼接多条线,这意味着“拿起笔”。然后,图例会将每个数据视为一组数据。

hold on
plot([x1 NaN x2], [y1 NaN y2], 'b');
plot([x3 NaN x4], [y3 NaN y4], 'r');
legend({'foo', 'bar'})
hold off

为方便起见,您可以将其粘贴在多行版本的情节中。

plot([x1 NaN x2], [y1 NaN y2], 'b', [x3 NaN x4], [y3 NaN y4], 'r');

这可以让您将分组行的()属性设置为单位。

答案 2 :(得分:7)

为了回应您的更新,并延长Andrew Janke的答案,我发现这种方法非常适合自动传奇:

% Sample data
order = -1:2;      % number of orders to plot
x = (0:0.01:10)';

% Plot each instance of data in a separate graph
for i=1:numel(order)
    plot(x,besselj(order(i),x))
    hold all

    % Amend legend to include new plot
    [~,~,~,current_entries] = legend;
    legend([current_entries {sprintf('Order = %i',order(i))}]);
end

给出下图: Plot of Bessel functions with automatic legend

编辑:在Matlab 2014b中,“图例”的使用已经改变,上面的解决方案会引发错误。相反,我们应该修改图例的'String'属性。请按照此代码获得与上一个示例相同的结果:

% Sample data
order = -1:2;      % number of orders to plot
x = (0:0.01:10)';

% Plot each instance of data in a separate graph
for i=1:numel(order)
    plot(x,besselj(order(i),x))
    hold on

    % Amend legend 'entries' to include new plot
    entries(i) = { sprintf('Order = %i',order(i)) };
end

% Create legend using the 'entries' strings
legend('String',entries);

现在您可以根据需要添加任意数量的图表,图例将自动更新!

答案 3 :(得分:4)

Re:你的更新:

要更新图例,您需要再次调用“图例(名称)”来替换整个图例。您可以使用legend()的getter形式的第四个参数来确定当前名称,然后只需附加您的名称。 (这假设图中的所有线都是使用以这种方式逐步更新图例的东西添加的。)

[~,~,~,names] = legend;
legend([names {'my new line name'}]);

另一种方法是使用DisplayName属性跟踪行的名称,然后在添加新内容时根据绘图的当前状态重建图例。 DisplayName是legend()用于在调用简单的“图例显示”表单时自动生成行名称的内容。恕我直言,这个传奇充当当前情节状态的视图,而不是要求呼叫者保持两者同步。

function repro_incremental_legend
%REPRO_INCREMENTAL_LEGEND Demonstrate plots with incrementally updated legend
figure; hold on
x = 1:5;
names = {'foo', 'bar', 'baz', 'qux'};
for i = 1:4
    myplot(gca, x, x.*(1/i), names{i});
    update_legend(gca);
    pause(1); % remove in real code
end

function myplot(ax, x, y, name)
%MYPLOT Wrapper for plot() that respects ColorOrder and sets DisplayName
h = plot(ax, x, y); % plot before setting color so HOLD state is respected
set(h, 'DisplayName', name);
ColorOrder = get(ax, 'ColorOrder');
nLines = numel(get(ax, 'Children'));
set(h, 'Color', ColorOrder(1+mod(nLines-1, size(ColorOrder,1)),:));

function update_legend(ax)
%UPDATE_LEGEND Update legend based on current child lines
kids = get(ax, 'Children');
kids = kids(end:-1:1); % Legend seems to have the opposite ordering
legend(get(kids, 'DisplayName'));

答案 4 :(得分:1)

实际上,使用hggroups有一种非黑客方法可以做到这一点。下面绘制了几行,但是图例只将它们视为两行:

t = 0:.1:2*pi;
for k=1:5
    offset = k/7;
    m(:,k) = t+offset';
end
hSLines = plot(t,sin(m),'Color','b');hold on
hCLines = plot(t,cos(m),'Color','g');
hSGroup = hggroup;
hCGroup = hggroup;
set(hSLines,'Parent',hSGroup)
set(hCLines,'Parent',hCGroup)
% Include these hggroups in the legend:
set(get(get(hSGroup,'Annotation'),'LegendInformation'),...
    'IconDisplayStyle','on'); 
set(get(get(hCGroup,'Annotation'),'LegendInformation'),...
    'IconDisplayStyle','on'); 
legend('Sine','Cosine')

(从http://www.mathworks.se/help/matlab/creating_plots/controlling-legends.html无耻地复制)

答案 5 :(得分:1)

在我们进入lengends模式后执行使用plot的绘图时,您需要在数组上累积hold all,这样可以在不覆盖的情况下执行多个绘图彼此。然后,一旦我们完成,我们将使用hold off禁用它。

这是用于快速参考的较小代码。它完全回答了这个问题。这个脚本完成了所有请求,然而,这是一个完全有效的例子:

% To clean stuff.
clc
clear
close all

% Set some nice settings.
grid on;
format long;

% Hold the graphics output until we are good to go.
hold all;

% To create some random test data.
x1 = 0 : 0.1 : 1;
y1 = sin( x1 );
y2 = cos( x1 );
y3 = tan( x1 );

% To perform the plotting. Here to start answering the question.
plot(x1,y1,'--g','LineWidth',2);
legendText(end+1) = { 'Sin(x)' };

plot(x1,y2,'--b','LineWidth',2);
legendText(end+1) = { 'Cos(x)' };

plot(x1,y3,'-k','LineWidth',2);
legendText(end+1) = { 'Tan(x)' };

% Add the legends to the plotting.
legend(legendText,'location','northwest');

% Flush/display our accumulated plotting until now.
hold off;

输出图形:

参考文献:

  1. https://www.mathworks.com/help/matlab/creating_plots/add-plot-to-existing-graph.html