【问题标题】:Looping through columns to make subplots遍历列以制作子图
【发布时间】:2015-05-14 21:26:45
【问题描述】:

我有一个xls 格式的光谱吸收矩阵,其中第 1 列作为波长,第 2:3 列作为水柱中来自 depth1 的粒子的相关吸收光谱。 2:3 是重复的,因此必须将它们绘制在一起。接下来,我有 4:5 列,再次复制水柱中来自 depth2 的粒子的吸收光谱。然后是depth3、depth4等的数据。矩阵是1001行13列。

我想在一个图中有 3 个子图(深度 1、深度 2 和深度 3),每个子图包含每个深度的 2 个重复光谱。

我试图遵循对this question 的出色响应,但这给了我每个子图一条线,但我想绘制两条线(重复光谱)。所以我做了以下操作,但我只能得到 3 个子图:

[num,txt,raw]=xlsread('ANACONDAS2010-ST1.xls');
legendCell=cellstr(txt);
figure
subplot(3,1,1)
plot(num(:,1), num(:,2:3),'r');grid on; box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(2:3)),legend boxoff 

subplot(3,1,2)
plot(num(:,1), num(:,4:5),'b');grid on; box on; xlabel('Wavelength'),   ylabel('Absorbance'),legend(legendCell(4:5)), legend boxoff 

subplot(3,1,3)
plot(num(:,1), num(:,6:7),'g');grid on; box on; xlabel('Wavelength'),  ylabel('Absorbance'),legend(legendCell(6:7)), legend boxoff  

title('STATION 1','fontweight','bold','fontsize',16);

但是正如你所看到的,这只给了我 1 个带有 3 个子图的图形,其余的深度(d4、d5、d6)仍未绘制,因为我无法指定它们,

因为我的脚本又长又麻烦,我本来希望通过一个循环来运行它,但是尽管与第二个答案中提供的代码作斗争,我还是不知道该怎么做,我有点理解,不像第一个。

