Matplotlib 超入門(2):文字の挿入,ヒストグラム

以前の投稿までで,関数を描くこと,テキストデータをグラフにすることを紹介しました.公式のビギナーズガイドに従うと次は「二つのグラフを並べて出力する」ということについて説明するべきですが,こういうことよりも個人的には一枚の図をきちんと書けるようにすることの優先順位が高いと考えます.なので,ビギナーズガイドの順番を一つ飛ばして,今回は「文字の挿入」について書こうと思います.さらに「文字を用いる」章の例として挙げられているグラフがヒスとグラフであり,それが乱数を用いて書かれていることもあるので,この記事では

  1. 文字を挿入する
  2. 乱数を使う
  3. ヒストグラムを作成する

の3つについて説明することになります.







今回の例で用いるチュートリアルのコードと図は次のようになります.リンクを踏むと原文の英語のサイトが見れます.それぞれの行の説明は計算結果のあとに書いてあります.なお,乱数を使っているため皆さんの結果とチュートリアルの結果と下の図の結果はすべて違う形をしていると思いますが,それで正常です.ヒストグラムの大体の形があってればオッケーです.

import numpy as np
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, 50, normed=1, facecolor='g', alpha=0.75)

plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

計算結果
intro2_1

乱数

まず乱数を生成して数字の集りを作成する部分だけ取り出したいとおもいます.

import numpy as np
import matplotlib.pyplot as plt

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

最初の2行までは前回の投稿でみた通りです.numpy と pyplot を使う宣言をしています.

変数の代入(複数個同時に)

mu, sigma = 100, 15

Python では「(変数の名前) = (それに代入する値)」という形で変数に値を代入します.たとえば「a = 10」と書けば「a という変数に値 10 を代入する」という意味になります.これを複数個の変数について同時に行ったものがこの行になります.上の例では,mu という変数と sigma という変数を使うことを宣言(定義)して,それぞれに 100 と 15 を代入しています.

numpy を用いた乱数の生成

Python で乱数を生成する方法で一番簡単な方法は,numpy にある機能を用いることです.乱数とは”ランダムに”選んできた数のことです.この”ランダムに”の意味について考えることが乱数を考える上での第一関門なのですが,今回は matplotlib の説明なので深く考えないことにしたいと思います.numpy で乱数を作る方法は,例えば次のような方法があります.

numpy.random.rand(10)

この「numpy.random.rand」は「0 以上 1 未満の数を度の数も同じ程度ひいきしてとってくる(一様乱数)」ということをします.かっこの中の 10 は乱数を 10 個生成することを意味しています.

それを踏まえたうえで,今回のコードを見てみると

np.random.randn(10000)

という式に乱数が使われているっぽいです.そのとおりで,「np.random.randn」というのは「標準正規分布に従う乱数を生成する」という意味になります(Wikipedia「標準正規分布」).要するに「標準正規分布」という分布に従うように”ランダムに”数をとってきます.かっこの中の 10000 はとってきた乱数の数です.

それを踏まえたうえで,元のコードの次の部分を見てみます.

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

大体意味はお分かりかと思いますが,ひとつ注意していただきたいのは,= の左側にある x はある一つの値を持つ変数でなく配列(リストみたいなもの)であるということです.つまり,生成された 10000 この乱数それぞれに「mu + sigma」を足して,その 10000 個の数字の羅列を x は意味しています.これはprint(x)を直後に書くことでわかります.

気になる方へ:numpy は(おそらく)メルセンヌ・ツイスターを用いてる

(おそらく)ってのが大事です例えば次のリンク先.
Differences between numpy.random and random.random in Python
ここでは

they both use the Mersenne twister sequence to generate their random numbers

と書いてあるので,メルセンヌ・ツイスターを用いているといっていいのではと考えました.

さらにこちら.
pythonで疑似乱数生成 – ryamadaのコンピュータ・数学メモ
確実にメルセンヌ・ツイスターを用いているという根拠は正直に言うと見つけることができませんでした...上のはてぶの方も自分と同じように「Mersenne-Twisterのようだ」としていますね...

ヒストグラム

もとのコードからヒストグラムの作成に関する部分を抜き出してきます.とはいってもコメントアウトの部分を抜かすと1行だけですね.

n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)

ヒストグラムの作成

先ほどのデータからヒストグラムを作成してみます.

plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)

plt.hist」 は matplotlib のヒストグラムを書いてくれる機能です.引数(かっこの中)の最初の x はヒストグラムの作成にに用いるデータ(数字の集り),50 はヒストグラムの間隔を何等分するかを表しています.

ヒストグラムのスタイル

残りの「norm … 0,75」の部分はそのヒストグラムの様式についてのオプションです.「normed=1」は「ビンの高さをすべて足すと1になるように縦軸を調整する」という意味で,「規格化」とか「正規化」と言われます.英語だとどちらも “normalization” です.

facecolor=’g’」はヒストグラムの塗りつぶしの色を緑(green)にするという意味です.

