ヒストグラムのビン(bin)の値を直接操作した後で、ヒストグラムっぽいグラフを作りたいことがあるだろう。
以下では、plt.hist
を使った場合と、np.histgram
で計算させた、binの位置 X
とCounts Y
を使って plt.hist
以外で描画する方法を紹介する。
データ作成部分
ここは共通部分なので最初に書くべし。
import numpy as np import matplotlib.pyplot as plt np.random.seed(0) x = np.random.normal(0,1,10000) #平均0、標準偏差1、N=10000
普通にplt.hist
で描画
plt.hist(x, bins=100, range=[-10,10]) plt.xlim(-10,10) plt.show()
plt.bar
で描画
棒グラフを描画する plt.bar
を使う
Y, X = np.histogram(x, bins=100, range=[-10,10]) plt.bar((X[:-1]+X[1:])*0.5, Y, width=X[1]-X[0]) plt.xlim(-10,10) plt.ylim(0,None) plt.show()
plt.fill_between
で描画
少しトリッキーだが間を塗りつぶせる plt.fill_between
を使う
Y, X = np.histogram(x, bins=100, range=[-10,10]) X2 = np.array([e for e in X for _ in range(2)][1:-1]) Y2 = np.array([e for e in Y for _ in range(2)]) plt.fill_between(X2, X2*0, Y2, lw=0) plt.xlim(-10,10) plt.ylim(0,None) plt.show()
普通に plt.hist
で枠だけ描画
histtype="step"
で 枠(階段)だけ描画できる。
plt.hist(x, bins=100, range=[-10,10], histtype="step", lw=1) plt.xlim(-10,10) plt.show()
plt.step
で枠だけ描画
Y, X = np.histogram(x, bins=100, range=[-10,10]) plt.step((X[:-1]+X[1:])*0.5, Y, where='mid', lw=1) plt.xlim(-10,10) plt.ylim(0,None) plt.show()
plt.plot
で枠だけ描画
少しトリッキーだが、点列を作って plt.plot
で描画することもできる
Y, X = np.histogram(x, bins=100, range=[-10,10]) X2 = np.array([e for e in X for _ in range(2)][1:-1]) Y2 = np.array([e for e in Y for _ in range(2)]) plt.plot(X2, Y2, lw=1) plt.xlim(-10,10) plt.ylim(0,None) plt.show()
plt.hist
で塗りつぶし+枠を描画
plt.hist
で塗りつぶしと枠を両立するには fill="full", histtype="step"
とする。
plt.hist(x,bins=100, range=[-10,10], color="tab:cyan", fill="full", histtype="step", lw=1.5, edgecolor="tab:red") plt.xlim(-10,10) plt.show()
plt.bar
とplt.step
で塗りつぶし+枠を描画
Y, X = np.histogram(x,bins=100, range=[-10,10]) plt.bar((X[:-1]+X[1:])*0.5, Y, width=X[1]-X[0], color="tab:cyan") plt.step((X[:-1]+X[1:])*0.5, Y, where='mid', lw=1.5, color="tab:red") plt.xlim(-10,10) plt.ylim(0,None) plt.show()
凡例の描画
step+barで擬似ヒストグラムの描画はできるものの、凡例 legend
はそのままでは描画できないので、Patch
で凡例を作る必要がある。
import numpy as np import matplotlib.pyplot as plt np.random.seed(0) x = np.random.normal(0,1,10000) #平均0、標準偏差1、N=10000 Y, X = np.histogram(x, bins=100, range=[-10,10]) Xcenter = (X[:-1]+X[1:])*0.5 X2 = np.array([e for e in X for _ in range(2)][1:-1]) Y2 = np.array([e for e in Y for _ in range(2)]) fig, ax = plt.subplots(ncols=3, nrows=3, figsize=(12,10)) ax[0][0].hist(x, bins=100, range=[-10,10], label="hist") ax[0][1].bar(Xcenter, Y, width=X[1]-X[0], label="bar") ax[0][2].fill_between(X2, X2*0, Y2, lw=0, label="fill_between") ax[1][0].hist(x, bins=100, range=[-10,10], histtype="step", lw=1, label="hist+step") ax[1][1].step(Xcenter, Y, where='mid', lw=1, label="step") ax[1][2].plot(X2, Y2, lw=1, label="plot") ax[2][0].hist(x,bins=100, range=[-10,10], color="tab:cyan", fill="full", histtype="step", lw=1.5, edgecolor="tab:red", label="hist") ax[2][1].bar(Xcenter, Y, width=X[1]-X[0], color="tab:cyan", label="bar") ax[2][1].step(Xcenter, Y, where='mid', lw=1.5, color="tab:red", label="step") ax[2][2].bar(Xcenter, Y, width=X[1]-X[0], color="tab:cyan") ax[2][2].step(Xcenter, Y, where='mid', lw=1.5, color="tab:red") from matplotlib.patches import Patch ax[2][2].legend(handles=[Patch(facecolor='tab:cyan', edgecolor='tab:red', lw=1.5, label='bar+step+legend')]) for col in range(3): for row in range(3): ax[row][col].set_xlim(-10,10) ax[row][col].set_ylim(0,None) if col==2 and row==2:continue ax[row][col].legend() plt.show()
いろんな方法があるなあ・・・
2次元の場合
または、以下の記事の 「plt.pcolormesh で描画する方法」 参照