matplotlibのpyplot APIをいろいろ試す

matplotlibのpyplot APIをいろいろ試す
目次

matplotlibはpythonでデータの可視化をするときに重宝しますが、ドキュメントがパッと見わかりにくいので、取っ掛かりが難しいです。

たまにデータの可視化をするのですが、 matplotlibの調べ物に時間がかかるときがあり「なんか時間がもったいないな」と感じていました。

今回はmatplotlibのドキュメントを読みつつ、matplotlibのpyplot APIをいろいろ試し、自分向けにまとめました。

実行環境

実行環境は以下になります。

  • mac OS (High Sierra 10.13)
  • Python 3.6.1
  • matplotlib 2.2.2
  • jupyter 1.0.0
  • numpy 1.14.5
  • pandas 0.23.1

また、今回作成したグラフは こちら にpushしてあります。

pyplotの思想を理解する

グラフ描画を始める前にpyplotの思想を理解しました。

いきなりSample Garallyから行くと凝ったグラフが出てきて理解が追いつかなくなるので注意が必要です。

探しにくいですが、公式の Usage GuideのGeneral Conceptsの項 にpyplotの概念の説明があるので一読しました。

プロットできるデータの種類

matplotlib.pyplot モジュールがデータのプロット(描画)を司るモジュールになります。

matplotlibのpyplotのページ に提供しているAPIの一覧記載があるのでそれを参考に試していきます。

ここでは、大きくわけて以下2種類を取り扱います。

  • グラフの種類を指定する関数(棒グラフや円グラフなど)
  • 渡されたデータに対して、特定の演算結果を描画する関数(スペクトル計算など)

棒グラフ(積み上げ棒グラフ):bar/barh/broken_barh

棒グラフ を描画します。 xerr yerr オプションを指定すると誤差の指定ができます。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x =  np.arange(5)
5y = (1, 2, 3, 4, 5)
6width = 0.3
7yerr = (.1, .08, .1, .0, .5)
8
9plt.bar(x, y, width, align='center', yerr=yerr, ecolor='r')

bar

bottom オプションで積み上げておきたい初期値を設定することで、 積み上げ棒グラフ を描画することもできます。

積み上げるグラフの複数の配列の要素数は同一である必要があり、bottom 指定を忘れると、2種類の棒グラフを重ねて描画してしまうので注意が必要です。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4x =  np.arange(5)
 5y = (1, 2, 3, 4, 5)
 6y2 = (2, 1, 3, 2, 1)
 7width = 0.3
 8yerr = (.1, .08, .1, .0, .5)
 9
10p1 = plt.bar(x, y, width, align='center', yerr=yerr, ecolor='r')
11p2 = plt.bar(x, y2, width, align='center', bottom=y, yerr=yerr, ecolor='r')
12
13plt.show()

bar2

y軸から横に伸びる棒グラフbarh 関数を使います。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x =  np.arange(5)
5y = (1, 2, 3, 4, 5)
6width = 0.3
7xerr = (.1, .08, .1, .0, .5)
8
9plt.barh(x, y, width, align='center', xerr=xerr, ecolor='r')

barh

broken_barh 関数では、 軸に足をつけない棒グラフ を描画することができます。 実際には指定領域を矩形描画することになります。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x =  [(1.5, 0.5)]
5y = (.5, 2.0)
6
7plt.broken_barh(x, y)
8plt.xlim(0)
9plt.ylim(0)

broken_barh

ヒストグラム:hist/hist2d

ヒストグラム を表示します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4np.random.seed(0)
5
6mu, sigma = 100, 15
7x = mu + sigma * np.random.randn(100)
8
9plt.hist(x, 50, density=True, alpha=0.75)

hist

2次元のヒストグラム を描画するには、 hist2d 関数を使用します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4np.random.seed(0)
5
6x = np.random.randn(100000)
7y = np.random.randn(100000) + 5
8
9plt.hist2d(x, y, bins=40)

hist2d

円グラフ:pie

円グラフ を描画します。 autopct (円グラフ上に値を表示する)オプションのように、グラフを修飾する多くのオプションが備わっています。

1from matplotlib import pyplot as plt
2from matplotlib.gridspec import GridSpec
3
4labels = 'A', 'B', 'C', 'D'
5fracs = [15, 30, 45, 10]
6
7plt.pie(fracs, labels=labels, autopct='%1.1f%%')
8plt.show()

pie

散布図:scatter

散布図 を描画します。 マーカーの大きさはオプション指定で変更しています。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4N = 50
 5x = np.random.rand(N)
 6y = np.random.rand(N)
 7
 8colors = np.random.rand(N)
 9area = np.pi * (15 * np.random.rand(N))**2
10
11plt.scatter(x, y, s=area, c=colors, alpha=0.5)
12plt.show()

scatter

折れ線グラフ(積み上げ折れ線グラフ):plot/stackplot/plot_date

折り線グラフplot で描画できます。

