プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Google Colaboratory によるグラフの描画について

下記の平面走査法の記事を書いた際に、線分の画像(グラフ)をいくつか作成しました。

blog.mori-soft.com

そんなにややこしい図でもないので、 Excel で描こうかとも思ったのですが、せっかくなので最近の便利なツールがないか探して、それで描いてみることにしました。ということで、そのあたり、いろいろと調べたり試したことをメモっておきます。

調査

とりあえず、ブラウザで『グラフ 描画』と調べてみます。

いろいろと知らないサイトが出てきたので、ざっと見ていきました。

グラフ描画サイト

検索結果の結構先頭のほうに出てきたのが、

などといったサイトでした。

これらは何だろうか?と思ってみてみると、オンライン(またはオフライン)で使える、数式を入力してグラフなどを描画することができるサイトのようです。ブラウザで、関数を指定してグラフを描かせたり、今回作ったような線分のグラフ(プロット図)の描画もできるし、これは非常に便利です!

ただ、サイトの主目的としては、数学学習のための教材としての利用を想定しているようです。このため、例として GeoGebra のライセンスを調べてみると、先生と生徒であれば無料で使えるのですが、商用利用の場合はライセンスの取得が必要になってきます。このブログに記載するのであっても、屋号の名前も含めたブログなんで厳しく見ればアウトかな?

他のサイトのライセンスまでは調べていませんが、多分似たようなところだと思います。うーん、残念。

プロットのためのソフト

次に調べていくと、 gnuplot とかが出てきました。懐かしいなー、昔何かの時に触った覚えがあります。コマンドラインベースでグラフを描いていくやつですね。まだ、開発は続いているようですね。

他には、 maxima とかを使ってグラフを描こうという話も見られたのですが、これって確か Mathematica や Maple とかと類似の数式処理ソフトですよね?今回みたいに簡単なグラフを描くためだけには、ちょっと大げさな印象です。

まあ、最初にあったサイトたちも、これらの数式処理をオンライン化したものと考えれば、過剰なのかもしれませんがオンラインで手軽に使えるという点に惹かれています。

簡単なグラフなら、結局は Excel なのかな?とあきらめかけながら調べていて、最後にたどり着いたのが、 Google Colaboratory です。これだと、オンラインで、 Python とそのグラフ描画ライブラリである matplotlib を使って描画が出きるっぽいです。

なるほどね。 Python で描画できるのは知っていたのですが、環境整えるのめんどそうだと思って敬遠してましたが、これをオンラインで使えるようにしてくれているようです。

どうせ、コードでプロット描くなら、 gnuplot よりも python のほうがあとあと応用も効きそうですしね。というわけでこれでグラフを描画してみることにしてみます。

Google Colaboratory を使ってみる

まずは、 Google Colaboratory にアクセスすると、簡単な紹介を見ることができます。

ふむふむ、オンライン上で python を実行できる環境であり、一連の操作をノートブックという形式で保存できるという環境のようです。 で、いろいろと制限があるけど、無料でも使い始めることができるとのことですね。

Google 太っ腹だな。

まあ、主には機械学習とかをお手軽に試そうという場合を想定しているようですが、学生の学習やデータ分析なども視野に入っているようです。グラフの描画はビジュアライゼーションの一環としてカバーされているようですね。

これが無料ってすごいなと思っているのですが、一応 Google 的には、長時間の利用の場合はお金が必要となるというモデルにすることで、ある程度お金を取っているようです。これは、一定時間ごとにランタイム(Python の実行環境、仮想マシンのインスタンスかな?)が自動的にリセットされるっぽいのと、CPU(GPU)リソースでいいやつを使おうとするとお金がかかるという形になっています。機械学習していて、途中でリセットされたらたまらないですから、そりゃお金払ってでも結果を得られるようにしますよね。

今回は、(ごく簡単な)グラフ描画だけなので、当然無料枠の範囲内で使ってみます。早速試します。実際に試すには、 Google アカウントでのログインが必要です。

ログインして、メニューから『ファイル』、『ドライブの新しいノートブック』を選択します。するとこんな感じに新しいノートブック環境が立ち上がります。

最初の行は、コード入力セルになっているので、早速 Python コードを入力して実行してみます。

最初にセルの左側は三角矢印の実行ボタンを押すと、画面の下部に

のように、 Google Compute Engine を起動して、それに接続するような旨のメッセージが表示されます。これがランタイム環境ですね、きっと。で、接続が完了すると、 Python の実行結果が無事に表示されたという次第です。

これは簡単ですね。

matplotlib

では、いよいよ本題の matplotlib を試してみます。

上記などを参考に触ってみると、

おぉ、これは便利ですね。ちょっとした python のコードを描けば、きれいなグラフが作れます。

では、早速、平面走査法のテストデータの下記のグラフを作ってみることにします。

直線を描画

2点を結ぶ直線は、下記で描画できます。

from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = [0, 1.5]
y = [1, -0.5]
ax.plot(x, y)

