pyplotで中学数学のグラフを書く

<h2>前書き</h2>
先日、matplotlib.pyplotを使ったグラフのテキストの日本語化方法を記事にしました。
折角なのでいろいろ覚えようと思ったのですが、公式のチュートリアルはいろいろな機能の紹介が多く「なるほど」レベルでほぼ頭に残らなそうなので、ひとまず「中学数学レベル(一次関数、二次関数)のグラフを書く方法」として、Step by Stepで整理してみました。

※使いこなせれば便利と思いますが、「折れ線グラフとか棒グラフってExcelの方が楽なのでは？」とか「数値の可視化でいちいちコード書くのかったるい」とか考えてしまう「弱エンジニア」なので。。。

<h2>環境</h2>
- Windows10 build 18363.959
- Python 3.8.5
- matplotlib 3.3.0
- numpy 1.19.1

numpyはPythonで使う数値計算用拡張モジュールです。数学の理解が深ければ、こちらも色々使えそうですが、今回はグラフ描画のための数列データの作成に使用しています。

<h2>最初のグラフを描く</h2>
まずは、pyplotにデータを入れて描画させたのみの状態から。

```python:figure1.py
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# 日本語化
matplotlib.rc('font', family='BIZ UDGothic')

# データの作成
x = np.arange(-10., 10., 0.01)
y = 2 * x + 1
print(x.size)
print(y.size)

# データの描画
plt.plot(x, y)

# 軸のラベル
plt.xlabel('X軸')
plt.ylabel('Y軸')

# 表示
plt.show()
```
<h4>プログラムの説明</h4>
- `import ～`で必要なモジュールをインポートしています。
    - `as ～`でインポートしたモジュールを「～」という変数でインスタンス化しています。「インスタンス化」の詳しい説明は避けますが、要は「～という変数でプログラム内で使えるようにする。」と考えてもらえればよいと思います。
- `matplotlib.rc`で日本語フォントを使えるように設定しています。Linuxでは使えるフォントが変わりますので注意。
- `np.arange`を使って、変数`x`の内容を初期化しています。
    - `x`は`-10`から`10`の範囲で、`0.01`刻み。要素数2000。
    - 刻み幅を小さくするとデータの総数は減りますが、グラフが粗くなります。(直線のグラフでは気になりませんが。。。)
- `y = ～`で`x`に対する`y`の値を作成しています。
    - グラフを作るとき、`x`に対する`y`の値が必要ですので、要素数が異なるとエラーになります。基本的には「片方の軸の値からもう一つの軸の値を作成する」方法が無難です。
    - `print`を使ってデータの内容を確認できます。今回はデータ量が多いので、途中が省略された形で表示されます。
- `plt.plot`で描画をしてくれる処理にデータを入れています。
- `plt.xlabel`、`plt.ylabel`で各軸のラベルを設定しています。
- `plt.show`でグラフの描画が行われます。グラフは別ウインドウで開くので、グラフのウインドウを閉じるまで、プラグラム上は一旦停止します。

実行した結果は下記の様になります。
![python_figure1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/87213ad2-97e2-c44b-10c7-60dec3fc4c9e.png)

このままでもグラフとしては正しいのですが、

- 縦横の刻み幅が異なる。
- 格子がない。
- 縦横比が1:1になっていない。
- 始点、終点でグラフが切れている。(そのようなグラフもあるのですが、`-∞<x<∞`のグラフを最初に学ぶので、そのように「見える」方が良い。)
- 原点(座標[0,0])がわかりにくい。

などなど、学習に使うグラフとしてはちょっと困ることがあります。

また、`y`の計算式を`3 * x + 10`に変更した場合は下の様になるのですが、
![python_figure1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/518ef1d6-6e81-e683-b51c-6120b6d81cf7.png)
一見すると同じグラフの様に見えてしまいます。

という事で、いろいろと手を入れていきます。

<h2>2つのグラフを一緒に描く</h2>
まずは`x`の値はそのままで、`y = 2x`と`y = 3x + 10`のグラフを一つにまとめます。
一つのプログラムの中で、同じ変数名を同時に使う事は出来ないので、
`2x`を`y1`、`3x + 10`を`y2`という変数に入れます。
※`x`は同じ値を使うのでそのまま。

```python:figure2.py
y1 = 2 * x
y2 = 3 * x + 10
```
- `y = ～`の行は削除かコメントアウトしてください。

また、`plt.plot`でデータを入れているところも、修正します。

```python:figure2.py
plt.plot(x, y1, x, y2) 
```
- 1つ目、2つ目の変数が、グラフ１のデータ。
- 3つ目、4つ目の変数が、グラフ２のデータ。

実行するとこうなります。
![python_figure2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/8e815bcd-2b4c-d221-e2b8-282723f554ed.png)

値を渡すだけで、色の異なるグラフをきちんと描いてくれるのはユーザーフレンドリーで助かります。

<h2>格子を付ける</h2>
引き続き、今度は格子を追加したいと思います。
グラフによっては、格子があると見難くなったり、そもそも格子が不要という場合もあると思いますが、「グラフから(およその)値を読み取る」などの場合、必要かと思います。
格子の追加は`plt.grid`を使います。

```python:figure3.py
plt.grid(True)
```

- `plt.show`より上であればどこに追加しても良いのですが、今回は`plt.ylabel`の下に追加します。

これを実行すると、
![python_figure3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667657/d041af63-0526-3fa5-00b0-4d07471b5804.png)
と、言う事でだいぶ見やすくなりました。

ここまでくると、だいぶ数学っぽい話ができそうです。

- 青いグラフは傾きが"2"、オレンジのグラフは傾きが"3"。
- 青いグラフはy切片が"0"、オレンジのグラフはy切片が"10"。
- 青いグラフとオレンジのグラフの式を連立方程式として、解を求めると(x, y)=(-10, -20)。

などなど。

<h2>残課題</h2>
記事が長くなってしまったので、

- 縦横比が1:1になっていない。
- 始点、終点でグラフが切れている。(そのようなグラフもあるのですが、`-∞<x<∞`のグラフを最初に学ぶので、そのように「見える」方が良い。)
- 原点(座標[0,0])がわかりにくい。

は一旦、積み残します。
また、ここまでで作成したコードもまとめて残しておきます。

```python:figure3.py
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# 日本語化
matplotlib.rc('font', family='BIZ UDGothic')

# データの作成
# 横軸(X軸)
x = np.arange(-10., 10., 0.01)
# 縦軸(Y軸)
y1 = 2 * x
y2 = 3 * x + 10

# データの描画
plt.plot(x, y1, x, y2)

# 軸のラベル
plt.xlabel('X軸')
plt.ylabel('Y軸')

# 格子の表示
plt.grid(True)

# 表示
plt.show()
```