【アプリ開発】Pythonで波のアニメーションを作成しよう

みなさんこんにちは本日は以下の記事の続きとなります。

eye catch 【アプリ開発】Sikulixを使ってYouTube広告を自動スキップするアプリの開発

YouTube広告を自動スキップするためのステップで説明していくと説明しました。

SikuliXをインストールしよう

まずはSikuliXをインストールして、簡単な動作確認を行います。

Chromeを自動で立ち上げて、YouTubeまで自動で遷移するプログラムを作成します。

Pythonの書き方を覚えよう(本記事)

今回作成するアプリ開発で利用するPythonの基本的な文法について説明します。

ここでは、波のアニメーションを描画するアプリ開発を通じてPythonを楽しく学習します。

SikuliXの使い方を覚えよう

今回のアプリ開発で利用する機能を中心にSikuliXの機能をいくつか紹介します。

実際にアプリを作ってみよう

SikuliXの機能を組み合わせて作りたいアプリを作ってみましょう。

今回は、Pythonを使って波のアニメーションを作成します。

実際に動くアプリを作ることで、より具体的なイメージを持ちながらプログラミング学習ができると思いますよ!

今回作成するアプリの完成イメージは次の動画をご覧ください。

はじめに

今回の記事では、以下の読者を対象としています。

  • Pythonどころかプログラミングすらやったことのない初心者のかた
  • Pythonは何となくやったことがあるけれど、アニメーションの作成はやったことがないかた
  • 波動方程式を実際にPythonでレンダリングしてみたい!という、理系の君へ

今回の記事では、次のような内容を説明します。

  • はじめてのPythonのはじめかた(Visual Studio CodeでPythonを実装します)
  • 基礎的なPythonの文法や書き方
  • NumpyやMatplotlibを利用してアニメーションを作成する方法
  • (ちょっとだけ)波動方程式の解説

そもそもPythonってなに??

そもそも、Pythonってよく聞くけど、どんなプログラミング言語なの?

初心者向けのプログラミング言語なの??

ともとも
ともとも

Pythonはとっても学習コストの低いプログラミング言語のひとつだよ!

Pythonは通常のソフトウェア開発に使われることもあるけど、数値計算などの学術的な観点からも利用されることのあるプログラミング言語だよ!

最近よくPythonを聞く機会が多くなっているのは、機械学習にもPythonがよく使われることが多いからからな?Python自体は1991年にリリースされている歴史ある言語なんだよ。

Pythonを学ぶことで、今話題のAIについての学習や転職時にも役立つ知識を身に着けられるよ!

Pythonは1991年にGuido van Rossumによってリリースされた言語で、次のような内容に利用されています。

  • ソフトウェア開発
  • 数値計算
  • 機械学習

あの、YouTubeも実はPythonで開発されています。

また、Pythonはインタプリタ言語で、異なるプラットフォーム(Windows、Mac OS、Linuxなど)でも問題なく動作します。

インタプリタ言語とコンパイラ言語

現在多くのプログラミング言語が存在していますが、その特徴によって、インタプリタ言語コンパイラ言語のどちらかに大別されます。

今回扱うPythonは実はインタプリタ言語でその特徴を知っておくことは、今後ほかのプログラミング言語を学ぶ際に役立つかと思いますので、ぜひ知っておいてください!

インタプリタ言語

インタプリタ言語とは一言でいうと、実際に書いたプログラムを1行1行読み取って、システムが実行していく、という内容になります。

実際に例を挙げてみましょう。次のようなコードを見てください。

# 渡された数値nの2乗を返す
def square(n):
    return n * n;

print(square(10));
# 100が表示される

これはsquareという引数の2乗を計算する関数を定義して、それを利用して10の2乗を計算しています。

これは皆さん問題ないですよね?では次のコードはどうでしょうか?

print(square(10));

# 渡された数値nの2乗を返す
def square(n):
    return n * n;

# "NameError: name 'square' is not defined"が発生して100が表示されない。

