Juliaプログラミングクックブック ―言語仕様からデータ分析、機械学習、数値計算まで
- 作者:Bogumił Kamiński,Przemysław Szufel
- 発売日: 2019/10/19
- メディア: 単行本(ソフトカバー)
目次
目的
- プログラミング言語Juliaと、Pythonのグラフ描画ライブラリであるMatplotlibを組み合わせたグラフ作成の方法についてまとめる。
- グラフを作成するための準備の中でハマったポイント、その対処方法についてメモしておく。
- 基本的な各種グラフを作るためのサンプルプログラムをまとめておく。
JuliaのPlotsではなくMatplotlibを使う理由
- Matplotlibでグラフを表示させた時のGUIが便利
- Plotsだとグラフをスタンドアローンのウィンドウで表示させる際の挙動が不安定
- Matplotlibなら設定やコードの書き方が少し面倒になるが、確実に動いてくれる
JuliaからMatplotlibを使えるようにするための設定手順
1. Pythonのインストール
- Matplotlibを使えるようにするためにPythonをインストールする
- 自分はPythonもメインで使うので、各種ライブラリがほぼ揃っているAnacondaでインストールした
- Anacondaのインストール手順は下記を参照
2. JuliaにPyCallとMatplotlibをインストール
- JuliaからPythonを呼び出すためのパッケージ
- JuliaにはデフォルトでPython2環境が導入されているが、これをPython3に切り替えておく
- 下記の記事を参考に、PyCallのインストール前にJuliaのREPLからENV["CONDA_JL_VERSION"]=3を実行しておく
- 上記の設定が済んだら、下記の記事を参考にJuliaのREPLからPyCallとMatplotlibをインストールする
3. エラー "could not find or load the Qt platform plugin windows"が出た時の対処法
- 1~2の手順まで完了すれば基本的にはグラフが作成できるようになるが、人によっては上記のエラーメッセージが出てグラフが作れないことがある
- この場合は、下記を参考にグラフのGUIを形成するのに使われるQtプラグインを正しく読み込むように環境変数を設定する必要がある
サンプルプログラム集
JuliaプログラムからのMatplotlib呼び出し
- PyCallが持つマクロの@pyimportを使う
- 下記のようにPythonライクな書き方でMatplotlibをインポートできる
- ただし、"from hoge import fuga"のような書き方は出来ない
- この場合は、"@pyimport hoge.fuga as fuga"のように書く
using PyCall @pyimport matplotlib.pyplot as plt
2次元線グラフ
x = range(0, 2pi, length=100) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, sin.(x), "-", c="b", ms=10) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_title("2D Line Plot Sample") ax.grid(true) plt.show()
2次元点グラフ
x = range(0, 2pi, length=100) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, cos.(x), ".", c="b", ms=10) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_title("2D Point Plot Sample") ax.grid(true) plt.show()
2次元アニメーション
# data x = range(0, 2pi, length=100) y = sin.(x) # figure fig = plt.figure() ax = fig.add_subplot(1, 1, 1) pxy, = ax.plot([], [], ".", c="b", ms=10) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_xlim([0.0, 7.0]) ax.set_ylim([-1.0, 1.0]) ax.grid(true) # animation for i in 1:length(x) if show_plot == true pxy.set_data(x[1:i], y[1:i]) plt.pause(0.001) end end plt.show()
アニメーションのGIFファイル作成
- まずは上記のアニメーションを1フレームずつPNGファイルで保存していく
- 各ファイル名は、1始まりの連番.pngとなるようにする
# data x = range(0, 2pi, length=100) y = sin.(x) # image number im_num = 0 # figure fig = plt.figure() ax = fig.add_subplot(1, 1, 1) pxy, = ax.plot([], [], ".", c="b", ms=10) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_xlim([0.0, 7.0]) ax.set_ylim([-1.0, 1.0]) ax.grid(true) # animation for i in 1:length(x) if show_plot == true pxy.set_data(x[1:i], y[1:i]) i_num += 1 # update image number plt.savefig(string(im_num, ".png")) # save each frame as png file plt.pause(0.001) end end plt.show()
- 画像ファイルを扱うためのPythonライブラリであるPillowをインストールする
- インストール方法は、先述したMatplotlibと同様
- インストールしたら、Pillowライブラリの一つであるImageモジュールをインポートする
using PyCall @pyimport matplotlib.pyplot as plt @pyimport PIL.Image as Image
- Imageモジュールで保存したPNGファイルを一枚ずつ読み込み配列に格納する
- 画像配列をまとめてGIFファイルに変換する関数
function create_gif(im_num) images = [] if im_num > 0 for num in 1:im_num im_name = string(num, ".png") im = Image.open(im_name) push!(images, im) end images[1].save("animation_2d_sample.gif", save_all=true, append_images=images[1:end], loop=0, duration=60) end end
- 保存したPNGファイルが必要なければ、こちらの関数でまとめて削除する
function delete_png(im_num) if im_num > 0 for num in 1:im_num im_name = string(num, ".png") rm(im_name) end end end
複数グラフの重ね合わせ
x = range(0, 2pi, length=100) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, sin.(x), "-", c="b", ms=10, label="sin") ax.plot(x, cos.(x), ".", c="r", ms=10, label="cos") ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_title("2D Over Plot Sample") ax.grid(true) ax.legend() plt.show()
複数グラフを1つのFigureに並べて表示
x = range(-2, 2, length=100) fig = plt.figure() for i in 1:6 ax = fig.add_subplot(2, 3, i) ax.plot(x, x.^i, "-", c="c", ms=10) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_title("\$y = x^$(i)\$") ax.grid(true) end fig.tight_layout()
2次元散布図
x = rand(100) y = x.^2 + randn(100).* abs.(x) * 0.5 fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.scatter(x, y, marker="*", s=13) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_title("2D Scatter Sample") ax.grid(true) plt.show()
ヒストグラム
x = vcat(randn(100), 2 * randn(100).+ 4) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.hist(x, bins=30, color="g") ax.set_title("Histgram Sample") ax.grid(true) plt.show()
円グラフ
x = 10:10:40 labels = ["A", "B", "C", "D"] colors = ["r", "g", "b", "m"] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.pie(x, labels=labels, colors=colors, autopct="%1.1f%%", counterclock=true, startangle=90) ax.legend(labels, fontsize=12, loc=1) ax.set_title("Pie Chart Sample") plt.show()
3次元グラフのためのpyimport
using PyCall @pyimport matplotlib.pyplot as plt @pyimport mpl_toolkits.mplot3d as mpl3
3次元点グラフ
x = randn(100) y = randn(100) z = randn(100) fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection="3d") ax.plot(x, y, z, "o", color="r", ms=8) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") ax.set_title("3D Point Plot Sample") ax.grid(true) plt.show()
3次元線グラフ
x = 1:5 y = 1:5 z = 1:5 fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection="3d") ax.plot(x, y, z, "o-", color="r", ms=5) ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") ax.set_title("3D Line Plot Sample") ax.grid(true) plt.show()
GitHub
各サンプルプルプログラムは全て下記のGitHubリポジトリで公開済み。