統計検定の問題を解いていて、ヒストグラムが出てきましたので、勉強がてら Ploty、と、Bokeh でそれぞれ描画してみます。
データセットは、訪日外国人消費動向調査 | 統計情報 | 統計情報・白書 | 観光庁 にある、平成30年1月~3月期 の集計結果を用います。
データセット
イギリスの人の日本にきた回数と、回答した人の数を抜粋しました。
訪問回数 | 回答数 |
---|---|
1回目 | 84 |
2回目 | 18 |
3回目 | 12 |
4回目 | 4 |
5回目 | 12 |
6~9回目 | 5 |
10~19回 | 7 |
20回以上 | 12 |
前提
Bokeh と Ploty の バージョンは以下の通りです。
- Bokeh
% python3 -m pip list | grep bokeh
bokeh 0.12.16
-
holoviews
bokeh0.12.16
で、graph描画する方法が見つけられず、holoviews 経由で描画したので、holoviewsもインストールしております。
holoviews 1.10.4
-
Ploty
% python3 -m pip list | grep plotly
plotly 2.7.0
ヒストグラムについて
そもそも、棒グラフなのですが、真面目に考えるとあまりよくわかっていなかったので、調べてみました。
-
ヒストグラム - Wikipedia
Wikipedia -
メトリクスを用いたソフトウェア品質定量評価・改善 (GQM, Metrics, ET2013) ソフトウェアの品質観点で、サイクロマチック複雑度のヒストグラムが記載されていました。
-
ソフトウェア品質知識体系ガイド(第2版)-SQuBOK Guide V2- - Google ブックス
SQuBOK ガイドの 第2版 の 335 ページに以下のように記載されています。データのばらつきを把握したり、分布の特徴を見たり、規格値とデータの関係を見たりするために用いる、データの度数分布を表示した柱状図。
-
Googleスプレッドシートでヒストグラム(Excelは大変なので) - Akiyahの日記
Google スプレッドシートでのヒストグラムの書き方
Bokeh でヒストグラムを描画する
まず、Bokeh でヒストグラムを描画します。
調べた限りだと、区間決定後のヒストグラムを描画する方法がわからず、区間決定後の値を再度集計して、bins を 20 に指定して描画しました。
警告が出ましたが、そのまま描画しております。
import numpy as np
import holoviews as hv
import random
hv.extension('bokeh')
# ヒストグラムの値 区間決定後の値 を np.repeat、np.concatenate を使って再度集計
values = np.concatenate([np.repeat([1], 84),
np.repeat([2], 18),
np.repeat([3], 12),
np.repeat([4], 4),
np.repeat([5], 12),
np.repeat([random.randint(6,9)], 5),
np.repeat([random.randint(10,19)], 7),
np.repeat([random.randint(20,20)], 12)], axis=0)
frequencies, edges = np.histogram(values, 20)
# options で グラフの幅を指定
hv.Histogram(frequencies, edges).options(width=600)
WARNING:root:Histogram: Histogram edges should be supplied as a tuple along with the values, passing the edges will be deprecated in holoviews 2.0.
Plotly で描画する
これは、現在はまだ動作しない旨の警告が出力されました。
import numpy as np
import holoviews as hv
import random
hv.extension('plotly')
# ヒストグラムの値 区間決定後の値 を np.repeat、np.concatenate を使って再度集計
values = np.concatenate([np.repeat([1], 84),
np.repeat([2], 18),
np.repeat([3], 12),
np.repeat([4], 4),
np.repeat([5], 12),
np.repeat([random.randint(6,9)], 5),
np.repeat([random.randint(10,19)], 7),
np.repeat([random.randint(20,20)], 12)], axis=0)
frequencies, edges = np.histogram(values, 20)
hv.Histogram(frequencies, edges)
WARNING:root:Histogram: Histogram edges should be supplied as a tuple along with the values, passing the edges will be deprecated in holoviews 2.0.
:Histogram [x] (Frequency)
ploty の API を直接使用する
以下、のコードでヒストグラムが描画できました。
import numpy as np
import plotly.plotly as py
import plotly.graph_objs as go
import random
import plotly.offline as offline
offline.init_notebook_mode()
# ヒストグラムの値 区間決定後の値 を np.repeat、np.concatenate を使って再度集計
values = tuple(np.concatenate([np.repeat([1], 84),
np.repeat([2], 18),
np.repeat([3], 12),
np.repeat([4], 4),
np.repeat([5], 12),
np.repeat([random.randint(6,9)], 5),
np.repeat([random.randint(10,19)], 7),
np.repeat([random.randint(20,20)], 12)], axis=0))
data = go.Histogram(x=values,
xbins=dict(start=0, end=20, size=1)) # 区間の指定。sizeが区間幅
# レイアウトの指定
layout = go.Layout(
xaxis = dict(title="value", dtick=10),
yaxis = dict(title="count"),
bargap = 0.1)
fig = dict(data=[data], layout=layout)
offline.iplot(fig)
まとめ
区間決定後のデータを用いて、ヒストグラムを Bokeh と Plotly で描いてみました。
実施した後、思ったのですが、区間決定後のデータは普通に棒グラフで描くのでは?と思いました。
グラフ描画ライブラリの、ヒストグラムメソッドは、「ヒストグラムでないデータをヒストグラムにする」のが役割で、
既にヒストグラム化済みのデータセットを描画するためのものではないということがわかりました。
numpy の 変な使い方は学習できましたが、一般的なやり方ではなさそうに思いました。 以上です。
コメント