【入門】C#技術者の為のPython独学!グラフ作成(matplotlib)編

当ページのリンクには広告が含まれています。

C#には様々な種類のグラフ描画ライブラリがあるように、Pythonにも様々なライブラリが用意されています。

今回は、その中で最も標準で使われる matplotlib というライブラリについて解説します。

目次

最初の準備(インストールとインポート)

まず初めに matplotlib をインストールしなければなりません。

matplotlibは Anaconda をインストールするとPythonと一緒にインストールされます。

anaconda を使わず python を直接インストールしている場合は、次のコマンドを使ってインストールして下さい。

# anaconda を使わず pythonを直接インストールしていた場合
pip install matplotlib

#anaconda を使ってインストールする場合
conda install matplotlib

インストールされている環境では、プログラムの先頭に次の1行を記述することで使えるようになります。

import matplotlib.pyplot as plt

多くのサンプルにおいて、matplotlib は plt という略称で使われることが多いようなので、この記事でも、plt と記述することにします。

matplotlibの概要

matplotlib を使うと、グラフに応じたメソッドにデータを指定し、show メソッドを呼び出すだけでグラフを表示することが可能です。

例えば、pandas の read_csv を使ってCSVファイルを読み込み、折れ線グラフを表示する場合は次の様になります。

import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv('d:\data.csv')
plt.plot(df)
plt.show()

showメソッドを呼ぶと次のウィンドウが表示され、そこにグラフが表示されます。

グラフは単に表示されるだけではなく、マウスを使って見たい箇所を中央に移動したり、一部分を拡大表示し、その状態を画像としてファイルに保存することも可能です。

matplotlib の詳しい使い方については「公式ページ」があるので、より詳細な情報が必要な場合はご参照下さい。

とにかく表現力が豊かで、様々なグラフを描くことが出来ます。

下記は公式サイトのGalleryページに記載されているサンプルの一部を抜粋したものです。

引用元:matplotlib公式サイトより

とにかくバリエーションが豊富なことに加え、各画像をクリックすると対応するサンプルソースも参照できるなど、至れり尽くせりです。

はっきり言って、C#の無料グラフ作成ツールはmatplotlibの足元にも及ばないという感じです。

グラフ表示の基本

matplotlib は 1つのグラフを表示するだけではなく、異なった複数のグラフを同時に表示することが可能です。

例えるなら、1つのホワイトボードに対して、複数のグラフを張り付けるようなイメージです

この ホワイトボードに相当するものが figure です。

figure の中には複数の表示エリアを配置することが可能で、それを Axes と呼んでいます。

Axesは 複数の軸(X軸、Y軸)で構成されていて、この1つ1つの軸のことをAxisと呼んでいます。

ちなみに、Axes は Axis の複数形です。

日本語フォントへの対応

matplotlib でグラフを表示する際、タイトルや軸タイトルに漢字を表示すると文字化けしてしまいます。

しかし、これは matplotlib が対応している日本語フォントを使うようにすれば解決できます。

タイトル等を引数に持つメソッドでは、フォントファミリーを指定できるものも数多く存在しますが、毎回指定するのは面倒です。

幸いにも matplotlib 全体で様々な初期値を変更できる方法があるので、それを使います。

具体的には、rcParams をインポートし、rcParams['font.family'] にて日本語フォントを指定しています。

import matplotlib.pyplot as plt
from matplotlib import rcParams

#漢字が使えるフォントを指定する。
rcParams['font.family'] = 'Meiryo'   # フォントを指定
rcParams['font.size'] = 12'          # フォントサイズを指定

#これ以降は漢字が表示できるようになる

全ての日本語フォントに対応している訳ではありませんが、Meiryo、Yu Gothic、MS Gothic、MS Mincho、HGGothicM、HGMinchoB、HGGothicE、HGMinchoE など使えるフォントは結構あるので、日本語で文字化けした際は、一度お試しください。

1つのグラフを表示

1つのグラフを描くのは非常に簡単です。

ここでは折れ線グラフを例にすると、figure⇒plot⇒show の順でメソッドを読めばグラフを表示することができます。

#データを準備
x=[1,2,3,4,5]
y=[10,20,30,40,50]

#グラフを描画
plt.figure()
plt.plot(x,y)
plt.show()

これだけだと少し寂しいので、背景色やフォント、線種などを指定してみましょう。

少しコードは増えますが、figreやグラフのサイズ(インチ指定)、背景色、折れ線の色や種類、マーカーサイズなどを指定することが出来ます。

import matplotlib.pyplot as plt
from matplotlib import rcParams

#データを準備
x=[1,2,3,4,5]
y=[10,20,30,40,50]