1from matplotlib import pyplot as plt
2import numpy as np
3
4np.random.seed(0)
5
6x = np.random.rand(100)
7
8plt.plot(x)
9plt.show()

plot

積み上げの折れ線グラフ を描画するには stackplot 関数を使います。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4x = [1, 2, 3, 4, 5]
 5y1 = [1, 1, 2, 3, 5]
 6y2 = [0, 4, 2, 6, 8]
 7y3 = [1, 3, 5, 7, 9]
 8
 9plt.stackplot(x, y1, y2, y3, labels=labels)
10plt.show()

stackplot

また、 x軸が日付データの場合の折れ線グラフ には plot_date 関数を用いることが可能です。

 1import matplotlib.pyplot as plt
 2from matplotlib.dates import (DateFormatter, drange)
 3import numpy as np
 4import datetime
 5
 6np.random.seed(0)
 7
 8formatter = DateFormatter('%Y/%m/%d/')
 9date1 = datetime.date(1970, 1, 1)
10date2 = datetime.date(2018, 4, 12)
11delta = datetime.timedelta(days=100)
12
13dates = drange(date1, date2, delta)
14s = np.random.rand(len(dates))
15
16plt.plot_date(dates, s)
17plt.show()

plot_date

箱ひげ図:boxplot

箱ひげ図 (最小値、第1四分位点、中央値、第3四分位点、最大値)を描画します。

1import numpy as np
2from matplotlib import pyplot as plt
3import random
4
5a = np.array([1, 3, 0.25, 0.44, 5.88])
6plt.boxplot(a)

boxplot

バイオリン図:violinplot

バイオリン図 (箱ひげ図に確率密度表示を加えたもの)を描画します。

 1import pandas as pd
 2import numpy as  np
 3from matplotlib import pyplot as plt
 4
 5fs = 10
 6pos = [1, 2, 4, 5, 7, 8]
 7data = [np.random.normal(0, std, size=100) for std in pos]
 8
 9plt.violinplot(data, pos, points=20, widths=0.3, showmeans=True, showextrema=True, showmedians=True)
10plt.show()

violinplot

等高線・水平曲線:contour/contourf

等高線 (同じ高さの値の集まり)を描画します。 contour 単体だと値がわかりにくいので、 clabelcolorbar などで情報を付与すると良いです。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4delta = 0.025
 5x = np.arange(-4.0, 3.0, delta)
 6y = np.arange(-2.0, 2.0, delta)
 7X, Y = np.meshgrid(x, y)
 8Z1 = np.exp(-X**2 - Y**2)
 9Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
10Z = (Z1 - Z2) * 2
11
12plt.figure()
13plt.contour(X, Y, Z)

contour

等高線の塗りつぶし には contourf を使います。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4delta = 0.025
 5x = np.arange(-4.0, 3.0, delta)
 6y = np.arange(-2.0, 2.0, delta)
 7X, Y = np.meshgrid(x, y)
 8Z1 = np.exp(-X**2 - Y**2)
 9Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
10Z = (Z1 - Z2) * 2
11
12plt.figure()
13plt.contourf(X, Y, Z)

contourf

非構造三次元データ:tricontour/tricontourf

非構造三次元データ を扱う場合には tricontourtricontourf を使います。

 1import matplotlib.pyplot as plt
 2import matplotlib.tri as tri
 3import numpy as np
 4
 5n_angles = 48
 6n_radii = 8
 7min_radius = 0.25
 8radii = np.linspace(min_radius, 0.95, n_radii)
 9
10angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False)
11angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
12angles[:, 1::2] += np.pi / n_angles
13
14x = (radii * np.cos(angles)).flatten()
15y = (radii * np.sin(angles)).flatten()
16z = (np.cos(radii) * np.cos(3 * angles)).flatten()
17
18triang = tri.Triangulation(x, y)
19
20plt.gca().set_aspect('equal')
21plt.tricontourf(triang, z)
22plt.colorbar()
23plt.tricontour(triang, z, colors='k')

tricontour

極座標:polar

極座標 の円状グラフを描画します。

1from matplotlib import pyplot as plt
2import numpy as np
3
4r = np.arange(0, 2, 0.01)
5theta = 2 * np.pi * r
6
7plt.polar(theta, r)
8plt.show()

polar

対数:loglog/semilogx/semilogy

対数を描画します。 両対数 の場合には loglog 関数を使います。

1from matplotlib import pyplot as plt
2import numpy as np
3
4t = np.arange(0.01, 20.0, 0.01)
5plt.loglog(t, 20 * np.exp( -t / 10.0), basex=2)
6plt.grid(True)
7plt.title('loglog base 2 on x')
8plt.show()

loglog

x軸を10を底とする対数スケールでの片対数 を描画する場合には semilogx を使用します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4t = np.arange(0.01, 20.0, 0.01)
5
6plt.semilogx(t, np.sin(2*np.pi*t))
7plt.grid(True)