【问题讨论】:

    标签: matlab plot subplot


    【解决方案1】:

    更新答案 代码的插入版本 V2

    V2 版本的代码允许显示无限对的数据,而且比 V1 更简单。

    % Generation of example data
    num=1:33;
    number_of_data_colums=14;
    num=[num' rand(length(num),number_of_data_colums)];
    % Generation of legend string
    for i=1:number_of_data_colums
       legendCell{i}=['Absor. ' num2str(i)];
    end
    % Get the size of data to be plotted (columns from 2 to ...)
    [r,c]=size(num);
    n_data=floor((c-1)/2);
    % Define the number of data to be plotted in each subplt
    data_x_plot=2;
    % Consistency check: if the number of column data is not even generate an
    % error message and exit
    if(n_data*2 ~= (c-1))
       error('Number of data columns is not even')
    else
    % Define the number of subplot of each figure
    n_sub_plot=3;
    % Subplot and figure counters
    s_plot_cnt=1;
    fig_cnt=1;
    % Create the first figure
    figure
    % External loop on figures
    for i=2:2:n_data*2
    % If three subplot have been added to a figure, open a new figure
       if(s_plot_cnt == 4)
    % The Title is assigne to the first subplot of each figure   
          title(ax(fig_cnt,1),['STATION ' num2str(fig_cnt)],'fontweight','bold','fontsize',16);
          s_plot_cnt=1;
          fig_cnt=fig_cnt+1;
          figure
       end
          ax(fig_cnt,s_plot_cnt)=subplot(n_sub_plot,1,s_plot_cnt);
    % The indices of columns to be plotted are computed automatically
          plot(num(:,1), num(:,i:i+1));
          grid on;
          box on;
          xlabel('Wavelength')
          ylabel('Absorbance')
    % add legend      
          legend(legendCell(i-1:i),-1)
    % Increment subplot's counter      
          s_plot_cnt=s_plot_cnt+1;
    %       legend boxoff
       end
    end
    % Add the last title
    title(ax(fig_cnt,1),['STATION ' num2str(fig_cnt)],'fontweight','bold','fontsize',16);
    

    上一个答案和 代码版本 V1

    我不确定我是否理解了您的问题,但是,如果您有 6 对数据并且想要 3 个子图,则需要 2 个数字。

    我已经修改了您的原始脚本,以便自动确定您需要的图形数量,生成子图并在每个子图中绘制 2 组数据。

    更新的代码 - 现在带有图例

    % Generation of example data
    num=1:33;
    num=[num' rand(length(num),12)];
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %    UPDATED CODE STARS HERE
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % Generation of legend string
    legendCell{1}='Wavel';
    for i=2:13
       legendCell{i}=['Absor. ' num2str(i)];
    end
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %    UPDATED CODE ENDS HERE
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %
    % Get the size of data to be plotted
    [r,c]=size(num);
    % Define the number of data to be plotted in each subplt
    data_x_plot=2;
    % Define the number of subplot of each figure
    n_sub_plot=3;
    % Evaluate the number of figures to be created
    n_fig=(c-1)/(data_x_plot*n_sub_plot);
    % Define the index of data columns
    idx=[2:2:c-1];
    idx=reshape(idx,n_sub_plot,data_x_plot)';
    % External loop on figures
    for i=1:n_fig
       figure
    % Internal loop on subplots   
       for j=1:n_sub_plot
    % The subplot indices are computed automatically
          ax(i,j)=subplot(n_sub_plot,1,j);
    % The indices of columns to be plotted are computed automatically
          plot(num(:,1), num(:,idx(i,j):idx(i,j)+1));
          grid on;
          box on;
          xlabel('Wavelength')
          ylabel('Absorbance')
    % add legend      
          legend(legendCell(idx(i,j):idx(i,j)+1),-1)
    %       legend boxoff
       end
    % The Title is assigne to the first subplot of each figure   
       title(ax(i,1),['STATION ' num2str(i)],'fontweight','bold','fontsize',16);
    end
    

    给定一组 12 列数据,这是输出:

    更新的图表,带有图例

    【讨论】:

    • 很好的答案。我正要写一个答案,但我对措辞很困惑,所以我放弃了哈哈。 +1。
    • 非常感谢 - 我非常感谢拉法。我有一个问题要问 - 我如何为每个子图添加一个图例,图例是每列的标题,即第一行。我也很抱歉没有清楚地说明问题。
    • 添加图例,使用legend函数;你已经在你发布的代码中做到了。因为我没有可以从中读取它的 Excel,所以我已经提交了它。不过,我已经更新了答案中的代码(我需要生成一些文本);在对legend 的调用中添加-1 允许您将图例框放在图形旁边(有关更多信息,请参阅MatLab 帮助)。我还更新了答案中的图像。希望这会有所帮助。
    • 非常感谢 Raffa,我真的很感激,因为我不仅得到了我的代码,而且实际上我第一次学会了使用循环!!!你能否澄清一件让我有点困惑的事情:在'idx = reshape(idx,n_sub_plot,data_x_plot)'这一行中 - 我知道你使用了转置符号,但我无法理解这行背后的逻辑。对不起!
    • 很抱歉打扰你 Raffa,但当我有 10 列时遇到了问题,我怀疑这是因为现在 n_fig 变为 1.6667。我不知道如何解决这个问题,因为我得到一个错误:>> idx=reshape(idx,n_sub_plot,data_x_plot)' Error using reshape To RESHAPE the number of elements must not change
    【解决方案2】:

    也许您应该在添加新地块时使用Hold 来保留当前地块。 所以你的代码应该是这样的:

    [num,txt,raw]=xlsread('ANACONDAS2010-ST1.xls');
    legendCell=cellstr(txt);
    figure
    subplot(3,1,1)
    plot(num(:,1), num(:,2),'r');grid on;
    hold on;
    plot(num(:,1), num(:,3),'m');
    box on; xlabel('Wavelength'), ylabel('Absorbance'),legend(legendCell(2:3)),legend boxoff 
    
    subplot(3,1,2)
    plot(num(:,1), num(:,4),'b');
    hold on;
    plot(num(:,1), num(:,5),'c');
    grid on; box on; xlabel('Wavelength'),   ylabel('Absorbance'),legend(legendCell(4:5)), legend boxoff 
    
    subplot(3,1,3)
    plot(num(:,1), num(:,6),'g');
    hold on;
    plot(num(:,1), num(:,7),'k');
    grid on; box on; xlabel('Wavelength'),  ylabel('Absorbance'),legend(legendCell(6:7)), legend boxoff  
    
    title('STATION 1','fontweight','bold','fontsize',16);
    

    【讨论】:

    • 在这种情况下,hold on 将产生与 OP 所做的相同的事情。如果您为垂直轴绘制一个值矩阵,每列将代表一个单独的轨迹。您正在做的是使用hold on 单独绘制每一列以分隔痕迹。因此,您的代码将执行与 OP 相同的操作。
    • 嗨 rayryeng 我已经提高了评论的清晰度,因为我知道这不好。
    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多