はじめに
Pythonでエクセル表やDataFrameをグラフにする方法をまとめる。下図のようなグラフが数行のPythonコードで描画できる。
目次
必要なライブラリ
表をpandas
でDataFrame化して、matplotlib
でグラフ描画する。下記3つのライブラリをpipで取得する。japanize-matplotlib
は、グラフの日本語化けを防いでくれるライブラリ。
pip install pandas
pip install matplotlib
pip install japanize-matplotlib
pip install setuptools # pythonのバージョンによって必要。distutilsのエラーが出るため。
Pythonで実行時は下記のようにimport
する。
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}
})
期間 | 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化する。
# ファイル名 data.xlsx シート名 Sheet1 の場合
df = pd.read_excel('data.xlsx',sheet_name='Sheet1')
グラフ基本
基本は下記となる。df.plot()
でグラフ化し、plt.show()
で描画する。描画せずファイルとして保存する場合はplt.savefig('ファイル名')
。plot()
でグラフのパラメータを指定できる。
パラメータ | 意味 |
---|---|
title | グラフのタイトル。 |
x | x軸にする列を指定する。x を指定しない場合は、DataFrameのIndexが指定される。 |
y | y軸にする列を指定する。ただし、指定できるのは1列のみ。指定しない場合は、x で指定した列以外をy軸とする。 |
grid | グラフのグリッド。つける場合はTrue とする。 |
figsize | 図のサイズ、縦横指定をtupleで指定する。 |
kind | グラフの種類。初期値は line(折れ線グラフ) |
その他パラメータは下記参照。
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()
X軸Y軸のパラメータを変更する
グラフ変換後に設定することができる。
パラメータ | 内容 |
---|---|
x軸の範囲 | set_xlim():設定 get_xlim():取得 |
y軸の範囲 | set_ylim():設定 get_ylim():取得 |
x軸のラベル | set_xlabel():設定 get_xlabel():取得 |
y軸のラベル | set_ylabel():設定 get_ylabel():取得 |
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()
色々なグラフ
kind | グラフの種類 |
---|---|
line | 折れ線グラフ。 |
bar | 棒グラフ。 stacked=Trueで積み上げ。 |
barh | 横棒グラフ。 stacked=Trueで積み上げ。 |
area | 面グラフ。 |
box | 箱ひげグラフ。 |
hist | ヒストグラム。 |
scatter | 散布図。 |
hexbin | 散布図六角形。 gridsizeで六角形の大きさを変更。 |
pie | 円グラフ。 |
png_files=['line.png','bar.png','barh.png','area.png','box.png','hist.png','scatter.png','pie.png']
#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]