MATLAB:mファイルから空白領域(プロット、サブプロット)を削除し、サイズを設定して、鮮明な画像を保存します



Matlab Remove Blank Area Plot



(注:私が使用しているmalabのバージョンはMatlab 2018aです。)

1.アイデアの源
1.1需要の源 ****
絵を描くときは、単語の記事を編集するために保存する必要があり、保存された画像には大きな空白領域があり(画像の実際のコンテンツに比べてスペースが大きすぎる)、単語で手動でトリミングする必要があります。写真が多い場合は、繰り返す必要があり、各写真のサイズを一定に調整することは容易ではありません。
画像
1.2期待される結果



mファイルを使用して画像サイズを自動的に設定し、画像の周囲の空白部分を削除して、手動操作なしで鮮明な画像ファイルとして保存します。

2.軸の図と関連する概念



画像のサイズと空白領域を調整するには、最初に図の画像と軸オブジェクトのいくつかの重要な属性を理解する必要があります。

フィギュアオブジェクト :画像サイズは、プロパティPositionによって決定されます。

軸オブジェクト サイズと表示は、プロパティOuterPosition、TightInset、およびPositionによって決定されます。 TightInsetプロパティは、matlabによって自動的に決定され、手動で設定することはできません。



2.1プロット画像の特徴

次の図に示すように、MATLABのヘルプファイルに示されているように、プロット画像とその属性軸が定義されています。イントロダクションは、主にプロットによって描かれた絵の特徴に言及しています。

画像

2.2サブプロット画像の特徴

サブプロットで得られた画像では、境界が異なります。各サブ軸軸のOuterPositionは通常、図の位置と一致しません。また、各サブ画像のデータ範囲が異なるため、ラベルが占めるTightInsetのサイズも一般的に異なります。

画像

3.前任者の方法への参照

写真の周りの空白部分をなくすために、インターネットで広く使われている検索方法は2つあります。私はそれらを別々にテストしましたが、これら2つの方法にはまだ実際のアプリケーションには特定の問題があることがわかりました。 (上記のメソッド検証で使用されるサブプロットは、グラフごとに同じデータと曲線を持ち、各パラメーターの実際のデータ範囲が異なる可能性があるため、各サブプロットサブグラフのTightInsetとラベル付けが異なるため、アプリケーションの効果は次のようになります。満足のいくものではありません。)以下は私のテスト結果です:

参照方法1のURL: https://blog.csdn.net/shanchuan2012/article/details/53980288

画像
画像

空白は削除されていますが、座標位置の位置と幅および高さの属性を変更する過程で、軸xtickとytickの幅が異なり、各図の座標軸に一貫性がないことがわかります( OuterPositionサイズ)一貫性がありますが、TinghtInsetが同じサイズではないため、最終的な位置サイズが一貫性を失います)。

参照方法2のURL: https://ww2.mathworks.cn/matlabcentral/fileexchange/27991-tight_subplot-nh-nw-gap-marg_h-marg_w
画像内の軸とその注釈を正常に実現するには、関数の入力パラメータ(主に各座標軸と画像の周囲の空白との間のマージン)を手動で調整する必要があります。 )、プロセスを繰り返し試行する必要があり、使用するのは不便です。
画像
4.私の改善された方法
4.1考え
著者の経験を要約した後(上記の著者のおかげで)、空白領域を排除することは、matlabが描画した画像と設定の内部パラメーターを利用することだと思います。少し調整します。この方法の要点は次のとおりです。
(1)画像の空白の領域を見つけます
(2)各軸の位置の幅と高さを一定に保つ
(3)軸間の相対位置を変更しないでください
(4)TightInsetのサイズが同じです(軸ラベルが表示されていることを確認してください)
(5)各グラフのTightInsetの最大外側範囲をfigure.InnerPositionと一致させます。
画像
空白領域が見つかったら、次のステップは、アルゴリズムによって移動座標軸を実現し、座標軸範囲の幅と高さを増やして空白領域を埋め、主に次の3つのステップで空白領域の除去を完了します。
(1)四辺の空白部分の幅/高さを求めます
(2)空白領域の幅/高さの合計を各軸の軸に割り当てます。空白領域を埋められるように、幅と高さを増やして均等に配置します。
(3)各軸Axes.Positionの位置を調整し、パブリック最大境界の最大外側境界(すべての軸の青い点線のTightInset)と図位置境界が一致するように適切な距離を移動します。

4.2手順 (2つのmファイルに分割する必要があります。最初のmファイルが描画され、画像サイズが設定されます。2番目のmファイルは、空白領域を削除して画像が保存されるために使用されます。レガシーの問題については、セクション5を参照してください)
4.2.1空白部分を削除する機能