semilogx

y軸を10を底とする対数スケールでの片対数 を描画する場合には semilogy を使用します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4t = np.arange(0.01, 20.0, 0.01)
5
6plt.semilogy(t, np.exp(-t/5.0))
7plt.grid(True)

semilogy

行列:matshow

行列データ を描画します。

1from matplotlib import pyplot as plt
2import numpy as np
3
4np.random.seed(0)
5
6mat = np.random.rand(10,10)
7plt.matshow(mat)
8
9plt.show()

matshow

スパース行列:spy

スパース行列(疎行列) を描画します。

1from matplotlib import pyplot as plt
2import numpy as np
3
4x = np.random.randn(20, 20)
5x[5] = 0.
6x[:, 12] = 0.
7
8plt.spy(x, markersize=3)

spy

コヒーレンス:cohere

コヒーレンス(波の可干渉性) を描画することができます。

1import numpy as np
2import matplotlib.pyplot as plt
3
4n = 1024
5x = np.random.randn(n)
6y = np.random.randn(n)
7
8plt.cohere(x, y, NFFT=128)
9plt.figure()

cohere

離散データ:stem

x軸から伸びるシーケンスとしてyの値 を描画したい場合に使います。

1from matplotlib import pyplot as plt
2import numpy as np
3
4x = np.linspace(0.1, 2 * np.pi, 10)
5plt.stem(x, np.cos(x), '-.')
6
7plt.show()

stem

ステップ応答:step

ステップ応答 を描画します。コンピュータ信号のような離散値とかを扱うときに使います。

 1import numpy as np
 2from numpy import ma
 3import matplotlib.pyplot as plt
 4
 5x = np.arange(1, 7, 0.4)
 6y = np.sin(x).copy() + 2.5
 7
 8plt.step(x, y)
 9plt.scatter(x, y) #データを表す座標が見やすいようにしています
10plt.show()

step

自己相関・相互相関:acorr/xcorr

acorr 関数で 自己相関 を描画することができます。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x = np.random.normal(0, 10, 50)
5plt.acorr(x)

acorr

また、相互相関 を描画は xcorr になります。

1import matplotlib.pyplot as plt
2import numpy as np
3
4np.random.seed(0)
5
6x, y = np.random.randn(2, 100)
7plt.xcorr(x, y, usevlines=True, maxlags=50, normed=True, lw=2)
8
9plt.show()

xcorr

複数イベントデータ:eventplot

複数のイベントデータ を並行して描画する。公式から引用すると、以下のようなユースケースがあるらしいです。

This type of plot is commonly used in neuroscience for representing neural events, where it is usually called a spike raster, dot raster, or raster plot.

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4np.random.seed(1)
 5
 6data = np.random.random([6, 50])
 7lineoffsets = np.array([-15, -3, 1, 1.5, 6, 10])
 8linelengths = [10, 2, 1, 1, 3, 1.5]
 9
10plt.figure()
11plt.eventplot(data, lineoffsets=lineoffsets,
12              linelengths=linelengths)

eventplot

六角形で描画:hexbin

hex でデータを描画します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4x = np.arange(1, 10, 1)
5y = np.arange(1, 10, 1)
6
7plt.hexbin(x, y, gridsize=10)

hexbin

疑似カラー描画:pcolor/pcolormesh/tripcolor

2次元配列のデータを 擬似カラー で描画します。

 1import matplotlib.pyplot as plt
 2import numpy as np
 3
 4dx, dy = 0.15, 0.05
 5
 6y, x = np.mgrid[slice(-3, 3 + dy, dy),
 7                slice(-3, 3 + dx, dx)]
 8z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
 9z = z[:-1, :-1]
10z_min, z_max = -np.abs(z).max(), np.abs(z).max()
11
12plt.pcolor(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)

pcolor

メッシュデータを高速に描画したい 場合には pcolormesh 関数を使うと良いそうです。

 1import matplotlib.pyplot as plt
 2import numpy as np
 3
 4dx, dy = 0.15, 0.05
 5
 6y, x = np.mgrid[slice(-3, 3 + dy, dy),
 7                slice(-3, 3 + dx, dx)]
 8z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
 9z = z[:-1, :-1]
10z_min, z_max = -np.abs(z).max(), np.abs(z).max()
11
12plt.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)

pcolormesh

tricontour に対する疑似カラー描画 には tripcolor 関数を使います。

 1import matplotlib.pyplot as plt
 2import matplotlib.tri as tri
 3import numpy as np
 4
 5n_angles = 48
 6n_radii = 8
 7min_radius = 0.25
 8radii = np.linspace(min_radius, 0.95, n_radii)
 9
10angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False)
11angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
12angles[:, 1::2] += np.pi / n_angles
13
14x = (radii * np.cos(angles)).flatten()
15y = (radii * np.sin(angles)).flatten()
16z = (np.cos(radii) * np.cos(3 * angles)).flatten()
17
18triang = tri.Triangulation(x, y)
19
20plt.gca().set_aspect('equal')
21plt.tricontourf(triang, z)
22plt.colorbar()
23plt.tripcolor(triang, z, shading='flat')

tripcolor

スペクトラム:magnitude_spectrum/phase_spectrum/angle_spectrum/specgram

信号の強さを表す 振幅スペクトラムmagnitude_spectrum で描画します。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4np.random.seed(0)
 5
 6dt = 0.01
 7Fs = 1/dt
 8t = np.arange(0, 10, dt)
 9nse = np.random.randn(len(t))
10r = np.exp(-t/0.05)
11cnse = np.convolve(nse, r)*dt
12cnse = cnse[:len(t)]
13
14s = 0.1*np.sin(2*np.pi*t) + cnse
15
16plt.magnitude_spectrum(s, Fs=Fs)
17plt.show()

magnitude_spectrum

位相スペクトラムphase_spectrum で描画します。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4np.random.seed(0)
 5
 6dt = 0.01
 7Fs = 1/dt
 8t = np.arange(0, 10, dt)
 9nse = np.random.randn(len(t))
10r = np.exp(-t/0.05)
11
12cnse = np.convolve(nse, r)*dt
13cnse = cnse[:len(t)]
14s = 0.1*np.sin(2*np.pi*t) + cnse
15
16plt.phase_spectrum(s, Fs=Fs)
17plt.show()

phase_spectrum

角度スペクトラムangle_spectrum で描画します。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x = np.random.normal(0, 10, 50)
5plt.angle_spectrum(x)

angle_spectrum

スペクトログラムspecgram になります。

 1import matplotlib.pyplot as plt
 2import numpy as np
 3
 4np.random.seed(0)
 5
 6dt = 0.0005
 7t = np.arange(0.0, 20.0, dt)
 8s1 = np.sin(2 * np.pi * 100 * t)
 9s2 = 2 * np.sin(2 * np.pi * 400 * t)
10
11mask = np.where(np.logical_and(t > 10, t < 12), 1.0, 0.0)
12s2 = s2 * mask
13
14nse = 0.01 * np.random.random(size=len(t))
15
16x = s1 + s2 + nse
17NFFT = 1024
18Fs = int(1.0 / dt)
19
20plt.specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900)
21plt.show()

specgram

スペクトル密度:psd/csd

パワースペクトル密度psd で描画します。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3from matplotlib import mlab as mlab
 4
 5np.random.seed(0)
 6
 7dt = 0.01
 8t = np.arange(0, 10, dt)
 9nse = np.random.randn(len(t))
10r = np.exp(-t / 0.05)
11
12cnse = np.convolve(nse, r) * dt
13cnse = cnse[:len(t)]
14s = 0.1 * np.sin(2 * np.pi * t) + cnse
15
16plt.psd(s, 512, 1 / dt)
17plt.show()

psd

クロススペクトル密度csd で描画します。

 1from scipy import signal
 2from matplotlib import pyplot as plt
 3
 4fs = 10e3
 5N = 1e5
 6amp = 20
 7freq = 1234.0
 8noise_power = 0.001 * fs / 2
 9time = np.arange(N) / fs
10b, a = signal.butter(2, 0.25, 'low')
11x = np.random.normal(scale=np.sqrt(noise_power), size=time.shape)
12y = signal.lfilter(b, a, x)
13x += amp*np.sin(2*np.pi*freq*time)
14y += np.random.normal(scale=0.1*np.sqrt(noise_power), size=time.shape)
15
16plt.figure()
17plt.csd(x, y)

csd

ベクトル:quiver/quiverkey

ベクトル を描画します。また、 quiverkey 関数を使うことで、ベクトルのキー も描画することができます。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4X, Y = np.meshgrid(np.arange(0, 2 * np.pi, .2), np.arange(0, 2 * np.pi, .2))
 5U = np.cos(X)
 6V = np.sin(Y)
 7
 8Q = plt.quiver(X, Y, U, V, units='width')
 9plt.quiverkey(Q, 0.5, 0.9, 2, r'$2 \frac{m}{s}$', labelpos='E', coordinates='figure')
10plt.show()

quiver

流線グラフ:streamplot

流線 を描画します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4Y, X = np.mgrid[-3:3:100j, -3:3:100j]
5U = -1 - X**2 + Y
6V = 1 + X - Y**2
7speed = np.sqrt(U*U + V*V)
8
9plt.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn)

streamplot

グラフに付加情報を加える

グラフに付加情報を加えることで、プロットされたデータの理解を補助することができます。 以下ではグラフに付加情報を加える関数を調べてみました。

グラフのタイトル:title/suptitle

グラフに タイトルをつける には title 関数を使います。 複数グラフにタイトルをつける には suptitle 関数を使います。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4def f(t):
 5    return np.cos(2*np.pi*t)
 6
 7t1 = np.arange(0.0, 5.0, 0.1)
 8t2 = np.arange(0.0, 2.0, 0.01)
 9
