Matlab繪圖(2)透過程式碼進行區域性放大繪圖、多檔案繪圖

發表於2024-04-17

Matlab進階繪圖

在這次的繪圖練習中,我們需要考慮一次性將所有資料檔案逐一讀入,然後對每幅圖圖片進行放大處理。

引數設定

這裡包括每幅圖的標題,圖例,讀入檔案的名稱,等等

title_d   = {'SMOP1','SMOP3','SMOP7','SMOP8'};              %指定每幅圖的標題
figname = {'SECSO','SPS','SNSGAII','LERD','TS2SparseEA'};   %指定需要讀入的檔名
led = {'S-ECSO','SPS','S-NSGA-II','LERD','TS2-SparseEA'};   %指定每幅圖片顯示的圖例(這裡每幅圖片包括多個曲線)
Marker = ['s','*','s','d','v'];                             %指定圖片裡每條曲線的形狀
idx = [1,3,7,8];                                            %指定子資料夾名稱,配合後面程式碼使用
dimension = {'1000d','3000d'};                              %指定子資料夾名稱,配合後面程式碼使用

除此之外,還有一項關鍵內容,就是需要指定放大的區域。

xl = {[0.4 0.5], [0.4 0.5],[0.4 0.5],[0.4 0.5]};            %指定每幅圖x軸放大的區域
yl = {[0.5 0.75], [0.5 0.75],[0.8 1.2], [0.8 1.5]};         %指定每幅圖y軸放大的區域

至此我們完成大致準備工作
這裡

資料匯入

這裡我們暫時只考慮一幅圖片的資料匯入,之後我會把完整程式碼(多檔案資料讀取)放出。這裡我們的資料來源是Matlab中的Fig檔案,當然如果你有直接資料,然後可以忽略這一操作步驟。

xdata = [];
ydata = [];
% 資料匯入
for j = 1:5
    %開啟Fig, ['./MyPlot/Objective_Value_Distribution/figs/TS2SparseEA/',dimension{d},'/SMOP',num2str(idx(i)),'/',figname{j},'.fig']表示把資料裡的元素拼接成一個路徑。
    %invisible表示開啟圖片時,不顯示圖片,若該為visible則會開啟此圖片(建議不要開)
    fig = openfig(['./MyPlot/Objective_Value_Distribution/figs/TS2SparseEA/',dimension{d},'/SMOP',num2str(idx(i)),'/',figname{j},'.fig'],'invisible');
    lines    = findobj(fig, 'type', 'line'); %找到fig裡面所有的曲線
    xdata    = [xdata;get(lines, 'XData')];  %get(lines, 'XData'/'YData')表示獲取所有曲線的橫座標和縱座標
    ydata    = [ydata;get(lines, 'YData')];
end

繪製全圖

%由於我們要在一個fig裡面繪製兩幅圖(原圖和放大圖),因此需要兩個座標軸
figure;
% 建立全圖的座標軸,並指定其位置'Position'
ax1 = axes('Position', [0.15 0.15 0.75 0.75]);

%設定當前軸為全圖的座標軸
axes(ax1);

%曲線繪製,共有5條,box on表示顯示圖的框線,可以自己去掉看看變化。hold on表示不建立新的fig繼續在當前fig上繪製其他曲線。
for j = 1:5
    scatter(xdata(j, :), ydata(j, :),'Marker',Marker(j),'SizeData',60,LineWidth=1.5);
    box on;
    hold on;
end
title(title_d{i});

%設定當前圖的字型等資訊
set(gca,'FontName','Times New Roman','FontSize',17);

%設定xlabel和ylabel的文字,這裡使用latex顯示
xlabel('$f_1$', 'Interpreter', 'latex');
ylabel('$f_2$', 'Interpreter', 'latex');
%顯示當前軸的圖例
legend(led);

繪製放大圖

有時候,由於原圖裡面各個曲線直接的距離很近,因此無法顯出顯著區別,在這種情況下,我們就需要對原圖進行區域性區域放大並繪製放大圖以體現各曲線之間的細微區別。

%設定放大圖的座標軸
ax2 = axes('Position', [0.5 0.2 0.3 0.35]);
%將當前軸設定為放大軸
axes(ax2);
for j = 1: 5
    %找到符合x軸放大區域和y軸放大區域的x座標下標
    zoom_in_idx = (xdata(j, :) >= xl{i}(1)) & (xdata(j, :) <= xl{i}(2)) & (ydata(j, :) >= yl{i}(1)) & (ydata(j, :) <= yl{i}(2));
    %得到x座標和y座標
    xdata_zoom_in{j} = xdata(j, zoom_in_idx);
    ydata_zoom_in{j} = ydata(j, zoom_in_idx);
