MATLAB绘制多组数据的双轴、三轴、四轴图

目录

引言

Yaxis2:绘制2组数据的双轴图

Yaxis2N:绘制N组数据的双轴图

Yaxis3:绘制3组数据的三轴图

Yaxis3N:绘制N组数据的三轴图

Yaxis4:绘制4组数据的四轴图

Yaxis4N:绘制N组数据的四轴图

使用示例


引言

        MATLAB自带的plotyy函数能轻松实现在带有2个y轴的图中绘制2组数据,若想在其中某一y轴下绘制n组数据,也可通过将函数plotyy(x1,y1,x2,y2)中的自变量替换为n列矩阵实现。然而,plotyy函数难以实现对图像轴标、线形等元素的自主定义,且MATLAB未自带绘制多组数据三、四轴图的函数。因此笔者编写了一系列脚本,实现多组数据的双轴、三轴、四轴图像绘图,并封装成MATLAB函数。

        函数按照复杂度递增的顺序,如下表所示:

函数名功能调用格式
Yaxis22组数据-双条纵轴Yaxis2 (x数据, y数据, {线条颜色}, x数据名(带单位), {y数据名(带单位)})
Yaxis2NN组数据-双条纵轴Yaxis2N (x数据, y数据总矩阵, 右轴线条数, 右轴标注(带单位), {线条颜色}, x数据名(带单位), {y数据名});
Yaxis33组数据-三条纵轴Yaxis3(x数据, y数据, {线条颜色}, x数据名 (带单位), {y数据名(带单位)})
Yaxis3NN组数据-三条纵轴Yaxis3N (x数据, y数据总矩阵, 右轴线条数, 右轴标注(带单位), 右外轴线条数, 右外轴标注(带单位),  {线条颜色}, x数据名(带单位), {y数据名});
Yaxis44组数据-四条纵轴Yaxis4(x数据, y数据, {线条颜色}, x数据名 (带单位), {y数据名(带单位)})
Yaxis4NN组数据-四条纵轴Yaxis4N (x数据, y数据总矩阵, 右轴线条数, 右轴标注(带单位), 右外轴线条数, 右外轴标注(带单位), 左轴线条数, 左轴标注(带单位), {线条颜色}, x数据名(带单位), {y数据名});

        y轴增加的次序为,在原始x-y坐标系基础上,依次扩充右轴右外轴左轴

Yaxis2:绘制2组数据的双轴图

function [ha,h] = Yaxis2(x,y1,y2,ycl,xstr,ystr)
% [axis handle, line handle]

