【Python】Matplotlib

Matplotlibの概要

MatplotlibはPythonで重荷二次元のグラフを描画するためのライブラリです。
Matplotlibでグラフを描画するコードには、MATLABスタイルとオブジェクト指向スタイルの2つのスタイルがあります。

Matplotlibのインポートとggplotスタイルの指定

import matplotlib.pyplot as plt
import matplotlib.style
matplotlib.style.use('ggplot')

MATLABスタイル

MATLABスタイルは数値解析ソフトウェアであるMATLABと似た形式でグラフ描画を行う方法です。
このスタイルでは下記のようにmatplotlib.pyplotモジュールに対してグラフを描画するための各種関数を実行します。

x = [1,2,3]
y = [3,5,9]

plt.plot(x,y)
plt.title('MATLAB-style')

plt.show()

オブジェクト指向スタイル

オブジェクト指向スタイルは描画オブジェクトに対してサブプロットを追加して、サブスロットに対してグラフを描画します。オブジェクト指向スタイルでは1つのfigureオブジェクトに対して複数のサブプロットを指定し、複数のグラフをまとめて表示できます。

x = [1,2,3]
y = [3,5,9]

#描画オブジェクト(fig)とサブプロット(sub)
fig, sub = plt.subplots()

sub.plot(x,y)
sub.set_title('OBJ-style')

plt.show()

描画オブジェクト

描画オブジェクトとサブプロット

Matplotlibでグラフを描画するには、描画オブジェクト(figure)を生成し、その中に1つ以上のサブプロット(subplot)を配置します。subplot(2)と指定すると2つのサブプロットが配置されます。

import matplotlib.pyplot as plt
fig, axes = plt.subplots(2)
plt.show()

subplot(2,2)と指定すると2行2列の4つのサブプロットが配置されます。

fig, axes = plt.subplots(2,2)
plt.show()

それぞれの引数はキーワード引数nrows、ncolsでも指定可能です。

fig, axes = plt.subplots(nrows=2)
plt.show()

fig, axes = plt.subplots(ncols=2)
plt.show()

グラフのスタイル

matplotlib.styleを使用するとグラフの表示スタイル(線の色、太さ、背景色等)が指定できます。
下記ではスタイルの一覧を表示しています。

import matplotlib.style
print(matplotlib.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 
'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-v0_8',
'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette',
'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook',
'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk',
'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']

グラフのスタイルを’_classic_test_patch’に指定

matplotlib.style.use('_classic_test_patch')

fig,ax=plt.subplots()
ax.plot([1,2])

plt.show()

タイトル

描画オブジェクトとサブプロットにはタイトルを指定します。

fig, axes = plt.subplots(ncols=2)

#サブプロットにタイトル設定
axes[0].set_title('subplot title0')
axes[1].set_title('subplot title1')

#描画オブジェクトにタイトル設定
fig.suptitle('figure title')

plt.show()

軸ラベル

グラフのスタイル軸にラベルを指定します。

fig, ax = plt.subplots()

ax.set_xlabel('x label')
ax.set_ylabel('y label')

plt.show()

凡例

サブプロットに凡例を表示できます。
loc=’best’と指定してデータとの重なりが最小の位置に出力します。

fig, ax = plt.subplots()

#凡例用のラベルを設定
ax.plot([1,2,3],[2,6,8],label='subplots label')
ax.legend(loc='best')

plt.show()

凡例を右下に表示

fig, ax = plt.subplots()

#凡例用のラベルを設定
ax.plot([1,2,3],[2,6,8],label='subplots label')
ax.legend(loc='best')

plt.show()

ファイル出力

作成したグラフをsavefigメソッドでファイルに出力できます。
ファイル形式は、png、pdf、ps、eps、svgが選択可能です。

fig, ax = plt.subplots()
ax.set_title ('subplot title')
fig.savefig('sample-figure.png')

グラフの種類と出力方法

折れ線グラフ

pltメソッドの引数には折れ線グラフのX座標、Y座標を表す配列またはスカラーを渡します。

fig, ax = plt.subplots()

x=[1,2,3]
y1=[2,3,3]
y2=[3,2,3]
ax.plot(x,y1)
ax.plot(x,y2)

plt.show()

値の間隔を細かくすることで疑似的に曲線のグラフも作成できます。

import numpy as np

x=np.arange(0.0,10.0,0.1)
y1=np.sin(x)
y2=np.cos(x)

