Pythonでヒストグラムを作成する方法【Matplotlib】

Pythonでヒストグラムを作成する方法【Matplotlib】 プログラミング

次のヒストグラムは、ウィキペディア(Wikipedia)の「ヒストグラム」にあるモノです。
この記事では、このヒストグラムと同じものを作成していきます。
以下では、このヒストグラムを「ゴールのヒストグラム」と呼びます。

ウィキペディア(Wikipedia)の「ヒストグラム」

この記事を読めば、ヒストグラムを作成できるようになります。
本記事は次の構成で進めていきます。

本記事の内容

  • Pythonでヒストグラムを作成するための環境
  • とりあえず、Pythonでヒストグラムを作成する
  • Matplotlibで作成したヒストグラムを調整する
  • Matplotlibで作成したグラフの表示(サイズ、余白、ラベル)を調整する

上記の項目に沿って、本記事の説明を行っていきます。
まずは、この記事で用いた環境の説明からです。

Pythonでヒストグラムを作成するための環境

  • Windows 10 Home (バージョン1909)※以下の説明は64bit前提
  • Python 3.7.3
  • NumPy 1.18.5
  • Matplotlib 3.2.1

Pythonの上記ライブラリは、すべてインストールする必要があります。
インストールしていないライブラリは、以下のコマンドでインストール可能です。

pip install numpy
pip install matplotlib

Matplotlibを日本語化対応する必要がある場合は、以下の記事をご覧ください。
日本語が「□□□」と表示される場合は、対応の必要ありです。

とりあえず、Pythonでヒストグラムを作成する

「とりあえず」、Pythonで簡単にヒストグラムを作成しましょう。
どれほど、簡単に作成できるのかを確認できます。

モジュールを読み込む

ヒストグラムを作成するために必要なモジュールをimportします。
コードは以下。

import matplotlib.pyplot as plt

データを用意する

ウィキペディア日本語版の記事「ヒストグラム」ページへのアクセスデータです。

ウィキペディア日本語版の記事「ヒストグラム」ページへのアクセスデータです。

閲覧回数閲覧回数
17816625
212617606
315618483
423119377
521520370
630421587
748422667
854423643
956624756
1054525505
1147826436
1225827399
1322528611
1437329679
1562030575


31565

リスト型(list型)のデータを用意します。
30行前後のデータであるため、そのままコードに書きます。
もっと行数の多いデータであれば、ファイルに保存して読み込む形を取ります。

# 対象データ
values = [78,126,156,231,215,304,484,544,566,545,478,258,225,373,620,
              625,606,483,377,370,587,667,643,756,505,436,399,611,679,575,565]

ヒストグラムを作成する

ヒストグラムを表示するのは、たったこれだけです。
この1行で最低限のグラフを作成できます。

# グラフを作成
plt.hist(values)

グラフを画像ファイルに保存する

作成したグラフを画像ファイルに保存します。
facecolorは、背景色です。
何も指定しなければ、「白」となります。

# グラフを画像保存
plt.savefig("result.png", facecolor="white")

「とりあえず、Pythonでヒストグラムを作成する」のまとめ

ここまでコードをまとめます。
コードは、わずか4行です。(コメント除く)

import matplotlib.pyplot as plt

# 対象データ
values = [78,126,156,231,215,304,484,544,566,545,478,258,225,373,620,
              625,606,483,377,370,587,667,643,756,505,436,399,611,679,575,565]

# グラフを表示
plt.hist(values)
# グラフを画像保存
plt.savefig("result.png", facecolor="white")

このプログラムの実行結果が、以下のグラフです。

とりあえず、Pythonで作成したヒストグラム

とりあえず、Pythonでヒストグラムを作成できました。
簡単に作成できるということがわかったと思います。

では、次以降でこのヒストグラムをゴールのヒストグラムに寄せていきます。

Matplotlibで作成したヒストグラムを調整する