function [] = FcnRemoveWhiteSpaceV5(Hgcf,Axes) %*********************************************************************** % function description: Eliminate the blank area of ​​the figure by adjusting the size and position of the axis in the figure % parameter: Hgcf picture figure handle % Axes The coordinate axis handle of each submap subplot in the picture is the structure matrix of the Nrow*Ncol dimension % Axes(i,j) represents the axis object of the i-th row, j-th column %*********************************************************************** %--------------Automatically get the number of rows and columns of subplot ------------------------ Dimensions=size(Axes) Nrow=Dimensions(1) Ncol=Dimensions(2) %------------ To avoid the last picture being too crowded, set the percentage of white space around ------ WhiteSpaceLeftRatio=0.1 % sets the surrounding blank area leaving 10% not removed Ratio=1-WhiteSpaceLeftRatio %----------Get the position vector of TightInset for each axis --------- for i=1:Nrow for j=1:Ncol left=Axes(i,j).Position(1)-Axes(i,j).TightInset(1) bottom=Axes(i,j).Position(2)-Axes(i,j).TightInset(2) width=Axes(i,j).Position(3)+Axes(i,j).TightInset(1)+Axes(i,j).TightInset(3) height=Axes(i,j).Position(4)+Axes(i,j).TightInset(2)+Axes(i,j).TightInset(4) AxesTightInsetPosition(i,j).TightInsetPosition=[left bottom width height] end end %-------Calculate the blank area around the picture to get the width and height of the blank area that needs to be filled---- temp=AxesTightInsetPosition(1,1).TightInsetPosition(1) % seeking the leftmost margin for i=1:Nrow temp=min(temp,AxesTightInsetPosition(i,1).TightInsetPosition(1)) end WhiteLeft=temp % seeking the bottom blank temp=AxesTightInsetPosition(Nrow,1).TightInsetPosition(2) for j=1:Ncol temp=min(temp,AxesTightInsetPosition(Nrow,j).TightInsetPosition(2)) end WhiteBottom=temp % seeking the rightmost margin temp=AxesTightInsetPosition(1,Ncol).TightInsetPosition(1)+AxesTightInsetPosition(1,Ncol).TightInsetPosition(3) for i=1:Nrow temp=max(temp,AxesTightInsetPosition(i,Ncol).TightInsetPosition(1)+AxesTightInsetPosition(i,Ncol).TightInsetPosition(3)) end WhiteRight=1-temp % seeking the top margin temp=AxesTightInsetPosition(1,1).TightInsetPosition(2)+AxesTightInsetPosition(1,1).TightInsetPosition(4) for j=1:Ncol temp=max(temp,AxesTightInsetPosition(1,j).TightInsetPosition(2)+AxesTightInsetPosition(1,j).TightInsetPosition(4)) end WhiteTop=1-temp % finds the total blank and averages the height and width increments assigned to each axis WhiteWidth=WhiteLeft+WhiteRight WhiteHeight=WhiteBottom+WhiteTop deltaW=WhiteWidth/Ncol*Ratio deltaH=WhiteHeight/Nrow*Ratio %----------Adjust the position and width of the axis so that the blank area is filled ------------ % adjusts the width and height of each axis for i=1:Nrow for j=1:Ncol Axes(i,j).Position(3)=Axes(i,j).Position(3)+deltaW Axes(i,j).Position(4)=Axes(i,j).Position(4)+deltaH end end % adjust the horizontal position of each axis for i=1:Nrow for j=1:Ncol If(j==1) % first column: move WhiteLeft to the left Axes(i,j).Position(1)=Axes(i,j).Position(1)-WhiteLeft*Ratio Else % other columns Axes(i,j).Position(1)=Axes(i,j).Position(1)-WhiteLeft*Ratio+(j-1)*deltaW end end end % adjusts the vertical position of each axis for i=Nrow:-1:1 for j=1:Ncol If(i==Nrow) % Last line: Move WhiteBottom down Axes(i,j).Position(2)=Axes(i,j).Position(2)-WhiteBottom*Ratio Else % other lines Axes(i,j).Position(2)=Axes(i,j).Position(2)-WhiteBottom*Ratio+(Nrow-i)*deltaH end end end

4.2.2スクリプトファイルm1:

