スライダーを使ってfigureを更新② | MATLAB事例紹介2

この記事ではスライダーを使ってfigureを更新する方法について説明しています。前回の続きから説明しますので、1から確認したい方は前回の記事をご確認ください。

この記事では下記の4から説明します。

1、パラメータの設定
2、地球と月の座標定義
3、figureの作成
4、figureにスライダーとテキストを設置
5、figure更新用の関数作成
6,スライダーを動かした際に更新用の関数呼び出す

4、figureにスライダーとテキストを設置

いよいよfigure更新用のスライダーを設置します。figureにユーザーインターフェースを追加するuicontrolを使用します。uicontrolのStyleに「slider」を指定することでグラフにスライダーを設置できます。また、Sliderと同時に日付を表示するためのテキストも配置するため、uicontrolのStyleに「text」を指定したものも追加します。

MATLAB
% figureにテキストを設置
d = uicontrol(fig1,'Style','text');
d.Position = [180 30 200 20];
d.String = 'Day 1';

% figureにスライダーを設置
c = uicontrol(fig1,'Style','slider');
c.Position = [20 30 200 20];
c.Value = 1;
c.Min = 1;
c.Max = 365;
c.SliderStep = [1/365 1/365];

2行目でuicontrolでtextをStyleに指定し、dという変数に代入しました。3行目でtextのPositionを指定しています。のPositionは左下からの[x位置 y位置 幅 高さ]の順でpixel単位で指定しています。4行目は表示する文字を指定しています。初回実行時はDay 1と表示したいのでd.String = ‘Day 1’としました。

7~12行目でスライダーを設置しています。7行目でスライダーを作成し、cという変数に代入しています。8行目でPositionを調整しています。

9~11行目はスライダーの初期値と最小、最大値を設定しています。1~365日のスライダーを作成するため、c.Min = 1, c.Max = 365としました。

12行目はスライダーのステップを調整しています。SliderStepは[minorstep majorstep]で指定し、minorstepは矢印を押したときのスライダーの変化量、majorstepはスライダーのバー(トラフ)を操作したときの変化量を指定します。0~1で指定するため1/365を指定し、1日ごとにスライダーで変化させるようにしました。

5、figure更新用の関数作成

figureとスライダーができましたので、figureを更新するための関数を作成します。

スライダーが操作されたときに毎回実行される関数です。関数で必要な機能は

  • スライダーの位置から、何日目かを取得する
  • Day ○○のテキストを更新する
  • rectangleで作成したオブジェクトの位置を変更する
  • 移動軌跡を更新する

figrureの更新には上記の4つの機能が必要です。作成した関数updatePositionは下記のとおりです。

MATLAB
%% 5,figure更新用関数を定義
function [] = updatePosition(c,d,Earth,Moon,h,x_earth,y_earth,r_earth,x_moon,y_moon,r_moon)
    i = uint32(c.Value);
    d.String = sprintf('Day %d',i);
    Earth.Position = [x_earth(i)-0.5*r_earth y_earth(i)-0.5*r_earth r_earth r_earth];
    Moon.Position = [x_moon(i)-0.5*r_moon y_moon(i)-0.5*r_moon r_moon r_moon];
    h(1).XData = x_earth(1:i);
    h(1).YData = y_earth(1:i);
    h(2).XData = x_moon(1:i);
    h(2).YData = y_moon(1:i);
end

入力引数には、「c,d:ライダーとテキスト」、「Earth, Moon:figureに表示している円」、「h:地球と月の軌跡」、「x_earth,y_earth,r_earth,x_moon,y_moon,r_moon:地球と月の位置と半径」を指定しています。

3行目でスライダーの位置から得られる値をiに代入しています。

4行目で設置したテキストの値をiを用いて更新します。sprintf関数を用いて「Day ○○」という形にしてd.Stringに代入しています。

5,6行目ではEarthとMoonの位置情報を更新しています。x_earth, y_earthは365列のベクトルでそれぞれの日付に対する位置情報が保存されています。そのためi番目の値を使用すると、Day iの位置にEarthとMoonを移動させることができます。

7~10行目では軌跡情報を更新しています。1~i列目までの値でplotすることでDay 1~Day iの軌跡を描くことができます。h(1)には地球の軌跡に対するplotが保存されており、h(1).XData, h(1).YDataにそれぞれ地球の軌跡のx座標ベクトル、y座標ベクトルが格納されています。その値を更新することで、軌跡を更新することができます。