内容的には先ほどと同じ内容を書いています。しかし、エラーが発生してしまいました。

その理由はシステムがコードを上から順番に1行ずつ解釈しているから、です。

1行目の時点ではsquareという関数をシステムが知らないので、そんな関数はないよ?とエラーを出しているのです。

インタプリタ言語のプログラミング言語には以下のようなものがあります。

  • Python
  • PHP
  • Ruby
  • Perl
  • JavaScript

インタプリタ言語でよいのは、次に説明するコンパイラ言語で必要となるコンパイルが不要である点です。

コンパイラ言語

コンパイラ言語とは一言でいうと、コードをシステムが読み込むための機械語(マシン語)に一度変換して、実行時には機械語を実行する言語のことを言います。

わかりづらいと思うので、コンパイラ言語の1つであるJavaを例に挙げて説明します。

Javaでうえで書いたPythonと同じ内容のプログラムを作ろうとすると次の手順で作成することになります。

まず、Pythonと同様にプログラムを書きます。

public class Main{
    public static void main(String[] args){
        // 100が出力される
        System.out.println(CalcUtils.square(10));
    }
}

class CalcUtils{
    public static int square(int n){
        return n * n;
    }
}

Pythonよりいろいろ書いていてよくわからないと思いますが、このコードを書いたファイルはそのまま実行できません。このファイルをコンパイラと呼ばれるソフトウェアを使って機械語に変換する必要があります。

機械語に変換すると、Javaの場合はclassファイルと呼ばれるファイルに変換され、システムはそのclassファイルを読み取ることでプログラムを実行します。

こう聞くと、どうしてそんなに面倒くさい方法でプログラムを作成しているの?と思う人もいると思います。

いろいろ理由はあるのですが、インタプリタ言語との違いとしては、コードの上から順番に実行するわけではないという点が異なります。

squareというメソッド(関数のようなもの)を定義しているのが、実際に呼び出している箇所(Mainの中)よりも下(CalcUtilsの中)で定義しているのに、正しく動きます。

また、一般的にインタプリタ言語よりも高速で動作する、ということがよく言われます。

Pythonを使えるようにしよう

今回は、Visual Studio Codeを使ってPythonが利用できるようにしていきましょう。

Windowsを想定して説明をしていきますので、ほかのOSを利用しているなどうまくいかない場合は、次のサイトを参考に環境構築してください。

Visual Studio Codeとは、Microsoftが開発しているWindows、Linux、macOS用のソースコードエディタ(プログラミングをする際に利用できるメモ帳のようなもの)のことです。

世の中にはいろいろなエディタが存在しますが、筆者はこのVisual Studio Codeを全力で推します!(理由はいろいろありますが、とっても使いやすくてサクサク動く!と思います。)

Visual Studio Codeをインストールしよう

Pythonがインストールできたら次はVisual Studio Codeをインストールしましょう。

次のサイトにアクセスしてください。

お使いのパソコンのOSにあったインストーラをダウンロードしてください。

ダウンロードが完了したら、インストーラを起動して、Visual Studio Codeを立ち上げてください。

するとこのような画面が表示されるかと思います。

Visual Studio Codeを日本語化しよう

まずは、Visual Studio Codeを日本語化しましょう。Ctrl + Shift + xを押して、その後japanese languageと入力してください。

そして1番上に出てくる(はず)の、Japanese Language Pack for Visual Studio Codeを選択し、installを押してください。インストールして、Visual Studio Codeを再起動すると日本語化されているはずです。

日本語化後の画面

Pythonをインストールしよう

まずはPythonをインストールしましょう。次のサイトにアクセスしてください。

そして、Download Python x.x.xを押して最新のPythonのインストーラーをダウンロードしてください。

筆者アクセス時(2021/5/30時点)での画面

すると、Pythonのインストーラがインストールできるので、ダウンロードしたら、クリックしてPythonをインストールしてください。