clc close all clear all % --------------------- nine map verification Hgcf=figure('color','w') subplot(331),plot(1:4,5000:5003),ylabel('αβμνλΨ')AX(1,1)=gca Subplot(332), plot(1:4,50:53),ylabel('Figure 2'),xlabel('t(s)'),AX(1,2)=gca Subplot(333), plot (1:4, 5000:5003), ylabel('Fig. 2'), AX(1,3)=gca Subplot(334), plot(1:4,5:8), ylabel('Fig. 2'), xlabel('t(s)'), AX(2,1)=gca Subplot(335), plot(1:4,5000000:5000003), ylabel('Fig. 2'), AX(2,2)=gca Subplot(336), plot(1:4,5:8), ylabel('Fig. 2'), xlabel('t(s)'), AX(2,3)=gca Subplot(337), plot (1:4, 5000:5003), ylabel('Fig. 2'), xlabel('t(s)'), AX(3,1)=gca Subplot(338), plot (1:4, 50:53), ylabel('Fig. 2'), AX(3,2)=gca Subplot(339), plot(1:4,5:8), ylabel('Fig. 2'), xlabel('t(s)'), AX(3,3)=gca % ----------Save the original picture (to matlab automatically adjust the picture spacing to eliminate overlap and leave enough time) -------- Print(Hgcf,'-dtiff','-r300', 'Original Image.png') %---------Image size setting and saved name parameter setting -------------------- Size Size PictureName='modified image .png' %----------Reset image size ----------------------------------- -- set(Hgcf,'units','pixel') Set(Hgcf,'position',[200 50 SizeWidth SizeHeight]) %Image window display size setting

4.2.3スクリプトファイルm2:

%-------------- eliminate blank area ---------------------- FcnRemoveWhiteSpaceV5(Hgcf,AX) %--------------save Picture---------------------- set(Hgcf, 'PaperPositionMode', 'auto') print(Hgcf,'-dtiff','-r300',PictureName)

4.3プログラム実行効果
さまざまなサブプロットのケースで検証されています。次の2つのケースがあります。
9つのマップ効果:
画像25番目のマップ効果: 画像

5.私の方法に関するレガシーの問題

5.1質問1:実行するには2つのmファイルに分割する必要があります

原因の分析:グラフィックが多数ある場合、サブプロットを描画するためのmファイルの操作中に、初期座標コンテンツがオーバーラップし、mファイルが終了した後、matlabが自動的に適応して画像の座標軸サイズ。自動調整後の軸の境界が一致しなくなりました。
下の図に示すように、Mファイルの操作中に取得された画像の境界:Mファイルの操作中に取得された画像の境界、座標境界のオーバーラップの存在
画像
Mファイルの実行が終了すると、Matlabは適応調整を実行します。実際の画像とグラフィックの境界は次のとおりであり、サブプロット間で重複はなくなりました。
画像
mファイルの実行中および実行後にデータを出力することにより、私の推測を検証しました。 画像

したがって、最後のmプログラムの描画後に最後のmファイルを実行し、次のmファイルを実行して座標軸を変更し、画像の空白領域を削除することしかできません。
実行するmファイルが2つない場合(および画像サイズが小さく設定されている場合)、サブプロット間で重なりが生じる可能性があります。

私は本当にこの問題を解決する方法を見つけることができません。期待される結果を実行するために取得できるmファイルは2つだけです。神々への解決策があれば、私はまだ私を啓発したいと思っています!

5.2質問2:画像を手動で縮小すると、表示が不完全になります
さらに、画像を手動でドラッグしてズームアウトすると、軸ラベルの境界が不完全に表示され、サブプロット間でオーバーラップします。私の本来の意図は画像のサイズを手動で変更することではなく、自動画像保存を実現するためにmファイルに完全に依存しているため、これは厳密には問題ではありません。

6.別の考え:
次のように手動で保存する方法があります。
(URL: https://blog.csdn.net/rookiew/article/details/51418661 )。

a)まず、Figureウィンドウの「ファイル」メニューを選択し、次に「セットアップのエクスポート」メニュー項目をクリックします。
b)最初に、長さの単位、高さ、幅など、エクスポートされた画像のサイズを設定します。ここでは、エクスポートされた画像に空白の境界線が含まれないように、「軸を拡張して図を塗りつぶす」をクリックすることを忘れないでください。
c)次の「レンダリング」は画像のレンダリング設定です。ここでの他のものは無視できます。主にdpiを設定する必要があり、dpiが高いほど、画像が鮮明になります。ペーパーワーカーにとって、多くのジャーナルは600dpi以上を必要としますが、これはすでに非常に明確です。
d)すべての設定が完了したら、右側の「apllytofigure」をクリックします。次に、[エクスポート]をクリックして、保存するパスと画像形式を選択します。

このようにして、空白領域を十分に排除することができますが、手動調整が必要であり、比較的面倒です。だから私は考えています、mファイルのエクスポート設定メニューを呼び出して「図を塗りつぶすために軸を拡張する」属性を選択し、画像を出力して白いエッジのない画像を取得できますか?