【Matplotlib】Python　グラフ描画テンプレート

## 1. はじめに
今回はMatplotlibというPythonのグラフ描画ライブラリを用いて、グラフの作成を行なっていきます。この記事では、Matplotlibの基礎から、実際のグラフ描画までの基本的な使い方やテンプレートを紹介していきます。
## 2. 環境構築
### 2-1. ライブラリの詳細
まずは、Pythonの環境構築を行います。
今回は、以下の4つのライブラリをインポートします。
- **NumPy**  
  様々な数値計算をサポートするライブラリ。平均値や中央値の計算、行列やベクトルの計算を行える関数がある

- **Matplotlib**  
  グラフを描画するためのライブラリ。折れ線グラフ、棒グラフ、散布図などを様々なグラフを簡単に描け、視覚化に便利である

- **pandas**  
  データ操作に特化したライブラリで、データフレームを使って表データを扱う。データの集計や分析がしやすい

- **japanize-matplotlib**  
  Matplotlibで日本語フォントをサポートするためのライブラリ。グラフ上に日本語を使う際の文字化けを防ぐ

### 2-2. ライブラリのインストール
- **個別にインストール**  
```terminal
pip install numpy
pip install matplotlib
pip install pandas
pip install japanize-matplotlib
```
- **個別にインストール**  
 ```terminal
pip install numpy matplotlib pandas japanize-matplotlib
```
### 2-3. ライブラリのインポート
Pythonでライブラリをインポートする際は、コードファイルの一番上（冒頭部分）に以下のインポート文を記述します。
```Python
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import japanize_matplotlib
```

## 3. グラフの基本要素
まず、前提としてグラフには様々な設定をする必要があります。軸ラベルや凡例、目盛、タイトル、配色など詳細に設定を加えることができるので、それらをうまく有効活用できれば、視認性に優れたグラフを作成することができるでしょう！今回は``` Pyplot ```と``` Axesオブジェクト ```をメインに詳細設定を確認していきます。

### 3-1. Pyplot （ plt ）について
``` plt ```は、``` matplotlib.pyplotモジュール ```からインポートされたインターフェースで、基本的なグラフ作成やカスタマイズが簡単に行うことができます。個人的には初学者の方は``` plt ```の方が扱いやすいと思います。

#### 3-1-1. Pyplotのプログラム
以下は、``` plt ```を使用して描画した折れ線グラフのプログラム
```Python:sine_wave_ex.py
import matplotlib.pyplot as plt
import numpy as np

# データの作成
x = np.linspace(0, 10, 100)
y = np.sin(x)

# グラフの作成
plt.figure(figsize=(8, 6))  

# 折れ線グラフの描画
plt.plot(x, y, label='Sine Wave', color='blue', linestyle='-', linewidth=2, marker='o')

# タイトルと軸ラベルの設定
plt.title('Sine Wave Example', fontsize=16)    
plt.xlabel('X-axis Label', fontsize=14)         
plt.ylabel('Y-axis Label', fontsize=14)          

# 軸の範囲の設定
plt.xlim(0, 10)                                 
plt.ylim(-1.5, 1.5)                               

# グリッドの設定
plt.grid(True, which='both', linestyle='--', color='gray', alpha=0.7)  

# 目盛りの設定
plt.xticks(np.arange(0, 11, 1))                 
plt.yticks(np.arange(-1, 2, 0.5))                  

# 凡例の表示
plt.legend(loc='upper right', fontsize=12)        

# PDFに保存（先に保存）
plt.savefig('sine_wave_ex.pdf')

# グラフの表示
plt.show()
```
#### 3-1-2. プログラムの仕様
- ``` np.linspace(start, stop, num) ``` :```start```から```stop```までの指定した範囲なを```num```の数値分だけ等間隔に数値を生成する関数。今回は1から10までを100等分するので、$x = 0.1, 0.2, 0.3, \sim$となる。
- ``` np.sin(x) ``` :与えられたxの値に対して、サイン関数を適用して、その結果を返す仕様。
- ``` plt.figure(figsize=(width, height)) ```:グラフのサイズを指定する関数。``` 第一引数 ```が横の長さで、``` 第二引数 ```が縦の長さを指定。(基本的に単位はインチ)
- ``` plt.plot(x, y, label='#', color='#', linestyle='#', linewidth=#, marker='#') ```:折れ線グラフの描画を行う関数。凡例のラベル・線の配色・線の形状・線の太さ・マーカーを指定することができる
- `plt.title('Title', fontsize=14)` : グラフのタイトルを指定する関数。`fontsize`でタイトルのフォントサイズを調整できる。