#漢字が使えるフォントを指定する。
rcParams['font.family'] = 'Meiryo'   # フォントを指定
rcParams['font.size'] = 12'          # フォントサイズを指定

#figureを作成(グラフのサイズ、背景色、縁の色、縁のサイズを指定)
plt.figure(figsize=(6,4),facecolor='cyan', linewidth=5, edgecolor='blue')

plt.gca().set_facecolor('lightblue') #グラフの背景色を設定
plt.title('X-Yの推移')               # グラフのタイトル
plt.xlabel('Y軸')                    # x軸のラベル
plt.ylabel('X軸')                    # y軸のラベル
plt.grid(True)                       # グリッドを表示する

# グラフを作成(線の色、線のスタイル、マーカーの形状を指定)
plt.plot(x,y,color='black',linestyle='dotted', marker='o')

# グラフを描画する
plt.show()

複数のグラフを表示

複数のグラフを表示する場合は、figure に対して add_subplot で表示エリアを追加する必要があります。

figureのどこに、どれくらいのサイズのものを置くかについては、add_subplotの引数で指定します。

この指定方法は少し特殊で、figure全体を行と列で分割した時に出来る格子状のエリアに対する番号で指定します。

例えば、add_subplot(3,2,4)と指定すると、figureを行3,列2で分割すると6個のエリアを作ることができますが、この中の4番目のエリアにグラフが表示されることになります。

言い換えると、本来は描画エリアの物理位置(X、Y座標、縦横サイズ)を指定すべきところですが、これだと直感的に分かり難いので、「〇行□列で分割した場合のn番目」という指定をすることで物理位置に読み替えてくれると解釈できます。

では、5つほど具体例を示して説明していきます。

add_subplotで指定する行、列は、物理的にfigureを分割しているのではなく、どこにグラフを置きたいかを指定するための方法に過ぎません。

従って個々のグラフの行、列の分割数はadd_subplotごとに異なっていても問題ありません。

但し、逆に縦と横の分割数を統一していない場合、指定の仕方によっては下図の通りグラフが重なってしまうため注意が必要です。

fig = plt.figure()
ax1 = fig.add_subplot(2,1,1,facecolor='yellow')
ax2 = fig.add_subplot(3,3,9,facecolor='blue')
ax3 = fig.add_subplot(4,4,3,facecolor='cyan')
ax4 = fig.add_subplot(3,2,4,facecolor='red')
ax5 = fig.add_subplot(2,2,3,facecolor='grey')
plt.show()

では、上記の考え方を元に実際に2行1列で分割した例を提示しておきます。

import matplotlib.pyplot as plt
from matplotlib import rcParams

month=[1,2,3,4,5,6,7,8,9,10,11,12]
price=[100,150,200,250,300,320,330,340,350,355,360,365]
count=[310,270,290,280,340,310,340,290,310,265,280,300]

rcParams['font.family'] = 'Meiryo'
rcParams['font.size'] = '8'

fig = plt.figure('売上金額・個数',facecolor='seashell', linewidth=5, edgecolor='gray')

#グラフ間の高さにおけるマージンを設定
fig.subplots_adjust(hspace=0.5)

ax1 = fig.add_subplot(2,1,1)
ax1.set_facecolor('beige')
ax1.grid(True)
ax1.plot(month,price,color='black',marker="o")
ax1.set_title('売上金額/月',size=8,color='red')
ax1.set_xlabel('月', size = 8,color='blue')
ax1.set_ylabel('売上金額', size = 8,color='blue')