10plt.subplot(121)
11plt.plot(t1, f(t1), '-')
12plt.title('subplot 1')
13plt.suptitle('Suptitle', fontsize=16)
14
15
16plt.subplot(122)
17plt.plot(t2, np.cos(2*np.pi*t2), '--')
18plt.title('subplot 2')
19
20plt.show()

title

凡例の追加:legend/colorbar

グラフデータの凡例 を追加します。

1from matplotlib import pyplot as plt
2import numpy as np
3
4x_data = (1, 2, 3)
5y_data = (.5, 1.5 , .8)
6
7plt.bar(x_data, y_data)
8plt.legend(['dataA'])

legend

等高線(contour)に対する、 色が表す値の凡例colorbar 関数で表示します。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4delta = 0.025
 5x = np.arange(-4.0, 3.0, delta)
 6y = np.arange(-2.0, 2.0, delta)
 7X, Y = np.meshgrid(x, y)
 8Z1 = np.exp(-X**2 - Y**2)
 9Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
10Z = (Z1 - Z2) * 2
11
12plt.figure()
13plt.contourf(X, Y, Z)
14plt.colorbar()

colorbar

ラベルの表示:xlabel/ylabel/clabel

グラフの軸に ラベル を表示します。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3import matplotlib
 4
 5np.random.seed(0)
 6
 7x = np.arange(0.0, 50.0, 2.0)
 8y = x ** 1.3 + np.random.rand(*x.shape) * 30.0
 9s = np.random.rand(*x.shape) * 800 + 500
10
11plt.scatter(x, y, s, c="g", alpha=0.5, label="Luck")
12plt.xlabel("Label X")
13plt.ylabel("Label Y")
14plt.show()

xlabel

等高線(contour)に対しては clabel 関数で 色が表す値のラベル を表示します。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4delta = 0.025
 5x = np.arange(-4.0, 3.0, delta)
 6y = np.arange(-2.0, 2.0, delta)
 7X, Y = np.meshgrid(x, y)
 8Z1 = np.exp(-X**2 - Y**2)
 9Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
10Z = (Z1 - Z2) * 2
11
12plt.figure()
13CS = plt.contour(X, Y, Z)
14plt.clabel(CS, inline=1, fontsize=10)

clabel

軸の描画範囲を制限:xlim/ylim

デフォルトだとデータの範囲に合わせてx軸/y軸の範囲が決まりますが、 軸の値の範囲 を変更できます。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4x = np.linspace(-np.pi, np.pi, 100)
 5
 6plt.xlim(-2, 2)
 7plt.ylim(-0.75, 0.75)
 8
 9plt.plot(x, np.sin(x),label="y = sinx")
10plt.show()

xlim

軸のスケールの変更:xscale/yscale

軸のスケール を変更します。linear log logit symlog を指定でき、対数をとった描画等ができます。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x = np.linspace(-np.pi, np.pi, 100)
5
6plt.xscale('symlog')
7
8plt.plot(x, np.sin(x))
9plt.show()

xscale

1import numpy as np
2from matplotlib import pyplot as plt
3
4x = np.linspace(-np.pi, np.pi, 100)
5
6plt.yscale('log')
7
8plt.plot(x, np.sin(x))
9plt.show()

yscale

目盛りの変更:xticks/yticks

目盛り をカスタマイズするには xticks yticks 関数を使います。

1from matplotlib import pyplot as plt
2import numpy as np
3
4x = np.arange(4)
5y = [10, 20, 30, 40]
6
7plt.bar(x, y)
8plt.xticks(x, ('A', 'B', 'C', 'D'))
9plt.show()

xticks

1from matplotlib import pyplot as plt
2import numpy as np
3
4x = np.arange(4)
5y = [10, 20, 30, 40]
6
7plt.bar(x, y)
8plt.yticks(y, ('10', '20', '30', '40'))
9plt.show()

yticks

表(テーブル)の表示:table

描画データの 表(テーブル) を表示します。 パッと見た感じ、表単体で描画するのはできなそうでした。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4data = [[ 66386, 174296,  75131, 577908,  32015],
 5        [ 58230, 381139,  78045,  99308, 160454],
 6        [ 89135,  80552, 152558, 497981, 603535],
 7        [ 78415,  81858, 150656, 193263,  69638],
 8        [139361, 331509, 343164, 781380,  52269]]
 9columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
10rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]
11
12plt.table(cellText=data,
13                      rowLabels=rows,
14                      rowColours=colors,
15                      colLabels=columns,
16                      loc='bottom')
17
18plt.show()

table

軸に対する描画データの追加:twinx/twiny