[ha,h(1),h(2)] = plotyy(x,y1,x,y2);
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1});
set(ha(2),'xcolor','k','ycolor',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all

hh1 = get(ha(1),'ylabel');
set(hh1,'string',ystr{1});
set(hh1,'color',ycl{1});

hh2 = get(ha(2),'ylabel');
set(hh2,'string',ystr{2});
set(hh2,'color',ycl{2});

set(h(1),'color',ycl{1},'linestyle','--');
set(h(2),'color',ycl{2});
xlabel(xstr);

%legend(h,ystr);

limy2 = get(ha(2),'ylim');
% 对齐刻度
ord  = round(log10(limy2(2))) - 1;
ord = 10^ord;
limy2(1) = floor(limy2(1)/ord)*ord;
limy2(2) = floor(limy2(2)/ord)*ord + ord;
TickArrray = linspace(limy2(1),limy2(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',limy2,'ytick',TickArrray,'yTickLabel',TickArrray2);

end

Yaxis2N:绘制N组数据的双轴图

function [ha,h] = Yaxis2N(x,yA,N,Nstr,ycl,xstr,ystr)
% [axis handle, line handle]

[ha,h(1),h(2)] = plotyy(x,yA(1,:),x,yA(2,:));
set(h(1),'color',ycl{1},'linestyle','--');
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1});
set(ha(2),'xcolor','k','ycolor',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all

% 对右轴添加曲线
ylimN = get(ha(2),'ylim');
for k = 2:(1+N)
ha(k) = ha(2);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN(1) = min(ylimN(1),min(yA(k,:)));
ylimN(2) = max(ylimN(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN(2))) - 1;
ord = 10^ord;
ylimN(1) = floor(ylimN(1)/ord)*ord;
ylimN(2) = floor(ylimN(2)/ord)*ord + ord;
TickArrray = linspace(ylimN(1),ylimN(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',ylimN,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha(2),'ylim',ylimN)

set(get(ha(1),'ylabel'),'string','n (r/min)')
set(get(ha(2),'ylabel'),'string',Nstr)

xlabel(xstr);

legend(h,ystr,'location','northwest');

end

Yaxis3:绘制3组数据的三轴图

function [ha,h] = Yaxis3(x,y1,y2,y3,ycl,xstr,ystr)
% [axis handle, line handle]

% 画前两条线
[ha,h(1),h(2)] = plotyy(x,y1,x,y2);
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1},'yTickMode','auto');
set(ha(2),'xcolor','k','ycolor',ycl{2},'yTickMode','auto');
set(h(1),'color',ycl{1},'linestyle','--');
set(h(2),'color',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all
% 设置第三各图窗间隙
cfig = get(gcf,'color');
pos = [0.1 0.1 0.7 0.8];
offset = pos(3)/5.5;
pos(3) = pos(3) - offset/2;
% 画第三条线
set(ha,'position',pos);
pos3 = [pos(1) pos(2) pos(3)+offset pos(4)];
limx1 = get(ha(1),'xlim');
limx3 = [limx1(1) limx1(1)+1.2*(limx1(2)-limx1(1))];
ha(3) = axes('position',pos3,'box','off','color','none','xcolor','k','ycolor',ycl{3},...
    'xtick',[],'xlim',limx3,'yaxislocation','right');
h(3) = line(x,y3,'color',ycl{3},'parent',ha(3));
limy3 = get(ha(3),'ylim');
% 遮盖第三个图窗多出的x轴
line([limx1(2) limx3(2)],[limy3(1) limy3(1)],'color',cfig,'parent',ha(3),'clipping','off');

axes(ha(2))
set(get(ha(1),'ylabel'),'string',ystr{1})
set(get(ha(2),'ylabel'),'string',ystr{2})
set(get(ha(3),'ylabel'),'string',ystr{3})
set(get(ha(1),'xlabel'),'string',xstr)

%legend(h,ystr);

limy2 = get(ha(2),'ylim');
% 对齐刻度
ord  = round(log10(limy2(2))) - 1;
ord = 10^ord;
limy2(1) = floor(limy2(1)/ord)*ord;
limy2(2) = floor(limy2(2)/ord)*ord + ord;
TickArrray = linspace(limy2(1),limy2(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',limy2,'ytick',TickArrray,'yTickLabel',TickArrray2);

ord  = round(log10(limy3(2))) - 1;
ord = 10^ord;
limy3(1) = floor(limy3(1)/ord)*ord;
limy3(2) = floor(limy3(2)/ord)*ord + ord;
TickArrray = linspace(limy3(1),limy3(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(3),'ylim',limy3,'ytick',TickArrray,'yTickLabel',TickArrray2);

end

Yaxis3N:绘制N组数据的三轴图

function [ha,h] = Yaxis3N(x,yA,N1,N1str,N2,N2str,ycl,xstr,ystr)
% [axis handle, line handle]

% 画前两条线
[ha,h(1),h(2)] = plotyy(x,yA(1,:),x,yA(2,:));
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1},'yTickMode','auto');
set(ha(2),'xcolor','k','ycolor',ycl{2},'yTickMode','auto');
set(h(1),'color',ycl{1},'linestyle','--');
set(h(2),'color',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all
% 设置第三各图窗间隙
cfig = get(gcf,'color');
pos = [0.1 0.1 0.7 0.8];
offset = pos(3)/5.5;
pos(3) = pos(3) - offset/2;
% 画第三条线
set(ha,'position',pos);
pos3 = [pos(1) pos(2) pos(3)+offset pos(4)];
limx1 = get(ha(1),'xlim');
limx3 = [limx1(1) limx1(1)+1.2*(limx1(2)-limx1(1))];
ha0(3) = axes('position',pos3,'box','off','color','none','xcolor','k','ycolor',ycl{2+N1},...
    'xtick',[],'xlim',limx3,'yaxislocation','right');
% h(3) = line(x,yA((2+N1),:),'color',ycl{2+N1},'parent',ha(3));
ha(3) = ha0(3);
limy3 = get(ha0(3),'ylim');

ylimN1 = get(ha(2),'ylim');
for k = 2:(1+N1)
ha(k) = ha(2);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN1(1) = min(ylimN1(1),min(yA(k,:)));
ylimN1(2) = max(ylimN1(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN1(2))) - 1;
ord = 10^ord;
ylimN1(1) = floor(ylimN1(1)/ord)*ord;
ylimN1(2) = floor(ylimN1(2)/ord)*ord + ord;
TickArrray = linspace(ylimN1(1),ylimN1(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',ylimN1,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha(2),'ylim',ylimN1)

ylimN2 = get(ha0(3),'ylim');
for k = (2+N1):(1+N1+N2)
ha(k) = ha0(3);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN2(1) = min(ylimN2(1),min(yA(k,:)));
ylimN2(2) = max(ylimN2(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN2(2))) - 1;
ord = 10^ord;
ylimN2(1) = floor(ylimN2(1)/ord)*ord;
ylimN2(2) = floor(ylimN2(2)/ord)*ord + ord;
TickArrray = linspace(ylimN2(1),ylimN2(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha0(3),'ylim',ylimN2,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha0(3),'ylim',ylimN2)

% 遮盖第三个图窗多出的x轴
line([limx1(2) limx3(2)],[ylimN2(1) ylimN2(1)],'color',cfig,'parent',ha0(3),'clipping','off');

set(get(ha(1),'ylabel'),'string','n (r/min)')
set(get(ha(2),'ylabel'),'string',N1str)
set(get(ha0(3),'ylabel'),'string',N2str)
set(get(ha(1),'xlabel'),'string',xstr)

legend(h,ystr,'location','northwest');

end

Yaxis4:绘制4组数据的四轴图

function [ha,h] = Yaxis4(x,y1,y2,y3,y4,ycl,xstr,ystr)
% [axis handle, line handle]

% 画前两条线
[ha,h(1),h(2)] = plotyy(x,y1,x,y2);
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1},'yTickMode','auto');
set(ha(2),'xcolor','k','ycolor',ycl{2},'yTickMode','auto');
set(h(1),'color',ycl{1},'linestyle','--');
set(h(2),'color',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all
% 设置第三各图窗间隙
cfig = get(gcf,'color');
pos = [0.2 0.1 0.6 0.8];
offset = pos(3)/5.5;
pos(3) = pos(3) - offset/2;
pos(1) = pos(1) + offset/2; %% 4
% 画第三条线
set(ha,'position',pos);
pos3 = [pos(1) pos(2) pos(3)+offset pos(4)];
limx1 = get(ha(1),'xlim');
limx3 = [limx1(1) limx1(1)+1.2*(limx1(2)-limx1(1))];
ha(3) = axes('position',pos3,'box','off','color','none','xcolor','k','ycolor',ycl{3},...
    'xtick',[],'xlim',limx3,'yaxislocation','right');
h(3) = line(x,y3,'color',ycl{3},'parent',ha(3));
limy3 = get(ha(3),'ylim');
% 遮盖第三个图窗多出的x轴
line([limx1(2) limx3(2)],[limy3(1) limy3(1)],'color',cfig,'parent',ha(3),'clipping','off');

pos4 = [pos3(1)-offset pos(2) pos3(3) pos(4)];
limx4 = [limx1(2)-1.2*(limx1(2)-limx1(1)) limx1(2)];
ha(4) = axes('position',pos4,'box','off','color','none','xcolor','k','ycolor',ycl{4},...
    'xtick',[],'xlim',limx4,'yaxislocation','left');
h(4) = line(x,y4,'color',ycl{4},'parent',ha(4));
limy4 = get(ha(4),'ylim');

line([limx1(1) limx4(1)],[limy4(1) limy4(1)],'color',cfig,'parent',ha(4),'clipping','off');

axes(ha(2))
set(get(ha(1),'ylabel'),'string',ystr{1})
set(get(ha(2),'ylabel'),'string',ystr{2})
set(get(ha(3),'ylabel'),'string',ystr{3})
set(get(ha(4),'ylabel'),'string',ystr{4})

xlabel(xstr);
%legend(h,ystr);

limy2 = get(ha(2),'ylim');
% 对齐刻度
ord  = round(log10(limy2(2))) - 1;
ord = 10^ord;
limy2(1) = floor(limy2(1)/ord)*ord;
limy2(2) = floor(limy2(2)/ord)*ord + ord;
TickArrray = linspace(limy2(1),limy2(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',limy2,'ytick',TickArrray,'yTickLabel',TickArrray2);

ord  = round(log10(limy3(2))) - 1;
ord = 10^ord;
limy3(1) = floor(limy3(1)/ord)*ord;
limy3(2) = floor(limy3(2)/ord)*ord + ord;
TickArrray = linspace(limy3(1),limy3(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(3),'ylim',limy3,'ytick',TickArrray,'yTickLabel',TickArrray2);

ord  = round(log10(limy4(2))) - 1;
ord = 10^ord;
limy4(1) = floor(limy4(1)/ord)*ord;
limy4(2) = floor(limy4(2)/ord)*ord + ord;
TickArrray = linspace(limy4(1),limy4(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(4),'ylim',limy4,'ytick',TickArrray,'yTickLabel',TickArrray2);

end

Yaxis4N:绘制N组数据的四轴图

function [ha,h] = Yaxis4N(x,yA,N1,N1str,N2,N2str,N3,N3str,ycl,xstr,ystr)
% [axis handle, line handle]

% 画前两条线
[ha,h(1),h(2)] = plotyy(x,yA(1,:),x,yA(2,:));
grid on
set(ha(1),'xcolor','k','ycolor',ycl{1},'yTickMode','auto');
set(ha(2),'xcolor','k','ycolor',ycl{2},'yTickMode','auto');
set(h(1),'color',ycl{1},'linestyle','--');
set(h(2),'color',ycl{2});
% 对齐纵轴刻度新需求
nbTick = size(get(ha(1),'yTickLabel'));
nbT = nbTick(1);
hold all
% 设置各图窗间隙
cfig = get(gcf,'color');
pos = [0.2 0.1 0.6 0.8];
offset = pos(3)/5.5;
pos(3) = pos(3) - offset/2;
pos(1) = pos(1) + offset/2; %% 4
% 画第三条线
set(ha,'position',pos);
pos3 = [pos(1) pos(2) pos(3)+offset pos(4)];
limx1 = get(ha(1),'xlim');
limx3 = [limx1(1) limx1(1)+1.2*(limx1(2)-limx1(1))];
ha0(3) = axes('position',pos3,'box','off','color','none','xcolor','k','ycolor',ycl{2+N1},...
    'xtick',[],'xlim',limx3,'yaxislocation','right');
% h(3) = line(x,yA((2+N1),:),'color',ycl{2+N1},'parent',ha(3));
ha(3) = ha0(3);
limy3 = get(ha0(3),'ylim');

% 画第四条线
pos4 = [pos3(1)-offset pos(2) pos3(3) pos(4)];
limx4 = [limx1(2)-1.2*(limx1(2)-limx1(1)) limx1(2)];
ha0(4) = axes('position',pos4,'box','off','color','none','xcolor','k','ycolor',ycl{2+N1+N2},...
    'xtick',[],'xlim',limx4,'yaxislocation','left');
% h(4) = line(x,yA((2+N1+N2),:),'color',ycl{2+N1+N2},'parent',ha(4));
ha(4) = ha0(4);
limy4 = get(ha0(4),'ylim');

ylimN1 = get(ha(2),'ylim');
for k = 2:(1+N1)
ha(k) = ha(2);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN1(1) = min(ylimN1(1),min(yA(k,:)));
ylimN1(2) = max(ylimN1(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN1(2))) - 1;
ord = 10^ord;
ylimN1(1) = floor(ylimN1(1)/ord)*ord;
ylimN1(2) = floor(ylimN1(2)/ord)*ord + ord;
TickArrray = linspace(ylimN1(1),ylimN1(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha(2),'ylim',ylimN1,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha(2),'ylim',ylimN1)

ylimN2 = get(ha0(3),'ylim');
for k = (2+N1):(1+N1+N2)
ha(k) = ha0(3);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN2(1) = min(ylimN2(1),min(yA(k,:)));
ylimN2(2) = max(ylimN2(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN2(2))) - 1;
ord = 10^ord;
ylimN2(1) = floor(ylimN2(1)/ord)*ord;
ylimN2(2) = floor(ylimN2(2)/ord)*ord + ord;
TickArrray = linspace(ylimN2(1),ylimN2(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha0(3),'ylim',ylimN2,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha0(3),'ylim',ylimN2)

% 遮盖第3个图窗多出的x轴
line([limx1(2) limx3(2)],[ylimN2(1) ylimN2(1)],'color','w','parent',ha0(3),'clipping','off');

ylimN3 = get(ha0(4),'ylim');
for k = (2+N1+N2):(1+N1+N2+N3)
ha(k) = ha0(4);
h(k) = line(x,yA(k,:),'color',ycl{k},'parent',ha(k));
ylimN3(1) = min(ylimN3(1),min(yA(k,:)));
ylimN3(2) = max(ylimN3(2),max(yA(k,:)));
end
% 对齐刻度
ord  = round(log10(ylimN3(2))) - 1;
ord = 10^ord;
ylimN3(1) = floor(ylimN3(1)/ord)*ord;
ylimN3(2) = floor(ylimN3(2)/ord)*ord + ord;
TickArrray = linspace(ylimN3(1),ylimN3(2),nbT);
TickArrray2 = roundn(TickArrray,-1);
set(ha0(4),'ylim',ylimN3,'ytick',TickArrray,'yTickLabel',TickArrray2);
%set(ha0(4),'ylim',ylimN3)

% 遮盖第4个图窗多出的x轴
%line([limx1(2) limx3(2)],[limy3(1) limy3(1)],'color',cfig,'parent',ha0(3),'clipping','off');
line([limx1(1) limx4(1)],[ylimN3(1) ylimN3(1)],'color','w','parent',ha0(4),'clipping','off');


set(get(ha(1),'ylabel'),'string','n (r/min)')
set(get(ha(2),'ylabel'),'string',N1str)
set(get(ha0(3),'ylabel'),'string',N2str)
set(get(ha0(4),'ylabel'),'string',N3str)
set(get(ha(1),'xlabel'),'string',xstr)

legend(h,ystr,'location','northwest');

end

使用示例

        编写主函数,在主函数中调用Yaxis4N为例:

% 主函数
clear 

x = linspace(0,10,500);

y1 = x;

y2 = 2*x;

y3 = 30*x;
y4 = 40*x;

y5 = cos(x);

yA = [y1;y2;y3;y4;y5];
N1 = 1; N2 = 2; N3 = 1; % 原轴1组,右轴1组,右外轴2组,左轴1组数据
N1str = 'y2 (单位b)'; N2str = 'y3,y4 (单位c)'; N3str = 'y5 (单位d)';

figure
% Yaxis4N (x数据, y数据总矩阵, 右轴线条数, 右轴标注(带单位), 右外轴线条数, 右外轴标注(带单位), 左轴线条数, 左轴标注(带单位),...
%   {线条颜色}, x数据名(带单位), {y数据名});
[ha,h] = Yaxis4N(x,yA,N1,N1str,N2,N2str,N3,N3str,...
    {'k',[1 0.38 0],'b','g','r'},'x(单位a)',{'y1=x','y2=2x','y3=30x','y4=40x','y5=cosx'});

几点注意:

        1. 适用于所有数据均共用唯一横坐标的情况;

        2. 若需修改原始y轴的标注,需在函数文件内统一修改;

        3. 若需在主函数中规定曲线线形,需在函数文件内添加变量;

        4. 当前版本原始y轴仅能绘制一组数据,其余三个纵轴(右、右外、左)可绘制多组;

        5. 若需隐藏左下角、右下角的小段横轴,则修改函数文件中矩形颜色参数与背景色相同。

  • 19
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sleepy Tiger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值