ゴールのヒストグラムに近づけていくために、必要な項目を洗い出しましょう。

  • ビンを数を設定する
  • ビンの幅を設定する
  • ビンの色を設定する

ビンとは?
以下の見たままです。

ヒストグラムにおけるビン

ビンを数を設定する

引数にbinsを追加。
ゴールのヒストグラムを同じく8個に指定します。

plt.hist(values, bins=8)

この結果は以下。

8個のビンで描いたヒストグラム

ビンの数は、8個になりました。
しかし、ゴールのヒストグラムとは、まだ形が異なりますね。

ビンの幅を設定する

ゴールのヒストグラムは、幅100ということです。
同じように幅100で設定します。
引数にrwidthを追加。

plt.hist(values, bins=8, rwidth=100)

この結果は以下。

8個のビンで描いたヒストグラム

まったく、変わりませんね。
ということは、デフォルトで100だったということになります。

ウィキペディア(Wikipedia)の「ヒストグラム」には、以下の表示があります。
幅だけではなく、開始と終了も関係があるようです。

閲覧回数その回数を記録した日数
0 – 991
100 – 1992
200 – 2994
300 – 3995
400 – 4994
500 – 5997
600 – 6997
700 – 7991

開始は0、終了は800とグラフと表から読み取れます。
これらは、rangeで設定可能です。

plt.hist(values, bins=8, rwidth=100, range=(0, 800))

結果は以下。

8個のビンで描いた範囲が0~800のヒストグラム

グラフの形が同じになりました。

ビンの色を設定する

colorで設定します。
複数データセット(複数種類のビン)がある場合は、配列での指定となります。

plt.hist(values, bins=8, rwidth=100, range=(0, 800), color='#14AE67')

色を変更した結果は以下。

ビンの色を変更したヒストグラム

アウトラインがありませんので、追加します。
以下のコードで設定します。

plt.hist(values, bins=8, rwidth=100, range=(0, 800), color='#14AE67',
         edgecolor='#000000', linestyle='solid', linewidth=1.0)

edgecolorでアウトラインの色を指定します。
linewidthにより、アウトラインの線の太さを指定することになります。

linestyleは、指定しなくても良いですが、念のため。
なお、linestyleに設定できるのは以下。

‘-‘ or ‘solid’solid line
‘–‘ or ‘dashed’dashed line
‘-.’ or ‘dashdot’dash-dotted line
‘:’ or ‘dotted’dotted line

アウトラインを付けた結果は、以下。

アウトラインを引いたヒストグラム

Matplotlibで作成したグラフの表示(サイズ、余白、ラベル)を調整する

ヒストグラムだけのことではなく、Matplotlibで作成したグラフすべてに関連する内容となります。
この内容の詳細に関しては、次のブログで詳細に説明しています。

そのため、本記事では詳細の説明は省きます。
詳細を知りたい場合は、上の記事をご覧ください。

画像サイズを合わせる

ゴールのヒストグラムの画像サイズは、横557px・縦491pxです。
対応するコードは以下。

# サイズ指定
fig = plt.figure(dpi=100, figsize=(5.57, 4.91))

x軸とy軸のラベルを設定する

ラベルを設定するコードは以下。
y軸のラベルを移動させる処理も含めています。

ax = fig.add_subplot(111)
ax.yaxis.set_label_coords(-0.1, 0.4)

# ラベル設定
plt.xlabel("閲覧回数(回)", fontsize=13)
plt.ylabel("日\n数\n(日)", fontsize=13, rotation=0)

余白を調整する

ゴールのヒストグラムと同じような余白にします。

# 余白調整
plt.subplots_adjust(left=0.13, right=0.99, bottom=0.12, top=0.99)

グラフとy軸間のスペースを除去する

ヒストグラムにおけるグラフとy軸間のスペース

上図の赤線の部分です。
ここをなくすためには、表示位置の調整が必要です。

x軸の目盛表示は、0~850ぐらいですね。
これは以下のコードで実現できます。

# グラフと枠線とのスペース除去
plt.xlim(0, 850)