6,スライダーを動かした際に更新用の関数呼び出す

スライダーを動かした際に、上記で作成したupdatePosition関数を呼び出す仕組みを作成します。そのコードが下記になります。

MATLAB
% 6,figure更新
c.Callback = @(src,event)updatePosition(c,d,Earth,Moon,h,x_earth,y_earth,r_earth,x_moon,y_moon,r_moon);

uicontrolのコールバック関数を実行する場合、2つの入力引数を渡します。これが、@(src,event)の「src,event」部分です。続きの「updatePosition(***)」で先ほど作成した関数を呼び出しています。入力引数は上で説明したとおりです。

Callbackで関数を呼び出す方法については、少し特殊な部分もあるのでこういう書き方するんだな程度でとどめておいてコピペして使用していただくのがいいと思います。まずは動かしてみるということが大事だと思います。

以上でスライダーを使ってfigureを更新できるようになりました。すべて理解することよりも、目的のデータで動かしてみて、わからない部分を調べたり読み返していただければと思います。

まとめ

2記事ににわたってスライダーを使ってfigureを更新する方法について説明しました。6つの細かいパートに分けて説明しましたので、理解しやすくなっていると思います。

今回作成したコードは実際にご依頼を受けて作成したコードを改変して題材としました。業務でも十分使用できる内容となっておりますので是非活用してください。

今回のように2次元の時系列データなどを確認する場合に便利です。また、スライダーを複数個設置して、2つ以上のパラメータの組み合わせを検討する際にも活用できると思います。

最後に作成したコードを載せておきますので、ぜひご活用ください。

MATLAB
clear;
clc;
close all;

%% 1,Parameter設定
Day = 1:1:365;

omega_earth = 2*pi / 365;

r_earth = 10;
r_r_earth = 100;

omega_moon = 2*pi / 27.3;
r_moon = 5;
r_r_moon = 20;

r_sun = 30;

%% 2,座標定義
x_earth = r_r_earth * cos(omega_earth*Day);
y_earth = r_r_earth * sin(omega_earth*Day);

x_moon = x_earth + r_r_moon * cos(omega_moon*Day);
y_moon = y_earth + r_r_moon * sin(omega_moon*Day);

%% 3,figure作成

fig1 = figure(1);
subplot(10,1,[1 9]);
hold on
h(1) = plot(x_earth(1),y_earth(1));
h(2) = plot(x_moon(1),y_moon(1));
Earth = rectangle('Position',[x_earth(1)-0.5*r_earth y_earth(1)-0.5*r_earth r_earth r_earth],'Curvature',[1 1],'FaceColor','b');
Moon = rectangle('Position',[x_moon(1)-0.5*r_moon y_moon(1)-0.5*r_moon r_moon r_moon],'Curvature',[1 1],'FaceColor','y');
Sun = rectangle('Position',[0-0.5*r_sun 0-0.5*r_sun r_sun r_sun],'Curvature',[1 1],'FaceColor','r');
axis equal
xlim([-150 150]);
ylim([-150 150]);

% 4,figureにテキストを設置
d = uicontrol(fig1,'Style','text');
d.Position = [180 30 200 20];
d.String = 'Day 1';

% 4,figureにスライダーを設置
c = uicontrol(fig1,'Style','slider');
c.Position = [20 30 200 20];
c.Value = 1;
c.Min = 1;
c.Max = 365;
c.SliderStep = [1/365 1/365];

% 6,figure更新
c.Callback = @(src,event)updatePosition(c,d,Earth,Moon,h,x_earth,y_earth,r_earth,x_moon,y_moon,r_moon);



%% 5,figure更新用関数を定義
function [] = updatePosition(c,d,Earth,Moon,h,x_earth,y_earth,r_earth,x_moon,y_moon,r_moon)
    i = uint32(c.Value);
    d.String = sprintf('Day %d',i);
    Earth.Position = [x_earth(i)-0.5*r_earth y_earth(i)-0.5*r_earth r_earth r_earth];
    Moon.Position = [x_moon(i)-0.5*r_moon y_moon(i)-0.5*r_moon r_moon r_moon];
    h(1).XData = x_earth(1:i);
    h(1).YData = y_earth(1:i);
    h(2).XData = x_moon(1:i);
    h(2).YData = y_moon(1:i);
end

関連記事

コメント

この記事へのコメントはありません。