Matlab 线组的图例

Matlab 线组的图例,matlab,plot,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}) 谢谢 更新: 一个新的问题是,有

我喜欢在同一个图中画两组线。每组有两条相同颜色的线,我必须按照一组接一组的顺序画。我尝试只为组显示图例,而不是为行显示图例。我该怎么做?下面是我错误代码的简化:

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})
谢谢


更新:


一个新的问题是,有没有办法在每行后面写上图例,而不覆盖以前的图例,而是附加到它上面?i、 e.类似于“等一下”但适用于图例。

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


您可以使用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中

plot([x1 NaN x2], [y1 NaN y2], 'b', [x3 NaN x4], [y3 NaN y4], 'r');
这也可以让您将分组行的()属性设置为单位。

Re:您的更新:

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

另一种方法是使用线的DisplayName属性跟踪线的名称,然后在添加新内容时根据绘图的当前状态重新生成图例。DisplayName是legend()在调用简单的“legend show”表单时用于自动生成行名的内容。IMHO这有点好,因为图例充当当前打印状态的视图,而不是要求调用者保持两者同步

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'));

事实上,有一种非黑客方式可以做到这一点,使用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')

(不知羞耻地抄袭)

为了回应您的更新,并扩展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
给出了下图:

编辑:在Matlab 2014b中,“图例”的使用已更改,上述解决方案将抛出错误。相反,我们应该修改图例的“字符串”属性。按照以下代码获得与前面示例相同的结果:

% 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);

现在,您可以添加任意数量的绘图,图例将自动更新

进入
hold all
模式后,当您使用
plot
执行绘图时,您需要在阵列上累积
lengends
,该模式允许在不相互覆盖的情况下执行多个绘图。然后,一旦我们完成了,我们就用
暂停
来禁用它

这是供快速参考的较小代码。它完全回答了这个问题。此脚本完成了所有要求的操作,但它是一个完整的工作示例:

% 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;

输出图形:

参考资料:


  • 谢谢一个新的问题是,有没有办法在每行后面写上图例,而不覆盖以前的图例,而是附加到它上面?i、 e.类似于“保持”但适用于图例。@蒂姆:我不知道有什么简单的方法可以将标签添加到现有图例中。如果要附加标签,则必须重新制作整个图例。
    % 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);
    
    % 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;