同一の軸に対して別のデータを描画します。 x軸はそのままに、別のyの値を描画する には twinx 関数を使います。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4fig, ax1 = plt.subplots()
 5t = np.arange(0.01, 10.0, 0.01)
 6s1 = np.exp(t)
 7ax1.plot(t, s1, 'b-')
 8ax1.set_xlabel('time (s)')
 9ax1.set_ylabel('exp', color='b')
10ax1.tick_params('y', colors='b')
11
12ax2 = ax1.twinx()
13s2 = np.sin(2 * np.pi * t)
14ax2.plot(t, s2, 'r.')
15ax2.set_ylabel('sin', color='r')
16ax2.tick_params('y', colors='r')
17
18plt.show()

twinx

y軸はそのままに、別のxの値を描画する には twiny 関数を使います。

 1import numpy as np
 2from matplotlib import pyplot as plt
 3
 4fig, ax1 = plt.subplots()
 5t = np.arange(0.01, 10.0, 0.01)
 6s1 = np.exp(t)
 7ax1.plot(t, s1, 'b-')
 8ax1.set_xlabel('time (s)')
 9ax1.set_ylabel('exp', color='b')
10ax1.tick_params('y', colors='b')
11
12ax2 = ax1.twiny()
13t2 = np.arange(10.01, 20.0, 0.01)
14s2 = np.exp(t2)
15ax2.plot(t2, s2, 'r.')
16ax2.set_xlabel('sin', color='r')
17ax2.tick_params('y', colors='r')
18
19plt.show()

twiny

注釈の追加:annotate

注釈を追加 します。特定のデータポイントを指し示すときに使います。

xycoords オプションによって、xyxytext の振る舞いが変わる点に注意が必要です。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4fig = plt.figure()
 5ax = fig.add_subplot(111)
 6
 7t = np.arange(0.0, 5.0, 0.01)
 8s = np.cos(2*np.pi*t)
 9line, = ax.plot(t, s, lw=2)
10
11# xycoordsがデフォルトの'data'なので、
12# 座標(4, 1)のデータに対して座標(3, 1.5)にテキストを表示して
13# 矢印で線を引っ張る
14ax.annotate('max', xy=(4, 1), xytext=(3, 1.5),
15            arrowprops=dict(facecolor='black', shrink=0.05),
16            )
17
18ax.set_ylim(-2,2)
19plt.show()

annotate

矢印(直線)の追加:arrow

矢印を描画 します。 head_width head_length オプションを記入しないとただの直線として描画されます。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4fig = plt.figure()
 5ax = fig.add_subplot(111)
 6
 7#head_widthとhead_lengthを入れないと矢印にならない
 8ax.arrow(x=0.5, y=0.5, dx=1.0, dy=1.0, ls='--', head_width=0.1, head_length=0.1)
 9
10ax.set_xlim(0.25, 1.75)
11ax.set_ylim(0.25, 1.75)
12plt.show()

arrow

平行・垂直の線を引く:axhline/axvline/hlines/vlines

axhline 関数は x軸に対する平行線 を引きます。 また、 xmin xmax オプションで、直線を引く区間を指定できるのが便利です。

1import numpy as np
2import matplotlib.pyplot as plt
3
4fig = plt.figure()
5ax = fig.add_subplot(111)
6
7plt.axhline(y=.5, xmin=0.25, xmax=0.75)
8plt.show()

axhline

同様に x軸に対する平行線を複数引く には hlines 関数が便利です。 指定された xminxmax は複数の線全てに適用されます。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4np.random.seed(0)
 5
 6xmin = 1
 7xmax =  10
 8
 9plt.hlines([-1, 1], xmin, xmax)
10plt.show()

hlines

axvline関数は x軸に対する垂直の線 を引くことが出来ます。オプションの概念は axhline と同様です。

1import numpy as np
2import matplotlib.pyplot as plt
3
4fig = plt.figure()
5ax = fig.add_subplot(111)
6
7plt.axvline(x=.5, ymin=0.25, ymax=0.75, color='r', linewidth=4)
8plt.show()

axvline

同様に x軸に対する垂直の線を複数引く には vlines 関数が便利です。 指定された yminxmax は複数の線全てに適用されます。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4np.random.seed(0)
 5
 6ymin = 1
 7ymax =  10
 8
 9plt.vlines([-1, 1], ymin, ymax)
10plt.show()

vlines

矩形の描画:axhspan/axvspan

axhspan 関数では x軸と平行の矩形(四角形) を描画することができます。 y軸の範囲を表現したいときに使います。 xmin xmax ymin ymax オプションを指定した場合は矩形を描画するという意味では axvspan と変わりません。

1import numpy as np
2import matplotlib.pyplot as plt
3
4fig = plt.figure()
5ax = fig.add_subplot(111)
6
7# yが1.25〜1.55までを一律で塗りつぶし
8plt.axhspan(1.25, 1.55, facecolor='g', alpha=0.5)
9plt.show()

axhspan

