MATLABでのGUI作成に関する小ネタです。
使用環境: MATLAB R2017a
使用したツールボックス: n/a
課題
時間変化がある2次元プロットで時間変化を見たい、3次元データのスライスプロットを描く際にスライス位置を移動させて描画したい。そんな時に便利なスライダーで操作をMATLABで実装してみたいと思います。
MATLABのQ&AサイトMATLAB Answersにも投稿がありますが、スライダーバーを操作して描画をいじる方法は意外と奥が深い。スライダーを操作する場合、uicontrol に指定する Callback 関数はスライダーをマウスで移動させ終わったときにしか実行されないので、スライダーをマウス移動させながらプロットを変化させたい場合には使えない。。
マウスがクリックされた状態の場合に処理を実施できる WindowButtonMotionFcn で実現も可能でばあるけどもあまり美しくない。。
参考:スライダーを動かして、マウスを押したままの状態でグラフ位置を調整するなどの処理を入れることは可能でしょうか?
addlistener
ここでは addlistenerを使ってみます。詳細は イベントとリスナーの概要に説明されていますので省略しますが、要はスライダバーが変化したというイベントを検知して、プロットを変化させる処理を逐次実行します。この機能を使ってスライダーバーの操作を動的にプロットに反映させてみます。
データはスカラー ボリューム データの可視化の技法で使われている「人の頭部の 27 個のイメージ スライスである一組の MRI データセット」を使っています。MATLABに入ってるデータなので、このままコピペで実行できるはず。
% データ読み込み
load mri
D = squeeze(D);
% Plot
figure(1)
[~,handle_surf] = contour(D(:,:,1));
title('スカラー ボリューム データの可視化');
% スライダーバー作成
handle_slider = uicontrol('Style','slider','Position',[10 50 20 340],'Min',1,'Max',27,'Value',1);
% イベントリスナーの作成
addlistener(handle_slider,'Value','PostSet',@(event,obj) update(event,obj,D,handle_surf,handle_slider));
% 描画のアップデート処理用関数
function update(event,obj,D,handle_surf,handle_slider)
index = round(handle_slider.Value);
handle_surf.ZData = double(D(:,:,index));
end