MATLABで積上げヒストグラムのプロット

Pythonで書いた積上げヒストグラムMATLABで書き直そうとしたときに
すぐに書く関数が無い様で少し手間取ったので,忘備録として書いておきます.
というかこのくらい標準で実装してくれないだろうか.

Pythonで書くときはこんなコードです.
import matplotlib.pyplot as plt
n, bins, patches = plt.hist(data, stacked=True, bins=10, range=(-2.5, 2.5))
plt.legend(['1','2','3','4','5','6','7'])
histtest_python.png 
matplotlibのhist()でヒストグラムが書けます.
積上げヒストグラムとしたい場合stacked=Trueとします.
ヒストグラムの個数カウントのデータ区間を変更する場合binsとrangeを指定します.
ヒストグラム自体は一行でビシッと書けますね.


MATLABではヒストグラムを書く関数自体はあるのですが,
積上げヒストグラムにはできないようです.

なにか方法がないか探すと,MATLABのQAページに記載がありました.

データを1系列ごとに個数数えて積上げ棒グラフでプロットせよ
とのことです.何じゃそりゃ.まあやってみましょう.

まずヒストグラムの個数のカウントです.
bins = -2.5:0.5:2.5;
stackhistdata = zeros(length(bins)-1, length(data(1,:)));
figure('visible', 'off');
for i=1:length(data(1,:))
    h = histogram(data(:,i), bins);
    stackhistdata(:,i) = h.Values;
end
binsで個数カウントするデータ範囲を指定します.
また,個数を格納するstackhistdataという行列を用意しておきます.
histgram関数でグラフが出てしまっては困るのでfigure('visible', 'off')でグラフ出力を抑制します.
histgram()でデータを1列ごとにヒストグラムを書いて返り値を得ます.
返り値のValuesにデータ区間ごとの個数が格納されているので,それを保存します.

続いて,得られた個数を積上げ棒グラフにします.
figure(1);
bar(stackhistdata, 1, 'stacked');
legend(string([1 2 3 4 5 6 7]));
grid;
bar()で棒グラフを描画します.'stacked'引数で積上げ棒グラフの指定です.
引数に1(=100%)を指定して棒グラフの幅を100%にして隙間をなくします.
凡例legend()は文字列しか指定できないので,
数字配列をstring()で文字列配列に変換して指定します.
histtest_matlab1.png 
これでやっと積上げヒストグラムが書けました.
でもよく見ると個数がPythonと違ってますね.
たぶん境界値あたりの処理が違うんでしょう.ここはちょっと放置します.

軸が気になりますね.元のヒストグラム同様にしましょう.
xticks*1-0.5);
xticklabels(string(bins));
xticksで軸位置を0.5ずつにします.
xticklabelsでラベル表記を変更して完成です.
histtest_matlab2.png 

はあめんどくさい.一発で書けるようになりませんかねMathWorksさん.



*1:1:length(bins