import する。

>>> import matplotlib.pyplot as plt

グラフを描写するキャンパスを作成する

matplotlib ではまずグラフを描写するキャンパスとなる Figure オブジェクトを作成します。

>>> fig = plt.figure()

キャンパスにグラフを作成する

次に作成した Figure オブジェクトに対して、グラフを描写するための AxesSubplot オブジェクトを add_subplot() で追加します。

add_subplot(nrows, ncols, plot_number)

nrows、ncols で Figure オブジェクトを縦横それぞれ何分割するかを指定します。
例えば、nrows=2, ncols=2 なら縦横をそれぞれ2分割するので、計4つの領域ができます。
分割した領域には上から行方向に1, 2, … と番号が振られます。



そして plot_number で分割したうち、どの部分に AxesSubplot オブジェクトを追加するかを指定します。add_subplot(2, 2, 3) では縦横2分割したうち、2行1列目に追加されます。

>>> ax1 = add_subplot(2, 2, 1)  # 2行1列目に追加
>>> ax2 = add_subplot(2, 2, 2)  # 2行2列目に追加
>>> ax3 = add_subplot(2, 2, 3)  # 1行1列目に追加
>>> ax4 = add_subplot(2, 2, 4)  # 2行2列目に追加



nrows, ncols, nrows * ncols がいずれも10未満の場合、つまり add_subplot(nrows, ncols, plot_number) の引数がすべて1桁であることが保証されている場合は次のような引数の渡し方もできます。

# add_subplot(2, 2, 3) と一緒
# nrows * ncols が10未満なら plot_number も10未満
>>> add_subplot(223)

途中で分割数を変更した場合は、以前に作成した AxesSubplot オブジェクトは削除されます。

>>> ax1 = add_subplot(2, 2, 1)  # 2行2列に分割
>>> ax2 = add_subplot(1, 2, 2)  # 1行2列目に分割
# 分割数を変更したので、ax1 は削除されてしまった。

一度に作成する

1つずつ AxesSubplot オブジェクトを作成するのが煩わしい場合は subplots() で Figure オブジェクトと複数の AxesSubplot オブジェクトを一度に作成できます。

>>> fig, axes = plt.subplots(2, 3)
>>> axes
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7f3308c76c18>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3308a2e8d0>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x7f33089facf8>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7f330893e710>]], dtype=object)

axes は2次元のリストになっていて、1行2列にアクセスしたい場合は axes[0, 1] とします。

グラフを描写する。

AxesSubplot オブジェクトに実際にグラフを描写してみます。

# 2x2 に分割する
>>> fig, axes = plt.subplots(2, 2)
# y = 2x のグラフを描写する。
>>> xs = [x for x in range(100)]
>>> ys = [2 * x for x in xs]
# 1行2列目の AxesSubplot オブジェクトに描写する。
>>> axes[0, 1].plot(xs, ys, 'r')
>>> plt.show()  # GUI で表示する

numpy の Broadcasting

numpy の ndarray の基本演算を紹介する.

要素ごとの加算

numpy.add(x, y) または x + y で要素ごとの加算を行える.

>>> a = np.array([[1, 1, 1],
                  [2, 2, 2]])
>>> b = np.array([[1, 1, 1],
                  [2, 2, 2]])
>>> np.add(a, b)
array([[2, 2, 2],
       [4, 4, 4]])

要素ごとの減算

numpy.subtract(x, y) または x – y で要素ごとの減算を行える.

>>> a = np.array([[3, 3, 3],
                  [2, 2, 2]])
>>> b = np.array([[1, 1, 1],
                  [1, 1, 1]])
>>> np.subtract(a, b)
array([[2, 2, 2],
       [1, 1, 1]])

要素ごとの乗算

numpy.multiply(x, y) または x * y で要素ごとの乗算を行える.

>>> a = np.array([[1, 2, 3],
                  [1, 2, 3]])
>>> b = np.array([[3, 3, 3],
                  [2, 2, 2]])
>>> np.multiply(a, b)
array([[3, 6, 9],
       [2, 4, 6]])

要素ごとの除算

Python 2 と Python 3 で除算の挙動が異なるため,注意する必要がある.
Python 2 でも from __future__ import division とした場合は Python 3 の挙動になる.