end

%區域性放大麴線繪製,hold off表示第一張fig已經畫完了,下面再次繪圖時會建立一個新的fig而不是當前的。
for j = 1:5
    scatter(xdata_zoom_in{j}, ydata_zoom_in{j},'Marker',Marker(j),'SizeData',150,LineWidth=1.5);
    box on;
    hold on;
end
%隱藏放大圖的x軸和y軸,不顯示其他資訊,可以自己去掉看看變化。
set(gca, 'xtick',[], 'ytick',[]);
hold off;

最終效果展示

圖片名稱 圖片名稱 圖片名稱 圖片名稱

完整程式碼

clear;
clc;
% for TS2-SparseEA
title_d   = {'SMOP1','SMOP3','SMOP7','SMOP8'};
figname = {'SECSO','SPS','SNSGAII','LERD','TS2SparseEA'};
led = {'S-ECSO','SPS','S-NSGA-II','LERD','TS2-SparseEA'};
Marker = ['s','*','s','d','v'];
idx = [1,3,7,8];
dimension = {'1000d','3000d'};

% for TSD-MOEA
% title_d   = {'Sparse NN','Sparse SR','Sparse PO'};
% figname = {'MOEAPSL','SECSO','PMMOEA','TSDMOEA'};
% led = {'MOEA/PSL','S-ECSO','PM-MOEA','TSD-MOEA'};
% Marker = ['s','*','s','d'];
% color = {[214/255,232/255,121/255],[247/255,202/255,69/255],[82/255,198/255,160/255],[246/255,177/255,120/255]};
% idx = [1,3,7];
% dimension = {'3000d','RealWorld'};
% problem = {'NN','SR','PO'};
d = 2;

% zoom range
%self define
% TS2
xl = {[0.4 0.5], [0.4 0.5],[0.4 0.5],[0.4 0.5]};
yl = {[0.5 0.75], [0.5 0.75],[0.8 1.2], [0.8 1.5]};

% TSD
% xl = {[0 0.03], [0.05 0.1],[1.57e-7 8.33e-7]};
% yl = {[0.15 0.25], [0.78 0.82],[0.01 0.02]};
% label for each fig
% x_label = {'Complexity of neural network', 'Sparsity of reconstructed signal', 'Risk'};
% y_label = {'Training error', 'Loss of reconstructed signal', 'Return'};


for i = 1:4
    
    xdata = [];
    ydata = [];
    % 資料匯入
    for j = 1:5
        fig = openfig(['./MyPlot/Objective_Value_Distribution/figs/TS2SparseEA/',dimension{d},'/SMOP',num2str(idx(i)),'/',figname{j},'.fig'],'invisible');
        % TSD
        % fig = openfig(['./MyPlot//Objective_Value_Distribution/figs/TSDMOEA/',dimension{d},'/',problem{i},'/',figname{j},'.fig'],'invisible');
        lines    = findobj(fig, 'type', 'line');
        xdata    = [xdata;get(lines, 'XData')];
        ydata    = [ydata;get(lines, 'YData')];
    end

    % 繪製全圖
    figure;
    ax1 = axes('Position', [0.15 0.15 0.75 0.75]);
    axes(ax1);
    for j = 1:5
        scatter(xdata(j, :), ydata(j, :),'Marker',Marker(j),'SizeData',60,LineWidth=1.5);
        box on;
        hold on;
    end
    title(title_d{i});
    set(gca,'FontName','Times New Roman','FontSize',17);
    xlabel('$f_1$', 'Interpreter', 'latex');
    ylabel('$f_2$', 'Interpreter', 'latex');

    % TSD
    % xlabel(x_label{i});
    % ylabel(y_label{i});
    legend(led);


    % 繪製放大圖
    ax2 = axes('Position', [0.5 0.2 0.3 0.35]);
    axes(ax2);

    % 設定要放大的x軸範圍
    % 找到範圍內的資料點
    for j = 1: 5
        zoom_in_idx = (xdata(j, :) >= xl{i}(1)) & (xdata(j, :) <= xl{i}(2)) & (ydata(j, :) >= yl{i}(1)) & (ydata(j, :) <= yl{i}(2));
        xdata_zoom_in{j} = xdata(j, zoom_in_idx);
        ydata_zoom_in{j} = ydata(j, zoom_in_idx);
    end

    for j = 1:5
        scatter(xdata_zoom_in{j}, ydata_zoom_in{j},'Marker',Marker(j),'SizeData',150,LineWidth=1.5);
        box on;
        hold on;
    end
    set(gca, 'xtick',[], 'ytick',[]);
    hold off;
end

相關文章