データ可視化のためのmatplotlibの簡単な紹介

PythonにはTensorFlow、NumPy、scikit-learn、Pandasなど、機械学習や統計解析に役立つ様々なパッケージがあります。多くのデータサイエンス・プロジェクトに欠かせないパッケージの1つがmatplotlibです。

どのPythonディストリビューションでも利用可能で、Python 3ではpipでインストールできます。他の方法も利用可能です。詳細は https://matplotlib.org/ を確認してください。

インストール

ターミナルがあるOSをお使いの場合、以下のコマンドでmatplotlibをpipでインストールすることができます。

$ python3 -m pip install matplotlib


インポート & 環境

Pythonファイルでは、MATLABのようなプロット環境とのインタフェースを可能にする pyplot 関数をインポートしたいと思います。また、プロットに線を追加するための lines 関数もインポートします。

import matplotlib.pyplot as plt
import matplotlib.lines as mlines


基本的に、このプロット環境は、図形とその属性を変数として保存することができます。これらのプロットは、簡単なコマンドで印刷したり、見たりすることができます。例えば、Googleの株価を見ることができます。具体的には、直近250日間の日付、始値、終値、出来高、修正終値(日付は np.datetime64 として格納されています)です。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook


with cbook.get_sample_data('goog.npz') as datafile:
    price_data = np.load(datafile)['price_data'].view(np.recarray)
price_data = price_data[-250:] # get the most recent 250 trading days


次に、時系列などでよく行われる方法でデータを変換します。各観測値とその前の観測値との差、$d_i$を求めます。

d_i = y_i – y_{i – 1} $$` とします。

delta1 = np.diff(price_data.adj_close) / price_data.adj_close[:-1]


また、出来高や終値のような異なる変数の変換を見ることもできます。

# Marker size in units of points^2
volume = (15 * price_data.volume[:-2] / price_data.volume[0])**2
close = 0.003 * price_data.close[:-2] / 0.003 * price_data.open[:-2]


散布図のプロット

このデータを実際にプロットするには、 plt (matplotlib.pyplot) の subplots() 関数を使用することができます。デフォルトでは、これは図の領域とプロットの軸を生成します。

ここでは、連続した日の差の散布図を作成します。詳しく説明すると、x は i 日目と前日の差、y は i+1 日目と前日(i)の差です。

fig, ax = plt.subplots()
ax.scatter(delta1[:-1], delta1[1:], c=close, s=volume, alpha=0.5)


ax.set_xlabel(r'$\Delta_i$', fontsize=15)
ax.set_ylabel(r'$\Delta_{i+1}$', fontsize=15)
ax.set_title('Volume and percent change')


ax.grid(True)
fig.tight_layout()


plt.show()


そして、x軸とy軸のラベルとプロットのタイトルを作成します。このデータは、グリッドとタイトなレイアウトでプロットすることにします。

plt.show() がプロットを表示してくれます。

行を追加する

xとyの座標をリストとして Line2D インスタンスに与えることによって、このプロットに線を追加することができます。

import matplotlib.lines as mlines


fig, ax = plt.subplots()
line = mlines.Line2D([-.15,0.25], [-.07,0.09], color='red')
ax.add_line(line)


# reusing scatterplot code
ax.scatter(delta1[:-1], delta1[1:], c=close, s=volume, alpha=0.5)


ax.set_xlabel(r'$\Delta_i$', fontsize=15)
ax.set_ylabel(r'$\Delta_{i+1}$', fontsize=15)
ax.set_title('Volume and percent change')


ax.grid(True)
fig.tight_layout()


plt.show()


ヒストグラムのプロット

ヒストグラムをプロットするには、同様の手順で、pyplothist() 関数を使用します。ここでは、平均 100、標準偏差 15 の 10000 個のランダムなデータ点 x を生成します。

関数 hist は、データ x、ビンの数、そしてデータを確率密度に正規化する density やヒストグラムの透明度を設定する alpha などの引数を取ります。

また,ライブラリ mlab を使って,同じ平均と標準偏差を持つ正規密度関数を表す線も追加します.

import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt


mu, sigma = 100, 15
x = mu + sigma*np.random.randn(10000)


# the histogram of the data
n, bins, patches = plt.hist(x, 30, density=1, facecolor='blue', alpha=0.75)


# add a 'best fit' line
y = mlab.normpdf( bins, mu, sigma)
l = plt.plot(bins, y, 'r--', linewidth=4)


plt.xlabel('IQ')
plt.ylabel('Probability')
plt.title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)


plt.show()


バーチャート

ヒストグラムが視覚的な密度に役立つのに対して、棒グラフはデータのカウントを表示するのに役立ちます。matplotlib で棒グラフを描画するには、 bar() 関数を使用します。これは、他の引数とともに、カウントとデータラベルを x と y として受け取ります。

例として、異なる言語を使用するプログラマーの数のサンプルを見てみましょう。

import numpy as np
import matplotlib.pyplot as plt

objects = ('Python', 'C++', 'Java', 'Perl', 'Scala', 'Lisp')
y_pos = np.arange(len(objects))
performance = [10,8,6,4,2,1]

plt.bar(y_pos, performance, align='center', alpha=0.5)
plt.xticks(y_pos, objects)
plt.ylabel('Usage')
plt.title('Programming language usage')

plt.show()


画像のプロット

Pythonでは画像の解析は非常によく行われます。当然のことながら、画像を見るには matplotlib が使えます。画像を読み込むには、cv2 ライブラリを使用します。

read_image()` 関数の概要は以下の通りです.

  • 画像ファイルを読み込みます.
  • カラーチャンネルを分割します.
  • それらを RGB に変換します.
  • 画像のサイズを変更します.
  • RGB 値の行列を返します。

残りのコードは、画像認識CNNで使われるデータから、猫と犬の最初の5枚の画像を読み込んでいます。画像は連結され、同じ軸にプリントされる。

import matplotlib.pyplot as plt
import numpy as np
import os, cv2


cwd = os.getcwd()
TRAIN_DIR = cwd + '/data/train/'


ROWS = 256
COLS = 256
CHANNELS = 3


train_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] # use this for full dataset
train_dogs =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'dog' in i]
train_cats =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'cat' in i]


def read_image(file_path):
    img = cv2.imread(file_path, cv2.IMREAD_COLOR) #cv2.IMREAD_GRAYSCALE
    b,g,r = cv2.split(img)
    img2 = cv2.merge([r,g,b])
    return cv2.resize(img2, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)


for a in range(0,5):
    cat = read_image(train_cats[a])
    dog = read_image(train_dogs[a])
    pair = np.concatenate((cat, dog), axis=1)
    plt.figure(figsize=(10,5))
    plt.imshow(pair)
    plt.show()


結論

この記事では、散布図、ヒストグラム、棒グラフにデータをプロットするための matplotlib の使い方の簡単な紹介を見ました。また、これらのプロットに線を追加しました。最後に、cv2 ライブラリを使って画像を読み込み、matplotlib を使ってその画像をプロットする方法を見ました。

タイトルとURLをコピーしました