fig,ax=plt.subplots()
ax.plot(x,y1,label='sin')
ax.plot(x,y2,label='cos')
ax.legend()

plt.show()

棒グラフ

棒グラフの描画にはbarメソッドを使用します。

fig, ax=plt.subplots()

x=[1,2,3]
y=[5,2,8]
labels = ['A','B','C']
ax.bar(x,y,tick_label=labels) #棒グラフ描画、ラベルを指定

plt.show()

横向きの棒グラフを描画するには、barをbarhに変えるだけです。

fig, ax=plt.subplots()

x=[1,2,3]
y=[5,2,8]
labels = ['A','B','C']
ax.barh(x,y,tick_label=labels) #棒グラフ描画、ラベルを指定

plt.show()

複数のグラフを並べて表示するには、棒グラフの幅を指定してずらして描画します。

fig, ax = plt.subplots()

x=[1,2,3]
y1=[5,2,8]
y2=[10,3,6]
labels=['A','B','C']

width=0.3  #棒グラフの幅を0.3にする
ax.bar(x,y1,width=width,tick_label=labels,label='y1') #幅を指定して描画

#幅分をずらして棒グラフを描画
x2=[num + width for num in x]
ax.bar(x2,y2,width=width,tick_label=labels,label='y2')

ax.legend()
plt.show()

積み上げグラフの描画は、複数の値を持っている場合は全て足した棒グラフをまず描画して、その次に片方の値のみの棒グラフを描画します。

fig, ax = plt.subplots()

x=[1,2,3]
y1=[5,2,8]
y2=[10,3,6]

labels=['A','B','C']

y_total=[num1 + num2 for num1, num2 in zip(y1,y2)]

#y1、y2を足した高さの棒グラフを描画
ax.bar(x,y_total,tick_label=labels,label='y1')
ax.bar(x,y2,tick_label=labels,label='y2')

ax.legend()
plt.show()

散布図

散布図を作成するにはscatterメソッドを使用します。
下記ではランダムに生成した100個の要素で描画したものです。

fig, ax = plt.subplots()

np.random.seed(1230)
x=np.random.rand(100)
y=np.random.rand(100)

ax.scatter(x,y)

plt.show()

デフォルトではマーカーは〇で描画されますが、marker引数にマーカーの形を指定することにより、様々な形のマーカーを使用できます。

fig, ax = plt.subplots()

np.random.seed(1230)
x=np.random.rand(100)
y=np.random.rand(100)

ax.scatter(x[0:20],y[0:20], marker='v',label='下向き三角形')
ax.scatter(x[20:40],y[20:40], marker='^',label='上向き三角形')
ax.scatter(x[40:60],y[40:60], marker='s',label='正方形')
ax.scatter(x[60:80],y[60:80], marker='*',label='星形')
ax.scatter(x[20:40],y[80:100], marker='x',label='X')

ax.legend
plt.show()

ヒストグラム

ヒストグラムを描画するにはhistメソッドを使用します。

#データ生成
np.random.seed(1230)
mid=80 #平均値
sigma=20 #標準偏差
x= np.random.normal(mid,sigma,1000)

fig,ax=plt.subplots()

#ヒストグラム描画
n,bins,patches=ax.hist(x)

plt.show() 

histメソッドは返り値として度数分布表に使用できるデータを返します。
nには各bin(棒)の度数(要素数)が格納されています。
binsにはビンの境界の値、patchesにはビンを描画するための情報が入っています。
下記コードでデータが出力できます。

for i, num in enumerate(n):
 print('{:.2f}-{:.2f}: {}'.format(bins[i], bins[i +1],num))
17.37-30.92: 16.0
30.92-44.47: 25.0
44.47-58.02: 92.0
58.02-71.58: 209.0
71.58-85.13: 233.0
85.13-98.68: 262.0
98.68-112.23: 112.0
112.23-125.79: 43.0
125.79-139.34: 5.0
139.34-152.89: 3.0

histメソッドのデフォルトのビン数は10ですが、bins引数に任意の値を指定するとビン(棒)の数を変更できます。

#データ生成
np.random.seed(1230)
mid=80 #平均値
sigma=20 #標準偏差
x= np.random.normal(mid,sigma,1000)

fig,ax=plt.subplots()

#ヒストグラム描画
n,bins,patches=ax.hist(x,bins=30)

plt.show() 

