【Blender×Python】時系列データからアニメーションをつくる

BlenderとPythonを組み合わせて時系列データを読み込ませ、時間によって変化するデータの動きを視覚化できます。
この方法を使うことにより、状態の変化などを説得力の強い形で表現することができます。
この記事ではその方法と留意点などを解説しています。

関連記事について

本記事では、関連記事として震災データの可視化に関する記事に言及している箇所がありますので是非合わせてお読みください。

時系列データとは

時系列データとは、時間を軸にして変化を示したものデータです。
例として一般的なのは、この後に使用する人口推移データなどがあります。
また、財務データなど、至る所で使用されているポピュラーな形式のデータです。

時系列データのアニメーション化

次の例では時系列データを取り込んでみたいと思います。
この例では二系列のデータを扱い、使用するのは日本の人口推移データです。
このデータは男女別のデータとして人口が記録されています。

Pythonコードの解説

この例で使用するのは次のコードです。

import bpy, csv

data = "FILEPATH" # (1)
current_scene = bpy.context.scene
target_object_male = current_scene.objects["Male"]
target_object_female = current_scene.objects["Female"]

scale = 20000000 # (2)
interval = 10 # (3)

current_frame = 1

with open( data, encoding='shift_jis' ) as csvfile:
reader = csv.reader( csvfile )
for i, row in enumerate( reader ):
if i < 6: continue # (4)
if i > 126: continue # (5)
_,_,male,female = row[0:4]
male_scale = float(male) / scale
female_scale = float(female) / scale
target_object_male.scale = (1,1,male_scale) # (6)
target_object_female.scale = (1,1,female_scale) # (7)
target_object_male.keyframe_insert(data_path="scale", frame=current_frame*interval) # (8)
target_object_female.keyframe_insert(data_path="scale", frame=current_frame*interval) # (9)
current_frame += 1

こちらもGistにコードを用意しました。

上記のポイントは以下の通りです。

  1. 震災データの例にならい、こちらにファイル名を指定してください。
  2. 今回は数字が大きいため、2000万分の1の縮尺で表示します。
  3. ここを10に指定しているため、10フレームごとにキーフレームを打つ、という指定になります。
  4. ダウンロードしたデータは最初の5行がデータではないので除外します。
  5. 127行目以降はデータでないので同様に除外します。
  6. 男性の値をスケール値として指定します。
  7. 女性の値をスケール値として指定します。
  8. 男性のオブジェクトに対してキーフレームを打ちます。
  9. 女性のオブジェクトに対してキーフレームを打ちます。

制作プロセス

表示用オブジェクトの準備

震災データの例ではデフォルトキューブを対象オブジェクトとして使用しましたが、今回は二つの系列データを採用するのでオブジェクトを用意します。
今回はそれぞれ「Male」、「Female」としました。
また、それぞれ、色を指定しました。

用意したオブジェクト

用意したオブジェクト

次に原点をオブジェクトの下部に指定します。
以下の手順で限定を指定します。

  1. 対象のオブジェクトの編集モードに入り対象としたい部分(この例の場合は最下部)を指定する。
  2. [Shift+S]キーで「スナップ(Snap)」メニューを出し、「(Cursor to Selected)」(もしくは[2]キー)を押す。
  3. オブジェクトモードに戻り、対象となるオブジェクトを選択。
  4. 原点の設定メニューから原点を3Dカーソルへ移動(Origin to 3D Cursor)を選択。
基点をオブジェクト下部に設定

原点をオブジェクト下部に設定

この設定をする理由は、今回はZ軸のスケール値を数値の可視化として使用するためです。

原点を下部に指定した場合の拡大縮小の挙動

原点を下部に指定した場合の拡大縮小の挙動

このように、Z軸のスケール値を指定すると原点はそのままで大きさが変わっているのが分かります。

データの取り込み処理

震災データの場合と同じように取り込みを行うと、同様にキーフレームが打たれます。
今回の場合はインターバルとして10を指定しているので、10フレームごとにキーフレームが指定されています。

10フレームごとに打たれたキーフレーム

10フレームごとに打たれたキーフレーム

最終フレームを1212に指定し、このアニメーションを再生すると以下のようになります。

再生した人口データ(実際はもっと滑らかに表示されます)

再生した人口データ(実際はもっと滑らかに表示されます)

複数のオブジェクトのアニメーションを効率的に出力する方法

複数のオブジェクトで別のアニメーションを含むものを出力する場合、工夫が必要になる場合があります。

FBXを出力する

FBXを出力する際に、以下のように「NLAストリップ(NLA Strips)」と「全アクション(All Actions)」を無効にします。

アニメーション出力設定

アニメーション出力設定

Unityでのアニメーションの取り込み

これをUnityに取り込むと以下のようにアニメーションが入った形のものが使用できます。

Unityに取り込んだ状態

Unityに取り込んだ状態

このアニメーション(Sceneとなっているもの)を選択し、[Ctrl+d]キーを押すと、このアニメーションが独立して出力されます。

アニメーションが取り出された形

アニメーションが取り出された形

この取り出されたものを選び、右上のメニューよりDebugを選択します。

Debug切り替え

Debug切り替え

表示が切り替わるので「Legacy」を選択します。

Legacy設定

Legacy設定

その下の「Wrap Mode」を「Loop」に切り替えるとアニメーションが繰り返して再生されるようになります。

Wrap Mode設定

Wrap Mode設定

アニメーションコンポーネントの設定

シーンに配置したオブジェクトに「Animation」コンポーネントを追加し、先ほど変更したアニメーションを設定します。

アニメーションコンポーネント追加

アニメーションコンポーネント追加

これをプレハブ化し、アップロードするとSTYLYでアニメーションが再生されます。

Unityでのアニメーションの扱いに関しては次の記事も参考にしてください。

以下は上記2の方法を使い、ブルームなどのポストエフェクトを追加した例です。

このように数値データを見せることもできるので、他のアニメーションを追加したりすることで印象に残る形で数値を映像化できます。
そのため、プレゼンテーションなどでの各種ビジネスグラフィックとしての用途も考えられます。

時系列データの視覚化時に注意するべき点

時系列データを視覚化する際には、いくつかの注意するべき点があります。

振れ幅

例えば、100人の人口に対する10人の動きと、10000人の人口に対するそれでは表示できる情報量が異なってきます。
あまりにも大きい数字を扱う場合は対数的に表示するなどの工夫が必要になります。

再生速度

例えば、1年間の動きを1分間かけて再生するか、10秒かけて再生するかによって得られる印象や情報量が違ってきます。
変化の量を見せたい場合には短い時間、変化によってもたらされる細かい動きを見せたい場合は長い時間で再生するとわかりやすくなります。

STYLYにアップロードする方法

3DモデルをSTYLYにアップロードしてみましょう。

STYLYアカウントを作成する

アカウント作成方法

STYLYにアップロードする方法

UnityからSTYLYにアップロードする方法

STYLYに関する質問、バグ報告、改善してほしい要望はSTYLY FORUMまで
https://jp.forum.styly.cc/support/discussions

このように時系列データをSTYLYに取り込むことにより、変化が見やすい形式で時系列データを表現することができます。
是非、いろいろなデータの視覚化に挑戦してみてください。

また、地震計データをもとに地震のシミュレーションを行う手法についても別記事で解説していますので、併せてご覧ください。

Certified (QA) by Shota Shawn Yoshizawa
Edited by SASAnishiki