macOSやLinuxをお使いの方へ

上記はWindows用のダウンロード方法ですので、macOSやLinuxをお使いの方は、上記しているVisual Studio Codeの記載を参考にダウンロードをしてください。

Visual Studio CodeにPythonのExtentionを追加しよう

Visual Studio Codeを開いて、Ctrl + Shift + xを押してください。そしてPythonと入力して次の画像と同じものをインストールしてください。(筆者はすでにインストール済みのため、アンインストールと表示されていますが、インストールを押してください。)

Pythonがインストールされているか確認しよう

Visual Sudio Codeを開いてCtrl + @ を押してください。すると画面下にターミナル(コマンドを打ってシステムの操作を行うことができるもの)が表示されます。

そして、ターミナルにpy -3 --versionと打ってエンターキーを押してください。

そして、次のようにPythonのバージョンが表示されれば正常にインストールできていることが確認できます。

ワークスペースを作成しよう

今回アプリを作成する際に作成するファイルを格納するためのフォルダをデスクトップに作成しましょう。

そして、画面左上の「ファイル(F)」を押して、「フォルダーを開く」を押してください。

そうして作成したフォルダを選択して、「フォルダーの選択」を押してください。

続いて、Ctrl + Shift + Pを押してください。そうするとコマンドパレットが開くので、そこにPython: Select Interpreterと入力して、エンターキーを押してください。

そうして、上でダウンロードしたPythonのファイルを選択して、実際に利用するPythonを選択してください。

お疲れさまでした!これで、Visual Studio CodeでPythonが使えるようになりました!
実際に簡単なプログラムを書いてみましょう。

はじめてのPython

次の画像を参考に左上のボタンをおして、ファイルを作成してください。ファイル名は何でも構いませんが、ファイルの最後に必ず.pyをつけるようにしてください。(これでPythonのファイルだと認識されます。)

そして、次のコードを書いてみましょう。

Python
message = "はじめてのPython";
print(message);

これは、「はじめてのPython」を表示する簡単なプログラムです。実行するには右上の緑矢印ボタンを押してください。すると、ターミナルに「はじめてのPython」が表示されます。

Pythonのライブラリをインストールしよう

今回作成するプログラムでは、ライブラリ(便利な機能をまとめたもの)をいくつか利用します。

今回利用するライブラリは次の3つです。

  • NumPy
  • pandas
  • Matplotlib

なので、ここではこれらをインストールしていきましょう。

まずVisual Studio Codeを開いて、Ctrl + @ を押してターミナルを開いてください。

そして、py -m pip install -U pipと入力してください。これは、pipというPythonのライブラリなどを管理するツールを更新しています。今回はこのpipを使ってライブラリのインストールをします。

pipの最新化が終わったら、次はpy -m pip install numpyと入力してください。これでnumpyというライブラリがインストールできます。

Numpyとは?

Numpyとは、数値計算を高速に実行することができるようになるライブラリで、機械学習やディープラーニングなどでよく利用されるライブラリです。

今回は波の計算をするときに利用しており、Numpyの詳しい使い方については、次を参考にしてください。

次にpy -m pip install pandasと入力してください。これでpandasというライブラリがインストールできます。

pandasとは?

pandasとは、機械学習やディープラーニングなどでデータの解析を行う際に利用することが多いライブラリです。数値計算というよりは、統計的にデータを扱うことにたけているライブラリとなります。

今回は、波の計算結果(データの集合)を扱う際に利用しています。

pandasの詳細を知りたい方は次を参考にしてください。

最後にpy -m pip install matplotlibと入力してください。これで、matplotlibがインストールできます。

matplotlibとは?

matplotlibとは、グラフを書くことができるライブラリです。2次元だけでなく、3次元での描画も可能で、簡単にきれいなグラフに描画することができる優れものです。

今回は、波の計算結果を描画する際に利用しています。

詳細は次を参考にしてください。

以上で今回必要な準備が整ったことになります。