- `plt.xlabel('X-axis Label', fontsize=14)` と `plt.ylabel('Y-axis Label', fontsize=14)` : X軸とY軸のラベルを指定する関数。`fontsize`でラベルのフォントサイズを調整。

- `plt.xlim(left, right)` と `plt.ylim(bottom, top)` : X軸とY軸の表示範囲を設定する関数。指定した範囲内でグラフが描画される。

- `plt.grid(True, which='both', linestyle='#', color='#', alpha=#)` : グリッド線を表示する関数。`True`でグリッド線を有効化し、`which`で表示する軸を指定、`linestyle`でグリッド線の形状、`color`で色、`alpha`で透明度を設定。

- `plt.xticks(ticks)` と `plt.yticks(ticks)` : X軸およびY軸の目盛りを指定する関数。`ticks`で目盛りの位置を指定する。

- `plt.legend(loc='#', fontsize=#)` : 凡例を表示する関数。`loc`で凡例の位置、`fontsize`でフォントサイズを設定。

- `plt.savefig('#')` : 現在のグラフを指定したファイル名で保存する関数。ここではPDFファイルとして保存される。

- `plt.show()` : グラフを画面に表示する関数。インタラクティブなプロットウィンドウが開き、グラフを確認できる。

### 3-1-3. 描画されたグラフ
![sine_wave_ex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741767/4ec932a8-4f4b-4e35-65fb-6bff92d88f46.png)

### 3-2. Axesについて
``` ax ```は、``` matplotlib.axes.Axesオブジェクト ```であり、グラフの個別の「軸」を操作するために使用する。軸を操作するため、複数のサブプロットの作成が可能である。

#### 3-2-1. Axesのプログラム
以下は、Axesを使用して描画した折れ線グラフのプログラム
```Python:
![sine_wave_ax.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741767/932de368-2e3c-ec90-80fd-c2b6541e2925.png)
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots(figsize=(8, 6))  # Axesオブジェクトを作成
ax.plot(x, y)  # グラフを描く
ax.set_title("Sine Wave")  # タイトルを設定
ax.set_xlabel("X-axis")  # X軸ラベル
ax.set_ylabel("Y-axis")  # Y軸ラベル
plt.show()  # グラフを表示

```
#### 3-2-2. プログラムの仕様

- `np.linspace(start, stop, num)` : `start`から`stop`までの範囲を`num`個の等間隔で分割して数値を生成する関数。ここでは0から10までを100等分し、`x`に0.1刻みのデータ列を作成。

- `np.sin(x)` : 与えられた`x`の値に対してサイン関数を適用し、各点のサイン値を返す。

- `fig, ax = plt.subplots(figsize=(width, height))` : Figure（図全体）とAxes（描画領域）を作成する関数。`figsize`でFigureのサイズを指定し、ここでは横8インチ、縦6インチで設定。

- `ax.plot(x, y)` : `ax`に`x`と`y`のデータを用いてグラフを描画する関数。

- `ax.set_title("Title")` : グラフのタイトルを設定する関数。

- `ax.set_xlabel("X-axis")` と `ax.set_ylabel("Y-axis")` : X軸およびY軸のラベルを設定する関数。
- `plt.show()` : 作成したグラフを画面に表示する関数。

#### 3-2-3. 描画されたグラフ
![sine_wave_ax.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741767/13497321-96a4-f3b3-9af2-4a19536754b8.png)