plt.show()

subplot は一つの figure に対して複数のグラフを描画したい時に指定するようです。なので、今回の場合はなくても問題ないです。

複数の直線

複数の直線は、 plot を複数回呼び出せばよいようです。

x = [0, 1.5]
y = [1, -0.5]
ax.plot(x, y)

x = [-1, 2]
y = [-1, 2]
ax.plot(x, y)

x = [-2, 3]
y = [-0.75, 0.5]
ax.plot(x, y)

plt.show()

この場合、デフォルトだと、下記のようにプロットごとに、色が自動的に変わっていきます。

同じ色で描画したければ、色を指定します。

from matplotlib import pyplot as plt
import numpy as np

c = "tab:blue"

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = [0, 1]
y = [1.5, -0.5]
ax.plot(x, y, c)

x = [-1, 2]
y = [-1, 2]
ax.plot(x, y, c)

x = [-2, 3]
y = [-0.75, 0.5]
ax.plot(x, y, c)

plt.show()

こんな感じですね。

これで、基本的な線分を描画するというのはできたと思うので、次は見た目を整えていきます。

軸の位置を調整

下記サイトを参考にして、グラフの左端と下側にある軸の位置を調整します。

X軸(bottom)とY軸(left)をそれぞれ、0の位置に設定し、上と右の軸は非表示にしています。

ax.spines["bottom"].set_position(("data", 0))
ax.spines["left"].set_position(("data", 0))
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)

目盛を設定

X軸とY軸の間隔(スケール)が異なると、見た印象が間違うこともあるので、同じ大きさになるようにします。

ax.axis("equal")

あと、デフォルトだと、 X 軸と Y 軸の目盛の間隔が異なっているので、X軸の目盛の間隔を変更します。この時、X軸の目盛位置をすべて指定する形でもできるのですが、当然X軸の範囲も指定することになります。

そうではなくて、目盛の間隔のみを変更したかったので、下記のようにしました

この例だと、 X 軸の間隔を 0.5 刻みにしています。

from matplotlib import ticker as ticker
(略)
ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))

補助目盛線も表示します。

ax.minorticks_on()

グリッド線を表示

これは簡単ですね。

plt.grid()

引数を指定すればグリッド線も、X軸のみ表示、Y軸のみ表示とはいろいろと切り替えることができるそうです。

ファイルとして保存

最後に、下記を参考に描画したグラフをファイルとして保存します。

Colaboratoryでグラフをファイルとして保存する - Machine Morning

Google ドライブ上にも保存できるみたいですが、その場合 Google ドライブをマウントするとかいろいろと手順がいるっぽいので、単にローカルPCにダウンロードする方法を取りました。

from google.colab import files
(略)
#画像を保存
fn="fig_test2.png"
plt.savefig(fn)
files.download(fn)

# 画面に描画
plt.show()

plt.savefig でファイルが保存されるのですが、これって、ランタイム環境にファイルとして保存されているということのようです。なので、自分の手元に持ってくるために、 files.download というのが必要になっているっぽいです。

なお、ファイルとして保存する savefig() の呼び出しは show() の前に行わないと、正しい画像が保存できないようです(こちらなどによると、show の呼び出し後は描画がクリアされるそうです)。

全体像

最終的に、こういうコードで描画できました。

from matplotlib import pyplot as plt
from matplotlib import ticker as ticker
import numpy as np
from google.colab import files

c = "tab:blue"

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = [0, 1.5]
y = [1, -0.5]
ax.plot(x, y, c)

x = [-1, 2]
y = [-1, 2]
ax.plot(x, y, c)

x = [-2, 3]
y = [-0.75, 0.5]
ax.plot(x, y, c)

ax.axis("equal")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.minorticks_on()
ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))

ax.spines["bottom"].set_position(("data", 0))
ax.spines["left"].set_position(("data", 0))
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)

plt.grid()

#画像を保存
#fn="fig_test1_2.png"
#plt.savefig(fn)
#files.download(fn)

# 画面に描画
plt.show()

画像ファイルが欲しい場合は、『画像を保存』の部分をコメントアウトを外せば保存できます。

このコード自身は Google ドライブに保存されるのですが、コピーを Github や Gist に保存することもできるそうです。これも含めた、平面走査法で用いたテストデータのグラフを描画しものを Gist に置いておきます。

まとめ

ローカルの VSCode 環境で Python の環境を作ろうとしたとき、 Jupytor notebook という単語を嫌になるほど聞きました。当時は単なる Python の実行環境が欲しかったのと、 Jupytor Notebook がよくわからなかったので、無視してました。

でも、こうやって Colaboratory を触ってみると、これと同じことを自分のローカル環境でできるようにするのが Jupytor notebook ということなんでしょうね、きっと。そりゃ人気出るわ。

matplotlib については少し調べると山ほど情報が出てくるので、いろいろと試してみたいなと思います。なお、全部見切れてないですが、下記なども参考にしました。

matplotlibのめっちゃまとめ #Python - Qiita