GoogleColabでPythonを使って数学のグラフを作成してみた

## はじめに
　Pyhonは、近年ではスタンダードになりつつあるプログラミング言語で、プログラミング初心者にもとっつきやすく、一方でAI開発などの高度な使い方までができるのが特徴となっています。
　以前に、Pythonの超初心者向けとして、
 
【初心者向け】GoogleColabでPythonを使ってみよう！
https://qiita.com/tech-nami/items/5ccc313539563eeab117

という記事を投稿させていただきましたが、その後、子供の情報の授業で、GoogleColabでPythonを使って何かプログラムを作れという課題が出て頑張っているのを見て、私も少しやってみようと思い、その第２弾として、自分が中学生の頃に、数学の宿題を効率的に^^行おうとして BASIC 言語で作成した、自分で入力した数式をそのままグラフで表示できる、数学のグラフというプログラムを再現して作ってみました。

## 数学のグラフについて
　私が中学生だった約40年前、パソコンテレビ X-1 というテレビとパソコンが一体となった名機がありました。この X-1 に搭載されていた、Hu-BASIC という BASIC 言語には、インタープリタならではの機能として DEFFN(X) という、実行時に自分で入力した数式をそのまま関数として利用できる機能がありました。それを使うと数式を自分で構文解析しなくて済んでしまうため、たった10行程度で y が x の関数であるグラフは概ねなんでも描画できるプログラムが作成できました。その後 C や Java などのコンパイラの時代になり、こういうことはできなくなっていたのですが、インタープリタである Python には、当時の DEFFN(X) の代わりになる eval() という組み込み関数があり、これによりとても簡単に数学のグラフが作成できるようになっています。

## GoogleColab で Python を使って数学のグラフを作成！
　まずは、GoogleColabで新しいノートブックを準備をしてください。

（参考）【初心者向け】GoogleColabでPythonを使ってみよう！
https://qiita.com/tech-nami/items/5ccc313539563eeab117

１．「Colaboratoryへようこそ」画面にて、
「ファイル」「ドライブの新しいノートブック」を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822494/602c71e6-33b3-edba-bff7-7cdaaa36334c.png" width=100%>

２．新しいノートブックが表示されるので、

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822494/65ee9d86-5897-305e-0811-0bbf5869b866.png" width=100%>

下記のように入力して実行してみてください。
（わかりやすくするため、エラー処理などは割愛していますのでご容赦ください）

```py:Google Colab
import matplotlib.pyplot as plt
import numpy as np

# 日本語対応のmatplotlibをインストール
import importlib
if not importlib.util.find_spec('japanize_matplotlib'):
  !pip install japanize-matplotlib
import japanize_matplotlib

def plot_function():
    func_str = input("関数を定義してください (例: x**2 + 2*x + 1, np.sin(x), np.log(x) etc): ")

    # x の定義域（-10～10）とその間で何回 y を計算するか（400）を定義
    x = np.linspace(-10, 10, 400) 

    # グラフのタイトル、ラベル、罫線の表示を設定
    plt.title("数学のグラフ")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.grid(True)

    # 入力した関数を eval() で演算して y 座標に格納
    y = eval(func_str)              # 文字列を評価して関数を実行

    # グラフを描画
    plt.plot(x, y, label=func_str)  # ラベルを関数文字列に設定
    plt.legend()                    # 凡例表示
    plt.show()

if __name__ == "__main__":
    plot_function()
```

これを実行すると、表示したい関数を聞かれますので、
例えば、y = x のグラフであれば「x」
　　　　y = 2x のグラフであれば「2*x」
　　　　y = x^2 のグラフであれば「x**2」
　　　　y = sin(x) のグラフであれば「np.sin(x)」
　　　　y = log(x) のグラフであれば「np.log(x)」
の様に入力してください。

※プログラム上 numpy を np として定義しているため、sin(x)などの関数を使う場合は np.sin(x) の様に入力する必要があります。

すると、下記のようなグラフが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822494/16cd6b8f-79f4-4028-9c8e-e1044aaadaa4.png" width=80%>

・・・これだけです。簡単に数学のグラフが表示できました。

## プログラムのポイント
　簡単に、私の考えるポイントについて記載します。
 ・一番重要なポイントは、Python インタープリタにおいては、組み込み関数 eval() により、ユーザが入力した数式をそのまま関数として利用できること。
 ・日本語のラベルを使ったグラフ作成には、「japanize_matplotlib」が使える
 ・パッケージのインストールができていない場合、
```py:Google Colab
import importlib
if not importlib.util.find_spec('japanize_matplotlib'):
  !pip install japanize-matplotlib
import japanize_matplotlib
```
　のように記載すると、１つのコードセル内でインストールを済ませることができる。

## 複数のグラフを表示したい！
　数学のグラフと言えば、やはり２つの関数の交点を確認したい、といったことがあると思います。そこで、複数の関数を１つのグラフ上に表示できないかと思い、追加で実験しました。残念ながら、最初に複数の関数を入力しておき、入力完了後に一括でグラフが表示されるといった感じになってしまいましたが、一応そのコードも示しておきます。

```py:Google Colab
import matplotlib.pyplot as plt
import numpy as np

# 日本語対応のmatplotlibをインストール
import importlib
if not importlib.util.find_spec('japanize_matplotlib'):
  !pip install japanize-matplotlib
import japanize_matplotlib

def plot_function():
  # x の定義域（-4～4）とその間で何回 y を計算するか（400）を定義
  x = np.linspace(-4, 4, 400) 

  # グラフのタイトル、ラベル、罫線の表示を設定
  plt.title("数学のグラフ")
  plt.xlabel("x")
  plt.ylabel("y")
  plt.grid(True)

  while True:
    func_str = input("関数を入力してください (終了するには 'q' を入力): ")
    if func_str.lower() == 'q':
      break

    # 入力した関数を eval() で演算して y 座標に格納
    y = eval(func_str)              # 文字列を評価して関数を実行

    # グラフを描画
    plt.plot(x, y, label=func_str)  # ラベルを関数文字列に設定
    plt.legend()                    # 凡例表示

  plt.show()

if __name__ == "__main__":
    plot_function()
```
この結果、下記の様なグラフが表示できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822494/58668f8c-701c-4fc2-888d-491e35912ad2.png" width=80%>

　一応、ちょっと無理がありますが、円も書くことができます。数式に、
　　　１つめ：「np.sqrt(3\*\*2-x\*\*2」
　　　２つめ：「-np.sqrt(3\*\*2-x\*\*2」
　の様に入力すれば、２つあわせて円ぽくなります。（上記は半径3の円の例）
　きれいに描くには、定義域の
　　x = np.linspace(-4, 4, 400)
　の 400 のところを 2000 とかにすると途切れが目立たなくなります。
 （１つめの式でなぜか warning がでますが、無視してください）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822494/18c816ab-4bb5-4ac6-93fb-b8969bc4c698.png" width=80%>
 
## まとめ
　今回は、GoogleColab上で、Pythonを使って数学のグラフを表示してみる、ということでご紹介いたしました。みなさんも、Pythonを使っていろいろなプログラムを作ってみてください！