alpha=0.75」はグラフの透かしをどれだけ入れるかという意味です.alpha=0 にすると全く透明になってしまって,alpha=1にすると透明にせず完全に塗りつぶされます.計算結果は alpha=0.75 のときですが,確かにビミョーに透けて後ろの点線が見えているのがわかります.

ヒストグラムのスタイルを変数として代入

n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)

この行の右側については先ほどまでで理解できましたが,今度は左側の 「n, bins, patches」 を見ていきたいと思います.先ほど複数の変数に同時に値を代入するときの書式を見てみると,n, bins, patches にも何かの変数のようです.こちらを日本語に訳して,わかりやすいように加工してみます.

n にはデータの数(正確には上で規格化された値,つまりヒストグラムの棒の高さ)がの配列,bins はビンそれぞれの左端の値の配列,patches にはヒストグラムの様式が格納されています.何を言っているのかいまいちわからない方は print(n[2]),print(bins),print(patches) などをもとのプログラムに加えて実行してみると意味が明確にわかるかと思います.例えば print(patches[0]) を入れて計算すると「Rectangle(39.4842,0;2.43786×4.10195e-05)」のようになっている.これはヒストグラムの一番左側の棒についての情報で,”形(左端の座標;横幅x高さ)”と保存されているようです.

「bin」という言い方についてコメントですが,ヒストグラムの棒それぞれを細長い容器(ビン)だと思っていただければよいです.データを容器に入れていくと高さがどんどん上がっていくイメージですね.

文字の挿入

ヒストグラムについては初心者は少し難しかったかもしれないですが,次にやる「文字の挿入」については簡単です.文字を挿入する部分を取り出してくると次のようになります.

plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

plt.xlabel() とplt.ylabel() は前の投稿の最初の例にあるとおりx軸とy軸のラベルを決めるところでしたね.念のためy軸のラベルの向きに注意しておきましょう.

図のタイトルを挿入

plt.title('Histogram of IQ')

新しく出てきた「plt.title」 は大体想像がつきますが,図に題名を付けます.ちなみに,ラベルとタイトルの中身をそのまま日本語に変えるだけではうまく日本語は表示されません.もし日本語対応を急ぐ方は次のリンク先にやさしい説明があるので,そちらを参考にしていただければと思います.

matplotlibで、判例やグラフタイトルに日本語を使用する

入れたい位置に文字を書く

plt.text(60, .025, r'iretaimoji')

plt.text」を用いることで,文字を入れたい場所に書くことができます.使い方は

plt.text(入れる文字列の左下の座標, '入れたい文字列')

という形になります.例えばグラフの[math](x,y)=(2,3)[/math]のところに「hoge」という文字が書きたい場合には

plt.text(2.0, 3.0, 'hoge')

とすればよいです.

TeX の書式で文字を書く

しかし今回の例を見ると入れたい文字列の ‘hoge’ に対応する部分が r’$\mu=100,\ \sigma=15$’と複雑になっていて,「”の中は文字列」とさっき習ったはずなのに表示されているものは書いたものとは違う形のものが出ています.実はこれは数式を含む原稿などを作成するときによく用いられる TeX というプログラムの書式を使っていて,文字列の前の「r」は TeX のルールに従いますという意味になります.”の中身は TeX で書く時の指示そのものになっています.ここら辺は数式などをよく使う方だけ理解していればよいでしょう.

おまけ:グリッドを引く

ここまででもうほとんど学ぶことはないのですが,最後に一つだけ,グリッド(方眼紙の線)を引く線のコマンドを見てみましょう.

plt.grid(True)

これで「方眼紙のような線を引きましょうという指示」です.逆に線を引きたくないのであれば Ture を False に変えればよいです.この例では方眼紙の間隔は自動的に決まっています.グリッドの間隔の設定を急ぐ方は次のリンク先を参考にしていただければと思います.
matplotlib: Change grid interval and specify tick labels


あたりの plt.axis([40, 160, 0, 0.03]) では,グラフの表示範囲を決めています.前回の投稿の二番目の例にあるとおりです.最後は,plt.show() で今までの書くように指示したものをウィンドウで表示するような指示になります.

乱数,ヒストグラム,文字列を書く,の3つについてほんの簡単な説明になりましたが,理解の助けになったのであればうれしいです.しかし,ここまでの知識だとまだきれいな図を書くのは難しいでしょう.もっと見やすくするためには文字の大きの調整などももちろん必要になってくると思います.次回は文字のスタイルについてもう少し突っ込んで解説してみたいと思います.次はもっと図もいっぱい載せてわかりやすくしてみたいです.

このブログについて

IAtLeX です.ブログをはじめてさほど時間がたっていないので,未熟な内容が多々あるかと思いますが,それも時間が解決してくれるはず...Python系の記事を着々と充実させていきたいです.投稿主についてはこちらを参照してください.

このブログについて - http://iatlex.com/about_blog/

コメントを残す

*