直線を書いてみよう

波の描画に入る前にまずは、直線を書いてみましょう。

次のコードを入力してください。

Python
import numpy as np;

# 0から5までの数値を0.1刻みの配列で用意する
# np.arangeには引数が3つ必要で、1つめが開始時点の数値、
# 2つめが終了時点の数値、3つめがデータの刻み単位です。(numpyのメソッド)
x = np.arange(0, 5, 0.1);

print(x);
# [0 0.1 0.2 0.3 ... 4.9]の配列が出力される

まずは、x軸の値を用意します。ここでは、0から5まで0.1づつの数値が入った配列を変数xに代入します。

配列と変数

配列

プログラミングによっては、扱うデータに応じてデータ型が存在し、ざっくり次のようなデータがあります。

※Pythonではデータの種類を意識する必要はあまりありません。

  • 真偽値(boolean):trueかfalseの2つの値を持ち、プログラミングの最小単位。
  • 数値(number):整数や小数点を含めた数値のこと。(Javaなどの言語では、明確に整数と小数点を含む数値を異なるものとして扱います。)
  • 文字列(String):”はじめてのPython”などの文字列のこと。

そしてこのようなデータをまとめて扱うことができるもののことを配列といいます。

いろいろなデータをまとめて扱いたいときに配列を利用します。例えば、今回でいうとx軸を表す値をまとめて扱いたいので、配列を使っています。

Pythonで配列を使いたいときは次のように書きます。

# データ1、データ2、データ3の配列
[ データ1,データ2, データ3] 
# 例)
# 100、Tomotomo(文字列)、trueの配列
[100, "Tomotomo", true]

変数

データや配列など、データを入れておくための箱のようなものを変数といいます。

変数には名前を付ける必要があり、ほかの変数と区別するため名前が重複しないようにする必要があります。

今回はxという名前の変数に0から5まで、0.1刻みの数値の配列を入れています。

続いて、y軸の値を算出していきましょう。

直線を表す公式は次です。(中学生でやったはず?の内容です)

# 直線を表す公式(aが傾き、bが切片)
y = a * x + b;

今回はy = 2 * x + 2を書いてみましょう。次のコードを書いてください。

Python
import numpy as np;

import matplotlib.pyplot as plt;

# 0から5までの数値を0.1刻みの配列で用意する
# np.arangeには引数が3つ必要で、1つめが開始時点の数値、
# 2つめが終了時点の数値、3つめがデータの刻み単位です。(numpyのメソッド)
x = np.arange(0, 5, 0.1);

# y = 2x + 2の直線のy軸のデータ

y = 2 * x + 2;

# 変数xと変数yをプロットする
plt.plot(x, y);

# プロットした値を表示する
plt.show();

これを動かすと、次の画像が表示されるはずです。

y = 2x + 2

どうでしょう?思ったより簡単に描画できたのではないでしょうか?

ユーザとやり取りしながら、描画できるようにしてみよう

ここでは、もう少し進めて、次を実行したユーザが選択できるようにしてみましょう。

  • x軸の範囲(上の例では0から5まで)
  • yの方程式(上の例では2x + 2)

上記を実現するためには、ユーザからの入力を受け付けるinput()メソッドを利用する必要があります。

次のコードを入力してみてください。

Python
x_range = input("表示するx軸の範囲をカンマ(,)区切りで整数で入力してください。:");
print(x_range);

そして実際に実行すると、ターミナルに「表示するx軸の範囲をカンマ(,)区切りで整数で入力してください。:」と表示されて、ユーザからの入力まちの状態になります。

なのでここで、たとえば3,10などと入力すると、ターミナルの次の行に3,10が表示されます。

つまり、inputを利用すると、入力した値がx_rangeに入るので、システムとユーザでやり取りできるようになるのです。

なので、次のコードを入力してください。

Python
import numpy as np;

x_range = input("表示するx軸の範囲をカンマ(,)区切りで整数で入力してください。:");

