静かなる名辞

pythonとプログラミングのこと

2019/03/22:TechAcademyがteratailの質問・回答を盗用していた件
2019/03/26:TechAcademy盗用事件 公式発表と深まる疑念


【python】matplotlibのboxplotで外れ値を表示しないようにする

はじめに

 matplotlibのboxplotを使うと簡単に箱ひげ図が描けます。ただし、デフォルト設定では外れ値が黒い円で表示されます。

 どんなデータでも、サンプル数が多いと一定数の外れ値は出てしまいます。ただ、図を見る人は気にするところですし、外れ値がたくさんあると見た目にも悪いので、何らかの処置が必要です。

 外れ値が描画されてしまうプログラムの例

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
x = np.random.normal(size=3*10**3)  # サンプル数に注目
plt.boxplot(x)
plt.savefig("result1.png")

外れ値がたくさん出ている
result1.png 外れ値がたくさん出ている

 ということで、外れ値を表示させない方法を解説します。なお、この記事の内容は公式リファレンスに基づいています。

matplotlib.pyplot.boxplot — Matplotlib 3.1.1 documentation

シンプルに表示させない

 boxplotのキーワード引数のsymを使うと外れ値を「描画させない」設定が可能になります。具体的には、空文字列を指定します。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
x = np.random.normal(size=3*10**3)
plt.boxplot(x, sym="")  # 変更点
plt.savefig("result2a.png")

外れ値が表示されなくなった
result2a.png 外れ値が表示されなくなった

 注意点としては、これはあくまでも外れ値の描画を行わないだけで、外れ値そのものはデフォルト通り計算されるということが挙げられます。つまり、本来の最大値・最小値よりひげが短くなります。

 プロット上でだけ「消している」ということですね。

 参考:
4-3. 外れ値検出のある箱ひげ図 | 統計学の時間 | 統計WEB

 また、外れ値のマーカーに好きな記号を指定したりすることもできます。本来はこの用途で用いる引数です。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
x = np.random.normal(size=3*10**3)
plt.boxplot(x, sym="+")  # 変更点
plt.savefig("result2b.png")

マーカーを十字にしてみた
result2b.png マーカーを十字にしてみた

 使えるマーカーの一覧はこちらを参照。
matplotlib.markers — Matplotlib 3.1.1 documentation

外れ値の計算そのものをやめる

 (外れ値も含めた)本来の最大値・最小値に基づいてひげを出す場合は、whis="range"を指定します。

 そもそも外れ値の概念なしで箱ひげ図を描くというやり方になります。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
x = np.random.normal(size=3*10**3)
plt.boxplot(x, whis="range")  # 変更点
plt.savefig("result3.png")

result3.png 上の方法で非表示にするよりひげが長くなる
result3.png 上の方法で非表示にするよりひげが長くなる

 この方が誤解を招く恐れがないので(つまり、外れ値検出をやっておいて外れ値をプロットしないという図は少しイレギュラーで伝わりづらい気がするので)、これでやるのがおすすめです。ただし、外れ値が少なくて、そんな極端に外れていないとき向きのやり方です(やたらひげが長いのも不格好ですから……)。

まとめ

 二つやり方がありますが、意味が微妙に違うし、実際にそれぞれで異なった結果になるので注意してください。