#### 3-2-EX. Axesの応用 ~複数のグラフの描画~
Axesは軸をベースに設定することで、サブプロットを作成することができるので、今回は$sin(x), cos(x), tan(x)$のグラフを作成してみましょう。
```Python:sin_cos_tan.py
import matplotlib.pyplot as plt
import numpy as np

# x軸の範囲とデータの作成
x = np.linspace(-2 * np.pi, 2 * np.pi, 400)
y_sin = np.sin(x)
y_cos = np.cos(x)
y_tan = np.tan(x)

# Figureと3つのAxesオブジェクトを作成（1列3行のレイアウト）
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 12))

# sin(x)のプロット
ax1.plot(x, y_sin, color='blue', label='sin(x)')
ax1.set_title("Sine Function")
ax1.set_xlabel("x")
ax1.set_ylabel("sin(x)")
ax1.legend()
ax1.grid(True)

# cos(x)のプロット
ax2.plot(x, y_cos, color='green', label='cos(x)')
ax2.set_title("Cosine Function")
ax2.set_xlabel("x")
ax2.set_ylabel("cos(x)")
ax2.legend()
ax2.grid(True)

# tan(x)のプロット（表示範囲を制限）
ax3.plot(x, y_tan, color='red', label='tan(x)')
ax3.set_title("Tangent Function")
ax3.set_xlabel("x")
ax3.set_ylabel("tan(x)")
ax3.set_ylim(-10, 10)  # tan(x)は無限大になるので範囲を制限
ax3.legend()
ax3.grid(True)

# グラフの間に余白を調整
plt.savefig('sin_cos_tan_wave.png')
plt.tight_layout()
plt.show()
```
**ポイントなるのが…**
`fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 12))`**の部分である！**

- `fig, (ax1, ax2, ax3) = plt.subplots(#, #, figsize=(#, #))`:グラフの大きさを指定し、3つのAxesオブジェクトを作成する。plt.subplotsは第一引数に「行に配置するプロット数」、第二引数に「列に配置するプロット数」を指定することで、#行#列のレイアウトにすることができる。（今回は1列3行のレイアウトになる→縦長）

![sin_cos_tan_wave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741767/dfa48f07-5ab5-7d39-a8e4-450417adb3d1.png)

### 3-3. PypltとAxesの比較
|                | `plt`（Pyplot）                              | `ax`（Axesオブジェクト）                         |
|--------------------|----------------------------------------------|--------------------------------------------------|
| **使いやすさ** | 簡単で直感的　　　　　　　 → **初心者におすすめ** | 複雑だが柔軟なカスタマイズが可能 　　　　　 → **グラフを詳細にこだわりたい人向け**|
| **適用範囲**| 単一のグラフや簡単なグラフの作成に最適 | サブプロットや詳細なカスタマイズに最適|
| **主な利用** | **1つのグラフ**を手軽に描画したい時 | **複数のグラフ**や詳細なカスタマイズが必要な時|


## 4. グラフ描画テンプレート
ここでは、Matplotlibを用いて、描画できるグラフのテンプレートコードを掲載します。
今回紹介するのは、

- **折れ線グラフ**（Line Plot）→`plt.plot()`
データの傾向や変化を視覚化するためのグラフ。時間経過などの連続データを表すのに便利。

- **散布図**（Scatter Plot）→`plt.scatter()`
2つの変数の関係を視覚化するのに使用。データの分布や相関を確認する際に使う。

- **棒グラフ**（Bar Plot）→`plt.bar()（縦棒） / plt.barh()（横棒）`
カテゴリごとのデータを比較するためのグラフ。縦棒（棒グラフ）と横棒（横棒グラフ）がある。

- **ヒストグラム**（Histogram）→`plt.hist()`
データの分布状況を視覚化するためのグラフ。特にデータがどのように散らばっているかを確認するのに便利。

- **箱ひげ図**（Box Plot）→`plt.boxplot()`
データの分布や外れ値を確認するためのグラフ。四分位範囲でデータの散らばりを表す。

- **円グラフ**（Pie Chart）→`plt.pie()`
各カテゴリーの割合を視覚化するのに使用。データの構成比を円で表す。

- **エリアチャート**（Area Chart）→`plt.fill_between()`
折れ線グラフの下の領域を塗りつぶしたグラフで、変化量を視覚化。

- **ヒートマップ**（Heatmap）→`plt.imshow() または plt.pcolor()`
データを色の濃淡で表現し、行と列の関係を視覚化。

- **等高線図**（Contour Plot）→`plt.contour() / plt.contourf()`
3次元データの等高線を表示するグラフ。特に地形や密度の変化を示すのに利用。