演算 Python 2 Python 3
numpy.divide(x, y) または x / y (Python 2) 余りを切り捨てる 余りを切り捨てない
numpy.true_divide(x, y) または x / y (Python 3) 余りを切り捨てる 余りを切り捨てる
numpy.floor_divide(x, y) または x // y (Python 3) 余りを切り捨てる 余りを切り捨てる
>>> a = np.array([[2, 4, 6],
                  [8, 10, 12]])
>>> b = np.array([[2, 2, 2],
                  [2, 2, 2]])
>>> np.divide(a, b)
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
>>> np.floor_divide(7, 3)
2
>>> np.floor_divide([1., 2., 3., 4.], 2.5)
array([ 0.,  0.,  1.,  1.])

符号反転

numpy.negative(x) または -x で符号を反転する.

>>> np.negative([1., -1.])
array([-1.,  1.])

要素ごとのべき乗

numpy.negative(x) または -x で符号を反転する.

>>> a = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
>>> b = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
>>> np.power(a, b)
array([  1.,   4.,  27.,  64.,  25.,   6.])

numpy の Broadcasting

numpy の Broadcasting という機能を紹介する.
異なる形状の ndarray 同士で演算を行おうとした場合に,演算前に形状を揃える Broadcasting が行われる.
次の2つのルールを適用した結果,演算対象の ndarray の形状が一致させることができれば,Broadcast が可能となる.

ルール1: 次元数 ndim を揃える.

演算対象の中で,一番次元数が大きい ndarray より小さい次元数を持つ ndarray は1で埋めて一番大きい次元数を揃える.

ルール2: 形状 shape を揃える.

演算対象の中で,一番次元ごとの数を見ていき,その数が1の場合のみ最も大きいものに合わせる.
その際,要素はその次元の同じ値で埋める.

ルール1,ルール2 を適用した結果,形状が一致した場合は Broadcasting 可能である.
以下にいくつかできる例を出す.

ルール1,ルール2 を適用しても形状が一致しない場合は Broadcasting はできず,演算を行おうとした場合はエラーになります.

OKなコード例

>>> a = np.array([[1, 2, 1],
                  [1, 2, 1]])
>>> b = np.array([2, 1, 2])
>>> a.shape
(2, 3)
>>> b.shape
(3,)
>>> c = a + b
>>> c
array([[3, 3, 3],
       [3, 3, 3]])
>>> c.shape
(2, 3)
>>> a = np.zeros((1, 3, 1, 5))
>>> b = np.zeros((3, 3, 2, 5))
>>> c = np.zeros((3, 1, 1))
>>> d = a + b + c
>>> d.shape
(3, 3, 2, 5)

NGなコード例

>>> a = np.zeros((2, 3, 5))
>>> b = np.zeros((3))
>>> c = a + b
ValueError: operands could not be broadcast together with shapes (2,3,5) (3,)

About

Ubuntu 16.04 に NVIDIA-Docker を導入する方法を紹介します。

検証環境

2017年3月30日時点の情報です。

  • Ubuntu 16.04
  • GeForce GTX 1080
  • NVIDIA ドライバ 375

NVIDIA ドライバをまだインストールしていない場合は こちらの記事 を参考に先に導入してください。

Docker Engine のインストール

[公式サイト] Get Docker for Ubuntuを参考にします。

$ sudo apt-get update
$ sudo apt-get -y install apt-transport-https ca-certificates curl
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce

インストールできたか確認します。

$ docker --version
Docker version 17.03.1-ce, build c6d412e

NVIDIA Docker のインストール

[GitHub] nvidia-dockerを参考にします。

NVIDIA Docker をインストールします。

$ wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
$ sudo dpkg -i nvidia-docker*.deb

ユーザーを docker グループに追加

デフォルトでは、sudo をつけないと nvidia-docker コマンドが実行できません。

$ nvidia-docker ps
nvidia-docker | 2017/01/14 20:07:56 Error: Cannot connect to the Docker daemon. Is the docker daemon running on this host?

ユーザーを docker グループに追加します。

$ sudo usermod -aG docker $USER

再起動すると、sudo なしで nvidia-docker コマンドが叩けるようになっていると思います。