axvspan 関数では y軸と平行の矩形(四角形) を描画することができます。 x軸の範囲を表現したいときに使います。 xmin xmax ymin ymax オプションを指定した場合は矩形を描画するという意味では axhspan と変わりません。

1import numpy as np
2import matplotlib.pyplot as plt
3
4fig = plt.figure()
5ax = fig.add_subplot(111)
6
7plt.axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
8plt.show()

axvspan

誤差の表示:errorbar

データの誤差 を棒で表します。 uplims lolims オプションで、上下のどちらの誤差か指定することもできます。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4fig = plt.figure(0)
 5x = np.arange(10.0)
 6y = np.sin(np.arange(10.0) / 20.0)
 7
 8plt.errorbar(x, y, yerr=0.1)
 9
10y = np.sin(np.arange(10.0) / 20.0) + 1
11plt.errorbar(x, y, yerr=0.1, uplims=True)
12
13y = np.sin(np.arange(10.0) / 20.0) + 2
14plt.errorbar(x, y, yerr=0.1, lolims=True)

errorbar

テキストの追加:text/figtext

text 関数はグラフ上に テキストを追加 します。 オプション指定で修飾することもできます。

描画位置の指定は座標系に対して行います。

 1from matplotlib import pyplot as plt
 2
 3plt.text(0.6, 0.5, "hogehoge", size=20, rotation=20.,
 4         ha="center", va="center",
 5         bbox=dict(boxstyle="square",
 6                   ec=(1., 0.5, 0.5),
 7                   fc=(1., 0.8, 0.8),
 8                   )
 9         )
10
11plt.text(0.2, 0.5, "fugafuga", size=20, rotation=20.,
12         ha="center", va="center"
13         )
14
15plt.show()

text

同様に テキストを追加する 関数で figtext が存在します。

描画位置の指定は図に対する相対位置であることに注意が必要です。(座標に依存しません)

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4fig = plt.figure(0)
 5x = np.arange(10.0)
 6y = np.sin(np.arange(10.0) / 20.0)
 7
 8plt.errorbar(x, y)
 9# x軸方向の中央(0.5)
10# y軸方向の1/4(0.25)の場所に
11# 文字「x」を埋め込む
12plt.figtext(0.5, 0.25, '$x$')

figtext

範囲の塗りつぶし:fill/fill_between/fill_betweenx

グラフ上の 範囲を色で塗りつぶして 描画します。 fill ではy=0との間の色が塗りつぶされます。

1import numpy as np
2import matplotlib.pyplot as plt
3
4x = np.arange(0.0, 2, 0.01)
5y = np.sin(2*np.pi*x)
6
7#0〜y or y〜0の間を塗りつぶす
8plt.fill(x, y)

fill

塗りつぶし範囲のyを指定する には fill_between 関数を使用します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4x = np.arange(0.0, 2, 0.01)
5y1 = np.sin(2*np.pi*x)
6y2 = 0.5
7
8#y1〜y2の間を塗りつぶす
9plt.fill_between(x, y1, y2)

fill_between

x軸に対して塗りつぶし範囲を指定する には fill_betweenx 関数を使います。

1import numpy as np
2import matplotlib.pyplot as plt
3
4y = np.arange(0.0, 2, 0.01)
5x1 = np.sin(2*np.pi*x)
6x2 = 0.5
7
8#x1〜x2の範囲を塗りつぶす
9plt.fill_betweenx(y, x1, x2)

fill_betweenx

風向きの追加:barbs

天気図で使う風向きとその強さ を表す記号を描画します。

1import numpy as np
2import matplotlib.pyplot as plt
3
4x =  (1, 2, 3, 4, 5)
5y = (1, 2, 3, 4, 5)
6u = (10,20,-30,40,-50)
7v = (10,20,30,40,50)
8
9plt.barbs(x, y, u, v)

barbs

グラフのレイアウトを修正する

図を見やすくするために、グラフのレイアウトを微調整します。

グラフの位置変更:axes

グラフの位置を変更 します。 複数のグラフを重ね合わせる ときなどに使用します。

1import matplotlib.pyplot as plt
2import numpy as np
3
4x = np.random.normal(0, 10, 50)
5plt.acorr(x)
6
7# 引数は図を描画する位置の [left, bottom, width, height]を表す
8plt.axes([.65, .6, .2, .2], facecolor='k')
9plt.angle_spectrum(x)

axes

外枠の表示/非表示:box

グラフの 枠の表示/非表示 を設定します。デフォルトではTrue(表示する)です。

1import numpy as np
2from matplotlib import pyplot as plt
3
4x =  np.arange(5)
5y = (1, 2, 3, 4, 5)
6width = 0.3
7
8plt.barh(x, y, width, align='center')
9plt.box(False)

box

グリッド(格子)の表示:grid/rgrids/thetagrids/triplot

グラフ内に グリッドを表示 します。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4np.random.seed(0)
 5
 6mu, sigma = 100, 15
 7x = mu + sigma * np.random.randn(100)
 8
 9plt.hist(x, 50, density=True, alpha=0.75)
