Help us understand the problem. What is going on with this article?

MATLAB でインタラクティブな DashBoard をつくってみよう。

More than 1 year has passed since last update.

はじめに

データの可視化については、世の中に数多くのツールがあります。そんな中でも、ユーザとやりとりができるような、簡単なダッシュボードをつくってみましょう。MATLAB でね。

イメージはこんな感じ↓
DashBoard
2019-08-16_10-18-38.gif

実行環境

MATLAB (R2019a) のみ!

結論から

先にポイントとなるところだけ書いておきますね。

  • データの取り込みに迷ったら インポートツール を使ってみる
  • 対話型の コールバック を使ってみる
  • 使用する グラフの特性にあわせて、データを変更する

まずはデータの取り込みから

今回は、このデータを使いましょうか。総務省統計局からもってきます。人口を、各都道府県別に 年少人口(0~14歳)、生産年齢人口(15~64歳)、老年人口(65歳以上)で分けています。

都道府県,年齢3区分別人口(エクセル:30KB)

上記サイトから Excel をダウンロードしたら、適当なフォルダに置きます。まずはどんなファイルなのか、そのまま読めそうなのか、確認してみましょう。

MATLAB 上でそのファイルを右クリック → [データのインポート] で インポートツール が開きます。データの確認と、欲しいデータの選択をしましょう。今回はテーブルでよさそうですね。あとは、列名と変数名あたり、適当に変えましょうか。こんな感じで。
import.jpg
データをワークスペースへインポートする際、スクリプトの生成 をすると、インポートツール上で行った手順が MATLAB プログラムとして生成されます。今後同じようなファイルに対して解析をするときは、生成されたプログラムが使えそうですね。

createDashBoard.m
function createDashBoard
%% インポート オプションの設定
opts = spreadsheetImportOptions("NumVariables", 5);
% シートと範囲の指定
opts.Sheet = "02-06";
opts.DataRange = "B7:F53";
% 列名と型の指定
opts.VariableNames = ["Pref", "All", "Young", "Working", "Elderly"];% 列名
opts.SelectedVariableNames = ["Pref", "All", "Young", "Working", "Elderly"]; % 選択した列名
opts.VariableTypes = ["string", "double", "double", "double", "double"];% 各列のデータ型
%% データのインポート
pop = readtable("n190200600.xls", opts, "UseExcel", false);

対話型のコールバック

MATLAB では Figure 上にグラフを描きます。この Figure にはいくつかコールバックが用意されており、ユーザからのアクションを反映させることができます。今回であれば、マウスをクリックした時点で反応がほしいので、WindowButtonDownFcn を使用します。

f = figure;
f.WindowButtonDownFcn = @downfun;

使用するグラフについて

今回は、棒グラフ(bar)円グラフ(pie) を使用します。上で紹介した WindowButtonDownFcn では、これらグラフの更新をすることになります。そこで、それぞれどんな特徴があるか見てみましょう。

■ 棒グラフ

% 棒グラフの描画
b = bar(ax1,pop10.All,'FaceColor','flat'); % Top10の総人口
>> b
b = 
  Bar のプロパティ:

    BarLayout: 'grouped'
     BarWidth: 0.8000
    FaceColor: 'flat'
    EdgeColor: [0 0 0]
    BaseValue: 0
        XData: [1×10 double]
        YData: [1×10 double]

■ 円グラフ

% 円グラフの描画
p = pie(ax2,sum(pop10{:,3:5})); % Top10における、年少人口、生産年齢人口、老年人口の割合
>> p
p = 
  1×6 graphics 配列:

  1 から 4 の列
    Patch    Text     Patch    Text 
  5 から 6 の列
    Patch    Text 

棒グラフは、それぞれの都道府県(XData)における人口(YData)を持ちます。クリック時には、これら YData を更新してあげればよさそうですね。ただ、円グラフはそのような構成になっていないので、今回は再度描きなおします。

createDashBoard.m
function createDashBoard
%% インポート オプションの設定
opts = spreadsheetImportOptions("NumVariables", 5);
% シートと範囲の指定
opts.Sheet = "02-06";
opts.DataRange = "B7:F53";
% 列名と型の指定
opts.VariableNames = ["Pref", "All", "Young", "Working", "Elderly"];               % 列名
opts.SelectedVariableNames = ["Pref", "All", "Young", "Working", "Elderly"]; % 選択した列名
opts.VariableTypes = ["string", "double", "double", "double", "double"];         % 各列のデータ型

%% データのインポート
pop = readtable("n190200600.xls", opts, "UseExcel", false);

%% データのソートとTop10の抽出
pop_sorted = sortrows(pop,'All','descend');
pop10 = pop_sorted(1:10,:)

%% データの描画
f = figure;
f.WindowButtonDownFcn = @downfun;
% 軸の設定
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);
% 棒グラフの描画
b = bar(ax1,pop10.All,'FaceColor','flat'); % Top10の総人口
cdata = b.CData;
% x軸のラベル設定
ax1.XTickLabel = pop10{:,1}; 
ax1.XTickLabelRotation = 45;
ax1.Position = [0.13 0.11 0.420811785929044 0.786142433234422]; 
% 円グラフの描画
p = pie(ax2,sum(pop10{:,3:5})); % Top10における、年少人口、生産年齢人口、老年人口の割合
 [p(1:2:5).Tag] = deal('3','4','5');
% テキストの描画
 x = 0.5; y = 0.9; 
txt(1)= text(ax1, x, y,            '全体',                                 'Units', 'normalized');
txt(2)= text(ax1, x, y-0.05,  ['年少人口:', p(2).String], 'Units','normalized');
txt(3)= text(ax1, x, y-0.1 ,   ['生産人口:', p(4).String], 'Units','normalized');
txt(4)= text(ax1, x, y-0.15,  ['老年人口:', p(6).String], 'Units','normalized');

function downfun(obj,event)
    delete(txt) % テキストの消去
    city = '全体';
    co = gco; % 選択したオブジェクト
    ca = gca; % 選択した軸
    cp = round(ca.CurrentPoint); % 選択した軸の位置
    pref = cp(1,1); 
    b.CData = cdata;
    % 棒グラフに触れたとき
    if (isempty(co.Tag)) && (1 <= pref && pref <= 10)
        % 一旦デフォルト表示に戻す
        p = pie(ax2,sum(pop10{:,3:5})); 
        b.YData = pop10.All;
        p = pie(ax2,pop10{pref,3:5}); % 円グラフの更新
        b.CData(pref,:) = [.5 0 .5]; % 選択した都道府県の色を変更
         city = pop10{pref,1};
    % 円グラフに触れたとき     
    elseif ~isempty(co.Tag)
        % 選択した人口の分布を表示
        b.YData = pop10{:,str2double(co.Tag)};
    % 上記以外に触れたとき
    else
        % デフォルト表示に戻す
        p = pie(ax2,sum(pop10{:,3:5})); 
        b.YData = pop10.All;
    end
    [p(1:2:5).Tag] = deal('3','4','5');
    if isempty(co.Tag)
        txt(1)= text(ax1, x, y,            '全体',                              'Units', 'normalized');
        txt(2)= text(ax1, x, y-0.05,  ['年少人口:', p(2).String], 'Units','normalized');
        txt(3)= text(ax1, x, y-0.1 ,   ['生産人口:', p(4).String], 'Units','normalized');
        txt(4)= text(ax1, x, y-0.15,  ['老年人口:', p(6).String], 'Units','normalized');
    end
end
end

結果

こんな感じになりました:blush:
2019-08-16_11-34-49.gif

kkado
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした