Loading [MathJax]/extensions/tex2jax.js

[matplotlib] 98. ヒストグラムのalphaを調整して視認性を高める

matplotlib

はじめに

ヒストグラムを比較する際、複数のヒストグラムを重ねて表示することが多い。しかし、ヒストグラムが重なり合っている場合、分布がどの程度まで及んでいるのかがわからなくなる。したがって、ここでは棒グラフのalpha(透明度)を調整することでヒストグラムの視認性を高める方法について説明する。

コード

#histogramでalpha調整
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('ggplot')
#make histo
dat0 = np.random.randn(10000)
dat1 = np.random.randn(5000)+1
dat2 = np.random.randn(7000)+4
dat3 = np.random.randn(4000)+8
dat4 = np.random.randn(6000)+2
dat5 = np.random.randn(7000)+4
dat6 = np.random.randn(5000)+6
dat7 = np.random.randn(8000)+9
dat8 = np.random.randn(3000)+1
dat9 = np.random.randn(8000)+3
dat10 = np.random.randn(3000)+5
dat11 = np.random.randn(9000)+8
bins = np.linspace(-3,13,80)
hist0, bins0 = np.histogram(dat0, bins=bins)
bins0=bins0[1:]
hist1, _ = np.histogram(dat1, bins=bins)
hist2, _ = np.histogram(dat2, bins=bins)
hist3, _ = np.histogram(dat3, bins=bins)
hist4, _ = np.histogram(dat4, bins=bins)
hist5, _ = np.histogram(dat5, bins=bins)
hist6, _ = np.histogram(dat6, bins=bins)
hist7, _ = np.histogram(dat7, bins=bins)
hist8, _ = np.histogram(dat8, bins=bins)
hist9, _ = np.histogram(dat9, bins=bins)
hist10, _ = np.histogram(dat10, bins=bins)
hist11, _ = np.histogram(dat11, bins=bins)
width=(bins.max()-bins.min())/len(bins)
#alphaの調整
fig,ax=plt.subplots(3,1,dpi=120,figsize=(6,6),sharex=True,sharey=True)
ax=ax.ravel()
ax[0].bar(bins0,hist0,width=width,alpha=1,ec="k")
ax[0].bar(bins0,hist1,width=width,alpha=.3,ec="k")
ax[0].bar(bins0,hist2,width=width,alpha=.3,ec="k")
ax[0].bar(bins0,hist3,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist4,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist5,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist6,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist7,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist8,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist9,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist10,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist11,width=width,alpha=.3,ec="k")
[a.set(xlabel="x",ylabel="y") for a in ax]
plt.suptitle("1")
plt.tight_layout()
plt.savefig("histogram_alpha1.png",dpi=130)
plt.show()

解説

モジュールのインポートなど

#histogramでalpha調整
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('ggplot')

バージョン

#version
import matplotlib
print(matplotlib.__version__)
3.3.4
print(np.__version__)
1.20.1

データの生成

dat0 = np.random.randn(10000)
dat1 = np.random.randn(5000)+1
dat2 = np.random.randn(7000)+4
dat3 = np.random.randn(4000)+8
dat4 = np.random.randn(6000)+2
dat5 = np.random.randn(7000)+4
dat6 = np.random.randn(5000)+6
dat7 = np.random.randn(8000)+9
dat8 = np.random.randn(3000)+1
dat9 = np.random.randn(8000)+3
dat10 = np.random.randn(3000)+5
dat11 = np.random.randn(9000)+8

np.random.randn()で0から1の範囲の乱数を作成する。

続いて、np.histogramでヒストグラムデータに変換する。

bins = np.linspace(-3,13,80)
hist0, bins0 = np.histogram(dat0, bins=bins)
bins0=bins0[1:]
hist1, _ = np.histogram(dat1, bins=bins)
hist2, _ = np.histogram(dat2, bins=bins)
hist3, _ = np.histogram(dat3, bins=bins)
hist4, _ = np.histogram(dat4, bins=bins)
hist5, _ = np.histogram(dat5, bins=bins)
hist6, _ = np.histogram(dat6, bins=bins)
hist7, _ = np.histogram(dat7, bins=bins)
hist8, _ = np.histogram(dat8, bins=bins)
hist9, _ = np.histogram(dat9, bins=bins)
hist10, _ = np.histogram(dat10, bins=bins)
hist11, _ = np.histogram(dat11, bins=bins)
width=(bins.max()-bins.min())/len(bins)

全て不透明なヒストグラムの場合

#alpha=1の場合
fig,ax=plt.subplots(3,1,dpi=120,figsize=(6,6),sharex=True,sharey=True)
ax=ax.ravel()
ax[0].bar(bins0,hist0,width=width,alpha=1,ec="k")
ax[0].bar(bins0,hist1,width=width,alpha=1,ec="k")
ax[0].bar(bins0,hist2,width=width,alpha=1,ec="k")
ax[0].bar(bins0,hist3,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist4,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist5,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist6,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist7,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist8,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist9,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist10,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist11,width=width,alpha=1,ec="k")
[a.set(xlabel="x",ylabel="y") for a in ax]
plt.savefig("histogram_alpha0.png",dpi=130)
plt.show()

全てのヒストグラムのalphaを1とし、不透明とした場合は以下のようになる。
ヒストグラムが互いに重なり合い、見えない部分が発生している。

ヒストグラムのalphaを調整した場合

#alphaの調整
fig,ax=plt.subplots(3,1,dpi=120,figsize=(6,6),sharex=True,sharey=True)
ax=ax.ravel()
ax[0].bar(bins0,hist0,width=width,alpha=1,ec="k")
ax[0].bar(bins0,hist1,width=width,alpha=.3,ec="k")
ax[0].bar(bins0,hist2,width=width,alpha=.3,ec="k")
ax[0].bar(bins0,hist3,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist4,width=width,alpha=1,ec="k")
ax[1].bar(bins0,hist5,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist6,width=width,alpha=.3,ec="k")
ax[1].bar(bins0,hist7,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist8,width=width,alpha=1,ec="k")
ax[2].bar(bins0,hist9,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist10,width=width,alpha=.3,ec="k")
ax[2].bar(bins0,hist11,width=width,alpha=.3,ec="k")
[a.set(xlabel="x",ylabel="y") for a in ax]
plt.suptitle("1")
plt.tight_layout()
plt.savefig("histogram_alpha1.png",dpi=130)
plt.show()

一つのヒストグラムを不透明にし、その他を透明とした場合は以下のようになる。重なりあっている部分があらわになっていることがわかる。

不透明なヒストグラムが最前面に来る場合があるので、その際はzorderを設定して、不透明なヒストグラムが最背面に来るようにする。

fig,ax=plt.subplots(3,1,dpi=120,figsize=(6,6),sharex=True,sharey=True)
ax=ax.ravel()
ax[0].bar(bins0,hist0,width=width,alpha=.3,ec="k",zorder=2)
ax[0].bar(bins0,hist1,width=width,alpha=1,ec="k",zorder=1)
ax[0].bar(bins0,hist2,width=width,alpha=.3,ec="k",zorder=2)
ax[0].bar(bins0,hist3,width=width,alpha=.3,ec="k",zorder=2)
ax[1].bar(bins0,hist4,width=width,alpha=.3,ec="k",zorder=2)
ax[1].bar(bins0,hist5,width=width,alpha=1,ec="k",zorder=1)
ax[1].bar(bins0,hist6,width=width,alpha=.3,ec="k",zorder=2)
ax[1].bar(bins0,hist7,width=width,alpha=.3,ec="k",zorder=2)
ax[2].bar(bins0,hist8,width=width,alpha=.3,ec="k",zorder=2)
ax[2].bar(bins0,hist9,width=width,alpha=1,ec="k",zorder=1)
ax[2].bar(bins0,hist10,width=width,alpha=.3,ec="k",zorder=2)
ax[2].bar(bins0,hist11,width=width,alpha=.3,ec="k",zorder=2)
[a.set(xlabel="x",ylabel="y") for a in ax]
plt.suptitle("2")
plt.tight_layout()
plt.savefig("histogram_alpha2.png",dpi=130)
plt.show()
コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

numpy.histogram — NumPy v2.2 Manual
matplotlib.pyplot.bar — Matplotlib 3.10.1 documentation

コメント