ax2 = fig.add_subplot(2, 1, 2)
ax2.set_facecolor('darkred')
ax2.grid(True)
ax2.plot(month,count,color='white',linestyle='dotted',marker=“x")
ax2.set_title('販売個数/月',size=8,color='red')
ax2.set_xlabel('月', size = 8,color='blue')
ax2.set_ylabel('販売個数', size = 8,color='blue')

# 表示する
plt.show()

グラフにおける上下左右のマージン

グラフの内容によっては、軸のタイトルが外枠にはみ出す場合があります。

このような時は、subplots_adjust メソッドで上下左右のマージンを調整することが可能です。

マージンはX軸、Y軸それぞれ最小を0,最大を1とした場合の比率で指定します。

初期値は 次のようになっています。

leftrigthtopbottom
0.1250.90.90.1

マージンを指定しない場合と指定した場合のソースコードと描画イメージは次の通りです。

#マージン指定なし
plt.plot([1,2,3,4,5],[1,2,3,4,5])
plt.show()

#マージン指定有り
plt.plot([1,2,3,4,5],[1,2,3,4,5])
plt.subplots_adjust(left=0.3,right=0.82,top=0.82,bottom=0.3)
plt.show()

グラフ間のマージン

複数のグラフを描画する場合は、Axes間における縦方向と横方向のマージンを指定することも可能です。

初期値は次のようになります。

wspacehspace
0.1250.9

マージンを指定しない場合と指定した場合のソースコードと描画イメージは次の通りです。

#マージン無し
fig = plt.figure()
ax1=plt.subplot(2,2,1)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax2=plt.subplot(2,2,2)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax3=plt.subplot(2,2,3)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax4=plt.subplot(2,2,4)
plt.plot([1,2,3,4,5],[1,2,3,4,5])

plt.show()

#マージン有り
fig = plt.figure()
ax1=plt.subplot(2,2,1)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax2=plt.subplot(2,2,2)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax3=plt.subplot(2,2,3)
plt.plot([1,2,3,4,5],[1,2,3,4,5])
ax4=plt.subplot(2,2,4)
plt.plot([1,2,3,4,5],[1,2,3,4,5])

plt.subplots_adjust(hspace=0.8,wspace=0.6)

plt.show()

グラフのファイル保存

ファイルを保存する場合は pyplot 又は figureインスタンスの savefig メソッドを使います。

figure(ファイル名)

ファイル名の拡張子に応じたフォーマットでグラフ画像を保存してくれます。

使える拡張子は次の通りです。

 eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff

#pyplot のメソッドを使う場合
plt.plot([1,2,3,4,5],[100,150,200,250,300])
plt.savefig('d:/chart.jpg')


#figureインスタンスのメソッドを使う場合
fig=plt.figure()
plt.plot([1,2,3,4,5],[100,150,200,250,300])
plt.savefig('d:/chart.jpg')

代表的なグラフの使い方

グラフの数とバリエーションが多すぎるので、全てを紹介することは出来ません。

ここからは、良く使われるグラフに限定して詳しく見ていくことにしますので、必要に応じて公式サイトのGalleryページに記載されてい内容(サンプルソース)をご活用ください。

折れ線グラフ

折れ線グラフには plot メソッドが用意されており、描画したいデータを次のように引数で渡します。

  plt.plot(x,y)

第1引数と第2引数はグラフとして表示するデータで、リスト又はタプルで指定出来ます。

第2引数を省略した場合、第1引数の内容だけを使って線が描画されます。

# XとYの値をそれぞれリストで指定
plt.plot([1,2,3,4,5],[10,15,30,20,10])
plt.show()

# Yだけの値をタプルで指定
plt.plot((1,2,3,4,5))
plt.show()

第1引数が pandas のデータフレームや、NumPy の ndarray の場合は、各列が1つの折れ線データだと解釈され、全てが表示されます。

# pandasのDataFrameを使ってグラフ表示
df = pd.read_csv('d:\data.csv')
plt.plot(df)
plt.show()

# NumPyのndarrayを使ってグラフ表示
np.loadtxt('p:\data.csv',skiprows=1,delimiter=',')
plt.plot(df)
plt.show()

引数には線の色、種類、マーカーなど多くの種類がありますので、代表的なものを一覧にまとめました。

引数名内容
label凡例に表示するラベル。
color 又 は c 線の色('yellow'、'red' など)。
使用可能な色名は、こちらの公式サイトに記載。
但し、次の8色については1文字で指定が可能。
Blue⇒’b’、Green⇒'g'、Red⇒'r'、Cyan⇒'c'、Magenta⇒'m'、Yellow⇒'y' 、Black⇒'k'、White⇒'w'
linestyle 又は ls線の線種(dashesが指定されていると無視される)。
次の文字が指定可能。
'-'、 '--'、'-.'、 ':'、 'None'、' '、 ''、 'solid'、 'dashed'、'dashdot'、'dotted'
linewidth 又は lw線の太さ。
dashes線の実線部分と空白部分の長さをリストで指定。([0.2,0.5,0.2])。
markerマーカーの形状を半角1文字で指定(None を指定するとマーカーは非表示)
‘o’⇒丸、‘v’⇒下三角形、‘^’⇒上三角形、‘<‘⇒左三角形、‘>‘⇒右三角形、‘s’⇒四角形、‘p’⇒五角形、‘h’⇒六角形、‘*’⇒星型、‘+’⇒プラス、‘x’⇒バツ印
markersize 又は msマーカーのサイズ
markerfacecolor 又は mfcマーカーの色。
markeredgewidth 又は mewマーカーの縁の太さ。
markeredgecolor 又は mecマーカーの縁の色。
alpha線の透明度(0~1で指定)。
zorder線が重なる時の前面/背面の順番。値が大きいほど前面に描画される。

折れ線に限らず、matplotlib で使えるカラーマップは次の通りです。

出展元:「公式サイトのカラーサンプル一覧」

棒グラフ

棒グラフには bar メソッドが用意されており、描画したいデータを次のように引数で渡します。

  plt.bar(x,y)

第1引数はX軸の値であり、第2引数は棒グラフの高さの値を指定します。

X軸が文字列の場合は tick_label 引数にリスト形式で指定します。

x = [1,2,3,4,5]
y = [10,20,30,20,15]
label = ['餃子','焼飯','焼肉','牛丼','寿司'] 

plt.figure()
plt.bar(x,y,tick_label=label)
plt.show()

引数には次のようなものがあります。

引数名内容
width棒の太さ (初期値: 0.8)
bottom各棒の下側の余白。指定した値だけ宙に浮いて描画される。
後述の積み上げグラフで使用。
color 又は c棒の色。
edgecolor棒の枠線の色。
linewidth棒の枠線の太さ。
tick_labelX 軸のラベル
xerrX 軸方向のエラーバー (誤差範囲) の値(数値又はリストで指定)。
yerrY 軸方向のエラーバー (誤差範囲) の値(数値又はリストで指定)。
ecolorエラーバーの色(値または配列で指定)
capsizeエラーバーの傘のサイズ。
align棒の位置。(初期値:'edge')
’edge’⇒垂直方向の場合は左端, 水平方向の場合は下端、‘center’⇒中央が指定可能。
logTrue に設定すると対数目盛で出力。 (初期値: False)

積み上げグラフ

積み上げグラフの場合、専用のメソッドが存在しないため、bar メソッドを重ね合わせることで実現します。

ただ単純にbar メソッドを実行しても、上から上書きされていくだけなので、直前に書いた棒よりも高い棒を描くと、それしか表示されません。

つまり、積み上げグラフを作るためには、値の加算と表示順序を自分で制御しなければなりません。

具体的には、最初に合計の棒グラフを書き、そこから順に値を引きながら 棒グラフを描くという作業を繰り返す必要が生じます。

以下が4つの値を積み上げるグラフです。

x = [1,2,3,4,5]
y1 = np.array([10,20,30,20,15])
y2 = np.array([5,8,7,10,3])
y3 = np.array([10,17,10,15,14])
y4 = np.array([5,10,20,10,13])
label = ['餃子','焼飯','焼肉','牛丼','寿司'] 

plt.figure()

#積み上げバー
plt.bar(x,y1+y2+y3+y4,tick_label=label,color='lime',label='東京')
plt.bar(x,y1+y2+y3,tick_label=label,color='orange',label='大阪')
plt.bar(x,y1+y2,tick_label=label,color='violet',label='京都')
plt.bar(x,y1,tick_label=label,color='indigo',label='兵庫')

#凡例を表示
plt.legend(loc='upper right',shadow=True)

#グラフ表示
plt.show()

これで解決は出来たのですが、実はこの処理を楽にする引数がbar メソッドには備わっています。

それがbuttom 引数で、これを使うと棒の下側に指定した値だけ余白を作ることが出来ます。

つまり、積み上げる量をbuttomに指定してあげるだけで、先ほどと同じ効果が得られるのです。

これを利用ことで、次のように書くことが出来ます。

x = [1,2,3,4,5]
y1 = np.array([10,20,30,20,15])
y2 = np.array([5,8,7,10,3])
y3 = np.array([10,17,10,15,14])
y4 = np.array([5,10,20,10,13])
label = ['餃子','焼飯','焼肉','牛丼','寿司'] 

plt.figure()
plt.bar(x,y4,bottom=y1+y2+y3,tick_label=label,color='lime',label='東京')
plt.bar(x,y3,bottom=y1+y2,tick_label=label,color='orange',label='大阪')
plt.bar(x,y2,bottom=y1,tick_label=label,color='violet',label='京都')
plt.figure()
x = [1,2,3,4,5]
y1 = np.array([10,20,30,20,15])
y2 = np.array([5,8,7,10,3])
y3 = np.array([10,17,10,15,14])
y4 = np.array([5,10,20,10,13])
label = ['餃子','焼飯','焼肉','牛丼','寿司'] 

plt.bar(x,y1,tick_label=label,color='indigo',label='兵庫')
plt.bar(x,y2,bottom=y1,tick_label=label,color='violet',label='京都')
plt.bar(x,y3,bottom=y1+y2,tick_label=label,color='orange',label='大阪')
plt.bar(x,y4,bottom=y1+y2+y3,tick_label=label,color='lime',label='東京')

plt.legend(loc='upper right',shadow=True)

plt.show()

散布図

散布図は scatter メソッドを使います。

plt.scatter(x,y)

第一引数、第2引数にx、y座標をそれぞれ指定します。


x=[1,4,5,6,5,8,12,14,11,9,9,7,6,13,10,11,7,12,4,10,13]
y=[5,8,9,4,5,6,10,10,10,8,7,6,7,15,12,19,8,10,6,12,11]

plt.figure()
plt.scatter(x,y)
plt.show()

個々のマーカーは、カラーマップを使って色分けが可能です。

カラーマップを使う場合は、X、Yの各データに対応した色付け用の値を用意する必要があります。

例えば、「速度」「重さ」「温度」という3つの対応するデータがあり、Xを「速度」、Yを「重さ」で散布図を作成し、各マーカーの「温度」を色分けで表現したい場合などに使います。

x=[1,4,5,6,5,8,12,14,11,9,9,7,6,13,10,11,7,12,4,10,13]             #速度データ
y=[5,8,9,4,5,6,10,10,10,8,7,6,7,15,12,19,8,10,6,12,11]             #重さデータ
z=[11,14,15,16,15,18,12,14,11,19,19,17,16,13,10,11,17,12,14,11,15] #温度データ

plt.figure()
cm = plt.cm.get_cmap('RdYlBu')      #カラーマップの取得
sc = plt.scatter(x,y,c=z,cmap=cm)   #散布図の作成
plt.colorbar(sc)                    #カラーバーを表示

plt.show()

scatter メソッドで使える主な引数は次の通りです。

引数名内容
color 又は cマーカーの色。
カラーマップによりマーカーの色を変えたい場合は、データの個数だけ値を用意し、セットする。
markerマーカーの形 (初期値: ‘o’)
cmapカラーマップ。使えるカラーマップは「公式サイトのカラーマップ一覧」を参照。
cmap = plt.cm.get_cmap('RdYlBu')
vmin, vmaxscatterの機能で正規化を行う場合の最大、最小値。
指定しない場合、データの最大・最小値となる。
alphaマーカーの透明度。(0:透明~1:不透明の数値)
linewidthsマーカーの枠線の太さ。
edgecolorsマーカーの枠線の色。

公式サイトに掲載されているカラーマップは次の通りです。

出展元:「公式サイトのカラーマップ」

円グラフ

円グラフを描くには pie メソッドを使います。

  plt.pie(pi, labels=ラベル)

第1引数に円グラフにしたい値、labels 引数にラベルをリストで指定します。

label = ['餃子','焼飯','焼肉','牛丼','寿司'] 
pi =[500,200,350,220,110]

plt.figure()
plt.pie(pi, labels=label)
plt.show()

pie メソッドの主な引数は次の通りです。

引数名内容
explode指定した要素を中心から離す。
要素の個数だけ値を用意し、話したい要素のみ0以外を指定。
例:[0.1, 0, 0, 0, 0]
labels各要素のラベル。
colors各要素の色。要素の個数だけリストで指定。
autopct構成割合のパーセンテージ表示。 (初期値: None)
pctdistanceautopctを指定した際のパーセンテージの表示位置。
中心: (0.0) ~円周:(1.0) から指定。 (初期値: 0.6)
shadow影の表示指定。(初期値: False)
labeldistanceラベルの表示位置
中心: (0.0) ~円周:(1.0) から指定。 (初期値: 1.1)
startangle各要素の開始角度。 (初期値: None)
radius円の半径。 (初期値: 1)
counterclock各要素の並べ方の指定。
True⇒時計回り False⇒反時計回り。 (初期値: True)
wedgeprops各要素の枠線、色等の属性を指定。 (初期値: None)
辞書形式{'linewidth': 3, 'edgecolor':'white'}
textpropsテキストの色、太字等の属性を指定。 (初期値: None)
辞書形式{'color': 'red', 'weight': 'bold'})

まとめ

matplotlib は、C#で使えるフリーのグラフ描画ライブラリとは比べ物にならないくらい機能が豊富で、デザインも細部に渡って指定が可能です。

また、pandas の DataFrame や NumPy の ndarray に対応していて、引数に渡すだけで簡単に表示してくれるので、気軽に可視化するには非常に便利です。

機能が多すぎて全て一部しか紹介していませんが、基本的な考え方については分かっていただけたかと思います。

あとは、公式サイトのサンプルコードを参考に、活用して頂ければと思います。

matplotlib の最初の取っ掛かりとして、この記事がお役に立てれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次