Pythonのmatplotlibでエクセル表のデータを簡単にグラフにする。

# はじめに
Pythonでエクセル表やDataFrameをグラフにする方法をまとめる。下図のようなグラフが数行のPythonコードで描画できる。

![plot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/c042035c-a4c9-4984-bb9c-559adeb5209e.gif)



# 目次
+ [必要なライブラリ](#必要なライブラリ)
+ [表の準備](#表の準備)
+ [グラフ基本](#グラフ基本)
+ [X軸Y軸のパラメータを変更する](#x軸y軸のパラメータを変更する)


## 必要なライブラリ
表を```pandas```でDataFrame化して、```matplotlib```でグラフ描画する。下記3つのライブラリをpipで取得する。```japanize-matplotlib```は、グラフの日本語化けを防いでくれるライブラリ。 
```cmd:
pip install pandas
pip install matplotlib
pip install japanize-matplotlib
pip install setuptools # pythonのバージョンによって必要。distutilsのエラーが出るため。
```
Pythonで実行時は下記のように```import```する。
```python:
import pandas as pd
import japanize_matplotlib
import matplotlib.pyplot as plt
```


[戻る](#目次)

## 表の準備
今回使う表は下記とする。コードに埋め込むため、辞書型で宣言する。
```python:
df=pd.DataFrame({
	'期間': {0: '2024.1Q', 1: '2024.2Q', 2: '2024.3Q', 3: '2024.4Q', 4: '2025.1Q', 5: '2025.2Q', 6: '2025.3Q', 7: '2025.4Q'},
	'A': {0: 10, 1: 15, 2: 20, 3: 25, 4: 30, 5: 35, 6: 40, 7: 45},
	'B': {0: 5, 1: 5, 2: 5, 3: 5, 4: 10, 5: 10, 6: 10, 7: 10},
	'C': {0: 20, 1: 100, 2: 50, 3: 50, 4: 20, 5: 20, 6: 10, 7: 50},
	'D': {0: 30, 1: 20, 2: 60, 3: 40, 4: 50, 5: 60, 6: 60, 7: 60},
	'合計': {0: 65, 1: 140, 2: 135, 3: 120, 4: 110, 5: 125, 6: 120, 7: 165}
	})
```
|    | 期間      |   A |   B |   C |   D |   合計 |
|---:|:--------|----:|----:|----:|----:|-----:|
|  0 | 2024.1Q |  10 |   5 |  20 |  30 |   65 |
|  1 | 2024.2Q |  15 |   5 | 100 |  20 |  140 |
|  2 | 2024.3Q |  20 |   5 |  50 |  60 |  135 |
|  3 | 2024.4Q |  25 |   5 |  50 |  40 |  120 |
|  4 | 2025.1Q |  30 |  10 |  20 |  50 |  110 |
|  5 | 2025.2Q |  35 |  10 |  20 |  60 |  125 |
|  6 | 2025.3Q |  40 |  10 |  10 |  60 |  120 |
|  7 | 2025.4Q |  45 |  10 |  50 |  60 |  165 |

エクセルであれば、```pd.read_excel```でDataFrame化する。
```python:
# ファイル名 data.xlsx シート名 Sheet1 の場合
df = pd.read_excel('data.xlsx',sheet_name='Sheet1')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/4e355d15-93b1-17f3-59dc-52d44e81194c.png)

[戻る](#目次)

## グラフ基本
基本は下記となる。```df.plot()```でグラフ化し、```plt.show()```で描画する。描画せずファイルとして保存する場合は```plt.savefig('ファイル名')```。```plot()```でグラフのパラメータを指定できる。
パラメータ|意味
---|---
title|グラフのタイトル。
x|x軸にする列を指定する。```x```を指定しない場合は、DataFrameのIndexが指定される。
y|y軸にする列を指定する。ただし、指定できるのは1列のみ。指定しない場合は、```x```で指定した列以外をy軸とする。
grid|グラフのグリッド。つける場合は```True```とする。
figsize|図のサイズ、縦横指定をtupleで指定する。
kind|グラフの種類。初期値は line(折れ線グラフ)

その他パラメータは下記参照。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html


```python:
import pandas as pd
import japanize_matplotlib
import matplotlib.pyplot as plt

#表の準備
df=pd.DataFrame({
	'期間': {0: '2024.1Q', 1: '2024.2Q', 2: '2024.3Q', 3: '2024.4Q', 4: '2025.1Q', 5: '2025.2Q', 6: '2025.3Q', 7: '2025.4Q'},
	'A': {0: 10, 1: 15, 2: 20, 3: 25, 4: 30, 5: 35, 6: 40, 7: 45},
	'B': {0: 5, 1: 5, 2: 5, 3: 5, 4: 10, 5: 10, 6: 10, 7: 10},
	'C': {0: 20, 1: 100, 2: 50, 3: 50, 4: 20, 5: 20, 6: 10, 7: 50},
	'D': {0: 30, 1: 20, 2: 60, 3: 40, 4: 50, 5: 60, 6: 60, 7: 60},
	'合計': {0: 65, 1: 140, 2: 135, 3: 120, 4: 110, 5: 125, 6: 120, 7: 165}
	})
	
#グラフ変換
df.plot(title='折れ線グラフ', x='期間', grid=True, figsize=(5,5))

#描画
plt.show()

#図に保存する場合は
plt.savefig('グラフ.jpg')

#----------------------------------------------------------------
# A,B,Cだけに絞りたい場合はDataFrameを絞ればよい。y軸指定している場合はy軸を忘れずに。
df[['A','B','C','期間']].plot(title='折れ線グラフ', x='期間', grid=True, figsize=(5,5))

#描画
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/dd0e14c9-1ad1-1b8d-3ce8-db49e07a4ed4.png)

[戻る](#目次)

## X軸Y軸のパラメータを変更する
グラフ変換後に設定することができる。
パラメータ|内容
---|---
x軸の範囲|set_xlim():設定<br>get_xlim():取得
y軸の範囲|set_ylim():設定<br>get_ylim():取得
x軸のラベル|set_xlabel():設定<br>get_xlabel():取得
y軸のラベル|set_ylabel():設定<br>get_ylabel():取得

```python:
import pandas as pd
import japanize_matplotlib
import matplotlib.pyplot as plt

#表の準備
df=pd.DataFrame({
	'期間': {0: '2024.1Q', 1: '2024.2Q', 2: '2024.3Q', 3: '2024.4Q', 4: '2025.1Q', 5: '2025.2Q', 6: '2025.3Q', 7: '2025.4Q'},
	'A': {0: 10, 1: 15, 2: 20, 3: 25, 4: 30, 5: 35, 6: 40, 7: 45},
	'B': {0: 5, 1: 5, 2: 5, 3: 5, 4: 10, 5: 10, 6: 10, 7: 10},
	'C': {0: 20, 1: 100, 2: 50, 3: 50, 4: 20, 5: 20, 6: 10, 7: 50},
	'D': {0: 30, 1: 20, 2: 60, 3: 40, 4: 50, 5: 60, 6: 60, 7: 60},
	'合計': {0: 65, 1: 140, 2: 135, 3: 120, 4: 110, 5: 125, 6: 120, 7: 165}
	})

#グラフ変換
ax = df.plot(title='折れ線グラフ', x='期間', grid=True, figsize=(7,7))
# 値セット
ax.set_xlim([0,3]) #X軸
ax.set_xlabel('x軸のラベル')
ax.set_ylim([0,200]) #y軸
ax.set_ylabel('y軸のラベル')

# 値取得
x_min,x_max = ax.get_xlim()
y_min,y_max = ax.get_ylim()
x_label = ax.get_xlabel()
y_label = ax.get_ylabel()
print(f'# {x_min},{x_max},{x_label}/{y_min},{y_max},{y_label}')
# 0.0,3.0,x軸のラベル/0.0,200.0,y軸のラベル

#描画
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/9a0ce6b3-63a9-4387-9b2f-4d52939f7a64.png)

[戻る](#目次)

## 色々なグラフ
kind|グラフの種類
---|---
line|折れ線グラフ。
bar|棒グラフ。<br>stacked=Trueで積み上げ。
barh|横棒グラフ。<br>stacked=Trueで積み上げ。
area|面グラフ。
box|箱ひげグラフ。
hist|ヒストグラム。
scatter|散布図。
hexbin|散布図六角形。<br>gridsizeで六角形の大きさを変更。
pie|円グラフ。


png_files=['line.png','bar.png','barh.png','area.png','box.png','hist.png','scatter.png','pie.png']


```python:
#df = pd.read_excel('data.xlsx',sheet_name='Sheet1')

import pandas as pd
import japanize_matplotlib
import matplotlib.pyplot as plt

#表の準備
df=pd.DataFrame({
	'期間': {0: '2024.1Q', 1: '2024.2Q', 2: '2024.3Q', 3: '2024.4Q', 4: '2025.1Q', 5: '2025.2Q', 6: '2025.3Q', 7: '2025.4Q'},
	'A': {0: 10, 1: 15, 2: 20, 3: 25, 4: 30, 5: 35, 6: 40, 7: 45},
	'B': {0: 5, 1: 5, 2: 5, 3: 5, 4: 10, 5: 10, 6: 10, 7: 10},
	'C': {0: 20, 1: 100, 2: 50, 3: 50, 4: 20, 5: 20, 6: 10, 7: 50},
	'D': {0: 30, 1: 20, 2: 60, 3: 40, 4: 50, 5: 60, 6: 60, 7: 60},
	'合計': {0: 65, 1: 140, 2: 135, 3: 120, 4: 110, 5: 125, 6: 120, 7: 165}
	})
	
#line
df.plot(title='line', x='期間', grid=True, kind='line')
plt.savefig('line.png')
#bar
df.plot(title='bar', x='期間', grid=True, kind='bar')
plt.savefig('bar.png')
#barh
df.plot(title='barh', x='期間', grid=True, kind='barh')
plt.savefig('barh.png')
#area
df.plot(title='area', x='期間', grid=True, kind='area')
plt.savefig('area.png')
#box
df.plot(title='box', x='期間', grid=True, kind='box')
plt.savefig('box.png')
#hist
df.plot(title='hist', x='期間', grid=True, kind='hist')
plt.savefig('hist.png')
#scatter
df.plot(title='scatter', x='A', y='合計' , grid=True, kind='scatter')
plt.savefig('scatter.png')
#hexbin
df.plot(title='hexbin', x='B', y='合計' , grid=True, gridsize=15, kind='hexbin')
plt.savefig('hexbin.png')
#pie
df.plot(title='pie', y='合計', grid=True, kind='pie')
plt.savefig('pie.png')




#グラフ結合
from PIL import Image
#結合グラフ
png_files=['line.png','bar.png','barh.png','area.png','box.png','hist.png','scatter.png','hexbin.png','pie.png']
#PILで開く
gif_frames = [Image.open(png) for png in png_files]
# サイズを1枚目に合わせる。
for cnt in range(len(gif_frames)):
	gif_frames[cnt]=gif_frames[cnt].resize(gif_frames[0].size)
# append_images:次のページ,duration:表示時間(ms),loop:ループ回数0は無限
gif_frames[0].save("plot.gif", save_all=True, append_images=gif_frames[1:], duration=1000, loop=0)![plot.gif]
```
![plot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/c042035c-a4c9-4984-bb9c-559adeb5209e.gif)

[戻る](#目次)