概要
グラフィクスオブジェクト h を最前面に配置するには以下のコードを追加します.
legend("AutoUpdate","off"); % 凡例を表示し自動更新を停止
uistack(h, 'top'); % h を最前面に配置
はじめに
MATLAB の hold on で複数の線を重ね書きするとき,基本的には後から追加した線が手前に表示されます.
そのため,「適当な順番で plot したら,ある線が別の線の後ろに隠れてしまった...」という問題が生じる場合があります.
例えば以下のグラフでは,青線が橙色の線の後ろに隠れてしまって全く見えません🥲
x = 0:0.01:10;
y1 = sin(x);
y2 = y1 + 0.1 * randn(size(y1));
y3 = 4*y1;
figure;
hold on;
h1 = plot(x, y1, 'LineWidth', 2, DisplayName= "h1"); % h2 の後ろに隠れて見えない...
h2 = plot(x, y2, 'LineWidth', 2, DisplayName= "h2");
h3 = plot(x, 2*y1, 'LineWidth', 2, DisplayName= "h3");
ylim("padded")
legend;
もちろん,青線(h1)を最後にプロットするようにコードを修正すればこの問題は解決できます.
しかし,見た目上の前後を調整するためだけに plot 部分のコードを変更するのは面倒,というケースは多々あります.例えば,for 文を使って大量の plot を 重ね書きしている状況では,for 文のインデックスを書き換える,ちょっと面倒な修正が必要になってしまいます.
そんなとき,こう思うはず...!
🤔 「パワポの『最前面に配置』のノリで h1 を手前に持ってこれないかなぁ」
『最前面に配置』みたいなことをする
uistack 関数 を使えば,パワポの『最前面に配置』のように,プロットした線の順番を後から制御できます!
以下のコードを追加しましょう
uistack(h1, 'top'); % h1 を最前面に配置
コード全体
x = 0:0.01:10;
y1 = sin(x);
y2 = y1 + 0.1 * randn(size(y1));
y3 = 4*y1;
figure;
hold on;
h1 = plot(x, y1, 'LineWidth', 2, DisplayName= "h1"); % h2 の後ろに隠れて見えない...
h2 = plot(x, y2, 'LineWidth', 2, DisplayName= "h2");
h3 = plot(x, 2*y1, 'LineWidth', 2, DisplayName= "h3");
ylim("padded")
legend;
uistack(h1, 'top'); % h1 を最前面に配置
青線が一番手前に来てくれました!これでひとまず,青線が橙色の線に隠れて見えない問題は解決しました!
しかし,よく見ると凡例が h2,h3,h1 の順番になってしまっています.これは,デフォルト設定では凡例の順番が座標軸上の表示順に合わせて自動的に並び替えられるためです.
次のセクションではこの問題に対処します.
凡例の順番は変えたくない
凡例の順番を制御する方法はいくつかありますが,ここでは二つの方法を紹介します.
方法その1:legend の target を指定する
丁寧な方法として,legend にハンドルを並べた配列 [h1,h2,h3] を渡す方法を紹介します.このテクニックは凡例の内容を制御したい状況で広く役立ちます.
legend([h1,h2,h3]); % h1, h2, h3 の順で凡例を表示
uistack(h1, 'top'); % h1 を最前面に配置
コード全体
x = 0:0.01:10;
y1 = sin(x);
y2 = y1 + 0.1 * randn(size(y1));
y3 = 4*y1;
figure;
hold on;
h1 = plot(x, y1, 'LineWidth', 2, DisplayName= "h1"); % h2 の後ろに隠れて見えない...
h2 = plot(x, y2, 'LineWidth', 2, DisplayName= "h2");
h3 = plot(x, 2*y1, 'LineWidth', 2, DisplayName= "h3");
ylim("padded")
legend([h1,h2,h3]); % h1, h2, h3 の順で凡例を表示
uistack(h1, 'top'); % h1 を最前面に配置
方法その2:legend の AutoUpdate を off にする
続いてお手軽な方法を紹介します.legend の AutoUpdate オプションを "off" に設定することで凡例の自動更新を停止します.これにより,legend を表示した後に h1 を最前面に配置しても,その影響が凡例に及ぶことを回避します.
legend("AutoUpdate","off"); % 凡例を表示し自動更新を停止
uistack(h1, 'top'); % h1 を最前面に配置
コード全体
x = 0:0.01:10;
y1 = sin(x);
y2 = y1 + 0.1 * randn(size(y1));
y3 = 4*y1;
figure;
hold on;
h1 = plot(x, y1, 'LineWidth', 2, DisplayName= "h1"); % h2 の後ろに隠れて見えない...
h2 = plot(x, y2, 'LineWidth', 2, DisplayName= "h2");
h3 = plot(x, 2*y1, 'LineWidth', 2, DisplayName= "h3");
ylim("padded")
legend("AutoUpdate","off"); % 凡例を表示し自動更新を停止
uistack(h1, 'top'); % h1 を最前面に配置
いずれの方法を用いても,凡例は h1,h2,h3 の順で,見た目上は h1 を最前面に配置することができました!
むすび
本記事では MATLAB でパワポの「最前面に配置」みたいなことをする方法を紹介しました.お役に立てば幸いです.
東京農工大学 MATLAB 学生アンバサダー K.M.(@km_MATLAB_Amb )