# x軸開始の値
x_range_start = int(x_range.split(",")[0]);

# x軸終了の値
x_range_end = int(x_range.split(",")[1]);

# xに指定した区間で0.1刻みで配列を作成
x = np.arange(x_range_start, x_range_end, 0.1);

x_rangeにはカンマ区切りで数値が入力されていますが、これはまだ文字列なので、数値に変換する必要があります。

まずは、カンマ区切りで入力されている前の数字と後の数字を取得します。それには、split()というメソッドを利用する必要があります。

文字列をsplitの引数で分割した文字列の入った配列を作成します。

"3,10".split(","); # →[3, 10]
"あいうえお かきくけこ".split(" "); # →["あいうえお","かきくけこ"]

それで、配列から値を取得するときは、配列の何番目に入っている値が欲しいのかを記載する必要があります。

なので、今回はまず次のようにして値を取得する必要があります。

Python
# 3,10と入力したとする。
x_range = input("表示するx軸の範囲をカンマ(,)区切りで整数で入力してください。:");

 # [3, 10]の1番目の値(配列は0から順に数えます)を取得する
x_range_start = x_range.split(",")[0];
print(x_range_start); # 3が表示される

 # [3, 10]の2番目の値(配列は0から順に数えます)を取得する
x_range_end = x_range.split(",")[1];
print(x_range_end); # 10が表示される

あとは、ここでの数字は文字列のため、数値にデータを変換する必要があります。

そのためには、int()メソッドを利用します。引数に入った文字列を整数値に変換してくれます。

次に、描画する式をユーザから受け付けて、描画できるようにしてみましょう。

最終的にできるコードは次の通りです。

Python
import numpy as np;
import matplotlib.pyplot as plt;

x_range = input("表示するx軸の範囲をカンマ(,)区切りで整数で入力してください。:");

# x軸開始の値
x_range_start = int(x_range.split(",")[0]);

# x軸終了の値
x_range_end = int(x_range.split(",")[1]);

# xに指定した区間で0.1刻みで配列を作成
x = np.arange(x_range_start, x_range_end, 0.1);

# 公式をユーザが入力する
equation = input("描画する式を入力してください。(利用可能な変数はxです。):y =");

y = eval(equation);

plt.plot(x, y);
plt.show();

あとは、描画する式が入力できるようにinputをもう一つ追加してみましょう。

あとは、いろいろな入力をしてみると、それに合わせて描画がされるようになるはずです。

次は、このコードから出力できる描画イメージです。

y = x * x – 10 (-10 ≦ x ≦ 10)

波のアニメーションを作成しよう

最後に波のアニメーションを作成しましょう。

アニメーションを作成するということは、時間の経過とともにデータの形が変わるということになります。

そして波の演算ということで、今回は波動方程式というものを利用しています。

波動方程式とは波の動きをモデル化しているもので、変数に時間が含まれているので、時間がたつごとにどのような波形になるのかがこの方程式から読み取ることができます。

筆者自身が勉強していた時に利用していた参考書を載せておきますが、具体的な解説は割愛します。。(要望があれば、別途解説します)

今回作成するプログラムの完成図を先に書いてみましょう。(そのあとでポイントを説明します。)

Python
import numpy as np
import matplotlib.pyplot as plt
# アニメーションの描画に必要なライブラリ
import matplotlib.animation as animation

# 波動方程式
# x:x座標、t:経過時間
def wave_y(x,t):
    sigma = 0
    for n in range(50):
        sigma = sigma + (-1) ** (n + 1) / (2 * n - 1) ** 2 * np.sin((2 * n - 1) * np.pi * x / 2) * np.cos((2 * n - 1) * np.pi * t / 2)
    return 8 * h / np.pi ** 2 * sigma

# 変数定義
# 描画する空間を定義
fig = plt.figure()

# 描画するx軸の開始の値
x_range_start = 0

# 描画するx軸の終わりの値
x_range_end = 2

