先日seaborn
やmatplotlib
でヒストグラムを書こうと思った時に苦戦したので、備忘録と併せて記事を書きます。
具体的には以下のような状況に陥りました。
・2つ以上のグラフを重ねて書きたい(2群以上あるデータを合わせてplotしたい)
・いずれかのグラフが一意の値しか持たない(ex. 0しか持たない)ためうまく表示されない
要するに右図のようなグラフを描きたかったのに、左図のようなグラフしか書けずに苦戦した、という訳です。
環境
- google colab
matplotlib
== 3.8.0
seaborn
== 0.13.2
うまくいかなかった実装例
1群目を乱数で生成
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# 1群目を乱数で生成
x1 = np.random.normal(loc=0, scale=10, size=100)
sns.histplot(x1, bins=10, kde=True)
2群目を乱数で生成
# 2群目は1つの値しか持たないのでnp.zerosで生成
x2 = np.zeros(20)
sns.histplot(x2, bins=10, kde=True)
このように、それぞれ別々にグラフにすると表示されるのですが
2群を重ねて描画
sns.histplot(x1, bins=10, kde=True)
sns.histplot(x2)
重ねて表示すると太さが合わず、見た目が綺麗ではないです。
bins
を調整するという手もありそうですが、細いグラフの集合体になってしまいました。
何より、jupyter lab
ではオレンジの群が表示すらされませんでした。
※matplotlib
を使ってplt.hist()
で実装しても同じ結果となりました
解決策
ここで考えたのが
・グラフに表示させなくていいくらい大きい値、もしくは小さい値を任意で追加する
・グラフの表示領域を指定し、任意で追加したグラフは見えないようにする
という方法です。
実装例は以下の通りです。
2群を重ねて描画
# 2群目に任意の大きい値を追加
x2 = np.append(x2, 40)
# 重ねてヒストグラムを描く
sns.histplot(x1, bins=10, kde=True)
sns.histplot(x2, bins=10)
# グラフの表示領域を指定する
plt.xlim(x1.min()-2, x1.max()+2) # グラフの横に余白を持たせるため±2を追加
このようにすれば見た目に違和感のない重ねたヒストグラムを描くことができました。
終わりに
もしもっといい方法があるよ、などあったら教えていただけると幸いです。