histメソッドの引数にorientation=’horizontal’と指定すると横向きのヒストグラムが描画できます。

#データ生成
np.random.seed(1230)
mid=80 #平均値
sigma=20 #標準偏差
x= np.random.normal(mid,sigma,1000)

fig,ax=plt.subplots()

#ヒストグラム描画
n,bins,patches=ax.hist(x,orientation='horizontal')

plt.show() 

棒グラフと異なり、ヒストグラムでは複数の値を指定すると自動的に横に並べて表示してくれます。

#データ生成
np.random.seed(1230)
mid=80 #平均値
sigma=20 #標準偏差
x0= np.random.normal(mid,sigma,1000)

#異なる標準偏差でデータ生成
x1= np.random.normal(mid,13,1000)
x2= np.random.normal(mid,9,1000)

fig,ax=plt.subplots()
labels=['x0','x1','x2']

#ヒストグラム描画
ax.hist((x0,x1,x2),label=labels)

ax.legend()
plt.show() 

また、histメソッドの引数にstacked=Trueと指定すると、積み上げたヒストグラムが描画されます。

#データ生成
np.random.seed(1230)
mid=80 #平均値
sigma=20 #標準偏差
x0= np.random.normal(mid,sigma,1000)

#異なる標準偏差でデータ生成
x1= np.random.normal(mid,13,1000)
x2= np.random.normal(mid,9,1000)

fig,ax=plt.subplots()
labels=['x0','x1','x2']

#ヒストグラム描画
ax.hist((x0,x1,x2),label=labels,stacked=True)

ax.legend()
plt.show() 

箱ひげ図

箱ひげ図を描画するには、boxplotメソッドを使用します。

#データ生成
np.random.seed(1230)
x0= np.random.normal(0,20,300)
x1= np.random.normal(0,15,300)
x2= np.random.normal(0,10,300)

fig,ax=plt.subplots()
labels=['x0','x1','x2']
ax.boxplot((x0,x1,x2),labels=labels)

plt.show() 

boxplotメソッドの引数にvert=Falseと指定すると横向きの箱ひげ図を描画します。

#データ生成
np.random.seed(1230)
x0= np.random.normal(0,20,300)
x1= np.random.normal(0,15,300)
x2= np.random.normal(0,10,300)

fig,ax=plt.subplots()
labels=['x0','x1','x2']
ax.boxplot((x0,x1,x2),labels=labels,vert=False)

plt.show() 

円グラフ

円グラフはpieメソッドで描画します。
サブプロットに対してaxis(‘equal’)と指定するとアスペクト比を保持します。

labels=['A','B','C']
x=[9,4,2]

fig,ax=plt.subplots()

ax.pie(x,labels=labels)
ax.axis('equal')

plt.show()

円グラフはデフォルトで右(時計3時の位置)から反時計回りで各要素が配置されます。
上(時計12時の位置)から配置するにはcounterclock=Falseを指定します。

labels=['A','B','C']
x=[9,4,2]

fig,ax=plt.subplots()

ax.pie(x,labels=labels, startangle=90,counterclock=False)
ax.axis('equal')

plt.show()


円グラフに影をつけるには、shadow=Trueと指定します。
また、autopct=’%1.2f%%’のように指定すると、値のパーセント表記が追加されます。
‘%1.2f%%’は小数点2桁までを表します。

labels=['A','B','C']
x=[9,4,2]

fig,ax=plt.subplots()

ax.pie(x,labels=labels, startangle=90,counterclock=False,
       shadow=True,autopct='%1.2f%%')
ax.axis('equal')

plt.show()


円グラフでは一部の値を目立たせるためにexplode引数に値を指定して要素を切り出して表示させることができます。

explode=[0,0,0.2]  #2番目の要素(C)を切り出す
labels=['A','B','C']
x=[9,4,2]

fig,ax=plt.subplots()

ax.pie(x,labels=labels, startangle=90,counterclock=False,
       shadow=True,autopct='%1.2f%%',explode=explode)
ax.axis('equal')

plt.show()

複数のグラフを組み合わせる

複数のグラフを組み合わせることも可能です。
下記は棒グラフと折れ線グラフを組み合わせたものです。

fig,ax=plt.subplots()

x1=[1,2,3]
y1=[6,2,3]
x2=[1,2,3,4]
y2=[9,6,5,7]
ax.bar(x1,y1,label='y1') #棒グラフ描画
ax.plot(x2,y2,label='y1') #折れ線グラフ描画