# x軸を表す配列
x_range = np.arange(x_range_start, x_range_end + 0.1, 0.1)

# 経過時間を表す変数
t = 0

# 時間間隔を表す変数
dt = 0.02

# 初期の高さ
h = 2

# 波を描画する数
render_num = 5000

# 各断面のy座標の値を保持する配列
yt = []

# 経過時間に対するy座標を算出
for i in range(render_num):
    y = wave_y(x_range,t)
    yt.append(y)
    t = t + dt

# 再描画する際の設定を記載
def _update_plot(i):
    y = yt[i]
    fig.clear()
    plt.plot(x_range,y)
    plt.grid(True)
    plt.xlim([x_range_start, x_range_end])
    plt.ylim([-h - 2, h + 2])

# アニメーションの設定
ani = animation.FuncAnimation(fig, _update_plot, frames=360, interval=20)

# 実際に描画する
plt.show()

これを動かしてみると、次のようなアニメーションが表示されるはずです。

まず、波動方程式とその後の変数宣言の箇所についての説明は省略します。

このプログラムは、イメージとして次のように作られています。

  1. 時点tにおける、xの値とyの値を計算する。
  2. 時点t から少し経った時間でのxの値とyの値を計算する。
  3. 1~2を何度も繰り返す(今回は5,000回)
  4. 最後に、作成したxとyの値を描画する

そして、今回、xの値は0から2までの0.1刻みの数値の配列となっています。なので、時間によって値が変わるのはyの値のみとなります。それが次の箇所です。

Python
# 経過時間に対するy座標を算出
for i in range(render_num):
    y = wave_y(x_range,t)
    yt.append(y)
    t = t + dt

ここでは、render_numの回数だけ、ytに波動方程式で算出したyの値(配列)を入れています。

繰り返しについて

プログラムは大まかにいうと分岐繰り返しでできています。

繰り返しとは、同じ処理を何度も繰り替えすことを言います。繰り返しにはいろいろな書き方がありますが、今回はforループの書き方を説明します。

Pythonでの書き方は次の通りです。

for 変数名 in 配列:
   処理内容

例えば、次のようなコードを書いてみてください。

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
    print(i)
# 0 1 2 3 4 5 6 7 8 9 が表示される

inの右側に書いた配列の頭から順番にiに値が入っていきます。

あとはfor文書くときに便利な関数range()を覚えておくとよいでしょう。

# 0 ~ 99の配列を作成する
range(100)

for i in range(100):
    print(i)
# 0 1 2 ... 99が表示される

最後にアニメーションを動かす箇所の説明をします。

Python
# 再描画する際の設定を記載
def _update_plot(i):
    y = yt[i]
    fig.clear()
    plt.plot(x_range,y)
    plt.grid(True)
    plt.xlim([x_range_start, x_range_end])
    plt.ylim([-h - 2, h + 2])

# アニメーションの設定
ani = animation.FuncAnimation(fig, _update_plot, frames=360, interval=20)

実際にアニメーションを実行しているのは、animation.FuncAnimationの箇所です。

このメソッドでは4つの引数を設定しています。

1つ目の引数は描画する描画する対象のfigureを設定します。

2つ目の引数はfigureを更新するメソッドを指定します。メソッドの引数には0始まりで、1づつ増加する変数が勝手に入るようになっています。

3つ目以降は任意の変数で、今回はframesintervalを指定しています。

framesは2つ目の引数で指定したメソッドを呼び出す回数を指定しています。

intervalfigureを更新する間隔を指定しています。

FuncAnimationの詳細は次を参考にしてください。

そしてfigureを更新している_update_plotでは、波動方程式で算出したデータをiを利用して順番に取り出して図を更新しています。

さいごに

Pythonを使った簡単なアプリを作ってみましたが、いかがでしたでしょうか?

意外と簡単で、面白いなと思っていただけたら幸いです。

引き続き、アプリ開発を通じてプログラミングの学習を積んでいきましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です