上と右の枠線を非表示にする

下図の黄色の部分を非表示にします。

ヒストグラム上で不要な枠線

対応するコードは以下。

# 上・右の枠線を非表示
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

Pythonでヒストグラムを作成する方法のまとめ

ここまでの対応を含めたコードは以下。

import matplotlib.pyplot as plt

# サイズ指定
fig = plt.figure(dpi=100, figsize=(5.57, 4.91))
ax = fig.add_subplot(111)
ax.yaxis.set_label_coords(-0.1, 0.4)

# 対象データ
values = [78,126,156,231,215,304,484,544,566,545,478,258,225,373,620,
               625,606,483,377,370,587,667,643,756,505,436,399,611,679,575,565]

# ラベル設定
plt.xlabel("閲覧回数(回)", fontsize=13)
plt.ylabel("日\n数\n(日)", fontsize=13, rotation=0)
# グラフと枠線とのスペース除去
plt.xlim(0, 850)

# グラフを作成
plt.hist(values, bins=8, rwidth=100, range=(0, 800), color='#14AE67',
         edgecolor='#000000', linestyle='solid', linewidth=1.0)

# 上・右の枠線を非表示
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

# 余白調整
plt.subplots_adjust(left=0.13, right=0.99, bottom=0.12, top=0.99)
# グラフを画像保存
plt.savefig("result.png", facecolor="white")

このコードの実行結果は以下。

ほぼ完成したヒストグラム

ゴールのヒストグラムとほぼ同じ表示です。
これで完了と言ってもいいぐらいです。

でも、まだ一致できていない箇所が残っています。

  • 英語のラベル表示
  • x軸・y軸の先頭が矢印
  • x軸の「0」が不要

英語のラベル表示

次の英語のラベル表示は未対応です。
冗長過ぎるため、対応していません。

  • Page Views(times)
  • Days

x軸・y軸の先頭が矢印

また、x軸・y軸の先頭を矢印にするのは、結構な大事のようです。
そこまで重要なことではないため、今回は対応を見送ります。
機会があれば、対応します。

x軸の「0」が不要

x軸の目盛で0が不要

不細工な表示になっています。
x軸のラベルを制御することで対応します。

# x軸の目盛指定
plt.xticks(xscale)

xscaleは、以下の値が設定されています。
[100 200 300 400 500 600 700 800]

最終的に出来上がったコードは以下です。
途中でx軸の目盛設定のために計算処理を加えました。
その影響で、importするモジュールが増えています。

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

# サイズ指定
fig = plt.figure(dpi=100, figsize=(5.57, 4.91))
ax = fig.add_subplot(111)
ax.yaxis.set_label_coords(-0.1, 0.4)

# 対象データ
values = [78,126,156,231,215,304,484,544,566,545,478,258,225,373,620,
               625,606,483,377,370,587,667,643,756,505,436,399,611,679,575,565]

# x軸の目盛に関する処理
scale_num = 100
x_max = (math.ceil(max(values) / scale_num) + 1 ) * scale_num
xscale = np.arange(scale_num, x_max, scale_num)

# ラベル設定
plt.xlabel("閲覧回数(回)", fontsize=13)
plt.ylabel("日\n数\n(日)", fontsize=13, rotation=0)
# グラフと枠線とのスペース除去
plt.xlim(0, x_max - (scale_num/2))
# x軸の目盛指定
plt.xticks(xscale)

# グラフを作成
plt.hist(values, bins=8, rwidth=100, range=(0, 800), color='#14AE67',
         edgecolor='#000000', linestyle='solid', linewidth=1.0)

# 上・右の枠線を非表示
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)

# 余白調整
plt.subplots_adjust(left=0.13, right=0.99, bottom=0.12, top=0.99)
# グラフを画像保存
plt.savefig("result.png", facecolor="white")

そして、最終的に出来上がったヒストグラムのグラフ画像は以下。

完成したヒストグラム

今度こそ、完了です。

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