ax.legend()
plt.show()

ヒストグラムと折れ線グラフ

#データ生成
np.random.seed(1230)
x= np.random.randn(1000) #正規乱数を生成

fig,ax=plt.subplots()

#ヒストグラム描画
counts,edges,patches=ax.hist(x,bins=30)

#近似曲線に用いる点を求める(ヒストグラムのビンの中点)
x_fit=(edges[:-1] + edges[1:])/2

#近似曲線をプロット
y=1000*np.diff(edges)*np.exp(-x_fit**2/2)/np.sqrt(2*np.pi)
ax.plot(x_fit,y)

plt.show() 

スタイル

色の設定

グラフに表示する線、背景色、枠線などの要素に色が指定できます。

fig,ax=plt.subplots()

#線の色を名前で指定
ax.plot([1,5],[5,1],label='aqua',color='aqua')

#16進数のRGBで指定
ax.plot([1,5],[1,5],label='#0000FF',color='#0000FF')

#RGBAをfloatで指定
ax.plot([1,5],[3,3],label='(0,0,0,1)',color=(0,0,0,1))

ax.legend()

plt.show()

棒グラフや散布図にはcolor引数とedgecolor引数が指定できます。

fig,ax=plt.subplots()

ax.bar([1],[5],color='aqua') #塗りつぶしの色
ax.bar([2],[4],color='aqua',edgecolor='black')

plt.show()

線のスタイル

折れ線グラフやグラフの枠線など様々な線に対してスタイルを適用できます。

fig,ax=plt.subplots()

#6.5ポイントの幅の線で描画
ax.plot([1,5],[5,1],linewidth=6.5,label='6.5')

#11ポイントの幅の線で描画
ax.plot([1,5],[1,5],linewidth=11,label='11')
ax.legend()

plt.show()


linestyle引数では線の種類が指定できます。

fig,ax=plt.subplots()

#破線で描画
ax.plot([1,5],[5,1],linestyle='--',label='dashed')

#一点鎖線で描画
ax.plot([1,5],[1,5],linestyle='-.',label='dashdot')

#点線で描画
ax.plot([1,5],[3,3],linestyle=':',label='dotted')

ax.legend()

plt.show()

フォント

タイトル、凡例、軸ラベルなどのテキストに対してスタイルを適用できます。
size引数にはフォントサイズ
weight引数にはフォントの太さ(light、bold、heavyなど)
family引数にはフォントの種類(serif、sans-serif、cursive、fantasy、monospaceなど)

fig,ax=plt.subplots()

ax.set_xlabel('xlabel',family='monospace',size=25,weight='heavy')
ax.set_ylabel('ylabel',family='fantasy',size=20,weight='bold')
ax.set_title('title',family='cursive',size=40,weight='light')

plt.show()

フォントのスタイルを辞書で定義することも可能です。

#フォントのスタイルを辞書で定義
fontdict={
    'family':'monospace',
    'size':25,
    'weight':'bold'
}

fig,ax=plt.subplots()

ax.set_xlabel('xlabel',fontdict=fontdict)
ax.set_ylabel('ylabel',fontdict=fontdict)

#サイズだけ上書き
ax.set_title('title',fontdict=fontdict,size=40)

plt.show()

テキスト描画

textメソッドを使用するとグラフに任意のテキストを描画できます。

fig,ax=plt.subplots()

ax.text(0.3,0.5,'Text',size=25)

plt.show()

pandasのオブジェクトからグラフ描画

折れ線グラフ描画

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

matplotlib.style.use('ggplot')

#DataFrameを作成
df=pd.DataFrame({'A':[2,4,6],'B':[3,5,7]})
df.plot() #折れ線グラフ描画

plt.show()

棒グラフ描画

import numpy as np

np.random.seed(1230)
df2=pd.DataFrame(np.random.rand(3,2),columns=['y1','y2'])

df2.plot.bar() #棒グラフ描画
plt.show()

積み上げグラフ描画

import numpy as np

np.random.seed(1230)
df2=pd.DataFrame(np.random.rand(3,2),columns=['y1','y2'])

df2.plot.bar(stacked=True) #棒グラフ描画
plt.show()

この記事は役に立ちましたか?

もし参考になりましたら、下記のボタンで教えてください。

関連記事

コメント

この記事へのコメントはありません。