10plt.grid(linestyle='-', linewidth=1)

grid

極座標グラフ(polar)にグリッドを表示 するには rgrids 関数を使います。

1from matplotlib import pyplot as plt
2import numpy as np
3
4plt.polar()
5plt.rgrids((0.25, 0.5, 1.0))
6plt.show()

rgrids

rgrids の代わりに thetagrids 関数で、グリッドとラベルを一緒に設定 することも可能です。

1from matplotlib import pyplot as plt
2import numpy as np
3
4plt.polar()
5plt.thetagrids(range(45,360,90), ('NE', 'NW', 'SW','SE'))
6plt.show()

thetagrids

非構造三次元データ (tricontour) にグリッドを表示 するには triplot 関数を使います。

 1import matplotlib.pyplot as plt
 2import matplotlib.tri as mtri
 3import numpy as np
 4
 5x = np.asarray([0, 1, 2, 3, 0.5, 1.5, 2.5, 1, 2, 1.5])
 6y = np.asarray([0, 0, 0, 0, 1.0, 1.0, 1.0, 2, 2, 3.0])
 7triangles = [[0, 1, 4], [1, 2, 5], [2, 3, 6], [1, 5, 4], [2, 6, 5], [4, 5, 7],
 8             [5, 6, 8], [5, 8, 7], [7, 8, 9]]
 9triang = mtri.Triangulation(x, y, triangles)
10z = np.cos(1.5 * x) * np.cos(1.5 * y)
11
12plt.tricontourf(triang, z)
13plt.triplot(triang, 'ko-')
14plt.show()

triplot

目盛りの分割数を変更:locator_params

指定軸の 目盛りの分割数 を指定できます。 nbins オプションは2の乗数で指定するといい感じにスケールしてくれます。 指定された数字通りに分割してくれるときとそうでないときがあり。

 1import numpy as np
 2import matplotlib.pyplot as plt
 3
 4np.random.seed(0)
 5
 6mu, sigma = 100, 15
 7x = mu + sigma * np.random.randn(100)
 8
 9plt.hist(x, 50, density=True, alpha=0.75)
10# x軸を8分割
11plt.locator_params(axis='x', nbins=8)
12plt.show()

locator_params

マージンの追加:margins/subplots_adjust

図内の点に対してマージンをとって、データを見やすい位置に調整します。

1import matplotlib.pyplot as plt
2
3x = [1, 2, 3, 4]
4y = [1, 4, 9, 6]
5
6plt.plot(x, y, 'o')
7plt.margins(0.3)
8plt.show()

margins

subplots を使った複数のグラフ描画の場合には subplots_adjust が使えます。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4np.random.seed(0)
 5
 6plt.subplot(211)
 7plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
 8plt.subplot(212)
 9plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
10
11plt.subplots_adjust(bottom=0.3, right=0.8, top=0.9)
12plt.show()

subplots_adjust

レイアウトの自動調整:tight_layout

複数グラフ間のレイアウト設定から、自動で調節してくれます。

 1from matplotlib import pyplot as plt
 2import itertools
 3
 4fontsizes = itertools.cycle([8, 16, 24, 32])
 5
 6def example_plot(ax):
 7    ax.plot([1, 2])
 8    ax.set_xlabel('x-label', fontsize=next(fontsizes))
 9    ax.set_ylabel('y-label', fontsize=next(fontsizes))
10    ax.set_title('Title', fontsize=next(fontsizes))
11
12fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
13example_plot(ax1)
14example_plot(ax2)
15example_plot(ax3)
16example_plot(ax4)
17plt.tight_layout()

tight_layout

複数グラフの描画:subplots

複数のグラフを描画する場合には、 subplots を使います。 返却された axes 配列の要素にアクセスして、データをプロットする関数を実行することで描画が可能です。

 1from matplotlib import pyplot as plt
 2import numpy as np
 3
 4x = np.linspace(0, 2*np.pi, 400)
 5y = np.sin(x**2)
 6
 7fig, axes = plt.subplots(2, 1)
 8axes[0].plot(x, y)
 9axes[1].scatter(x, y)
10plt.show()

subplots

テイストを手書き風に変更:xkcd

グラフを手書き風にできます。

1import numpy as np
2from matplotlib import pyplot as plt
3
4plt.xkcd()
5
6x = np.linspace(-np.pi, np.pi, 100)
7plt.plot(x, np.sin(x),label="y = sinx")
8plt.show()

xkcd

まとめ

matplotlibのAPI一覧からいろいろ試してみました。

API名からは用途のイメージがわかないものもあり、試してみて「へぇ、こんなのあるんだ」というのも多かったです。 また、指定オプションも多く組み込まれているので、一つのAPIでもデータの表現方法に幅が出ます。

通常利用する分には概ねの十分な範囲をカバーできていると考えています。

参考にさせていただいたサイト