- **誤差棒付きグラフ**（Error Bar Plot）→`plt.errorbar()`
各データポイントの誤差範囲を示すためのグラフ。誤差の大きさを視覚化。

- **棒積み上げグラフ**（Stacked Bar Chart）→`plt.bar()（積み上げオプションを利用）`
複数のカテゴリを積み上げた棒グラフで、各部分が全体に占める割合を比較。

### 4-1. 折れ線グラフ
```Python:line_graph.py
import matplotlib.pyplot as plt
import numpy as np

# データの作成
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 折れ線グラフの描画
plt.plot(x, y, color='blue', linestyle='-', linewidth=2, marker='o', markersize=5, label='sin(x)')
# color option：'blue', 'red', '#FF5733' などの16進数カラーコードも指定可
# linestyle option：'-'(実線), '--'(破線), ':'(点線), '-.'(点破線)
# marker option：'o'(丸), 's'(四角), 'D'(ダイヤ)', '^'(上向き三角)

plt.title('Line Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.grid(True)
plt.show()
```
### 4-2. 散布図
```Python:scatter_plot.py
x = np.random.rand(50) #点(x,y)のxを入力する（リスト形式）
y = np.random.rand(50) #点(x,y)のyを入力する（リスト形式）
sizes = np.random.rand(50) * 100  # サイズのランダムな配列
colors = np.random.rand(50)       # 色のランダムな配列

# 散布図の描画
plt.scatter(x, y, s=sizes, c=colors, cmap='viridis', alpha=0.7, edgecolor='black', label='Data Points')
# c option：（色指定）
# cmap option：（カラーマップ）'viridis', 'plasma', 'rainbow'
# alpha option：（マーカー透明度）0（透明） ~ 1.0(不透明)
# edgecolor option：（マーカーの輪郭色）

plt.colorbar()  # カラーバーを表示
plt.title('Scatter Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.grid(True)　 
plt.show()
```

### 4-3. 棒グラフ
```Python:bar_graph.py
categories = ['A', 'B', 'C', 'D'] #リスト形式
values = [5, 7, 2, 4] #リスト形式

# 棒グラフの描画
plt.bar(categories, values, color='skyblue', edgecolor='black', width=0.6, label='Values')
# bar position：(バーの位置)'center''edge'
plt.title('Bar Plot')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.legend()
plt.grid(axis='y')
plt.show()

```

### 4-4. ヒストグラム
```Python:histgram.py
data = np.random.randn(1000)  # 標準正規分布の乱数

# ヒストグラムの描画
plt.hist(data, bins=30, color='purple', edgecolor='black', alpha=0.7, label='Frequency')
plt.title('Histogram')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.legend()
plt.grid(axis='y')
plt.show()
```
### 4-5. 円グラフ
```Python:pie_chart.py
labels = ['A', 'B', 'C', 'D']　# 描画する要素数分
sizes = [15, 30, 45, 10]  # 合計が100となるように調整する
explode = (0, 0.1, 0, 0)  # 2番目の要素を少し引き出す

# 円グラフの描画
plt.pie(sizes, labels=labels, explode=explode, autopct='%1.1f%%', startangle=140, colors=['gold', 'lightcoral', 'lightskyblue', 'lightgreen'])
# colors：指定した要素順にcolorsが適用される
plt.title('Pie Chart')
plt.show()

```

## 5. おわりに
今回はPythonのMatplotlibというライブラリを使って、様々なグラフの描画行ってきました。
グラフのテンプレートは数値や名称などを変えれば、すぐに使うことができるので、ぜひ使ってみてください!

### 追記　~描画したグラフをPDFやJPEGで出力する方法について~
描画したグラフをPDFやJPEG、PNGとして出力する方法があるので紹介しときます。
```Python
plt.savefig("file_name.png") #PNG形式で保存（file_name.pngとして保存されます）
plt.savefig("file_name.pdf") #PDF形式で保存（file_name.pdfとして保存されます）
plt.savefig("file_name.jpeg") #JPEG形式で保存（file_name.jpegとして保存されます）
```
:::note alert
**plt.savefigの記入注意**
plt.savefigを追加する際は、必ず` plt.show() `の前に挿入してください。
→` plt.show() `の後に挿入すると、ファイルは作成されるが、グラフデータが記入されていないままになるので、注意が必要です！
:::