Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

adjustText: matplotlib の散布図でラベルの重なりを自動調整

問題点

matplotlib の散布図などのプロットの際に、各点にラベルを付けてプロットしたい場合、下の図のようにラベルが重なってしまうため、ラベル付きプロットを諦めることが多々ありました。

f:id:Kurene:20191024012128p:plain
図1: 散布図 (Before)

解決方法

ラベルの配置を制御する方法を探していたら、adjustTextというモジュールと出会いました。

github.com

なんとラベルの重なりを最小限にし、スマートに配置してくれるモジュールとのこと。早速使ってみました。

f:id:Kurene:20191024012232p:plain
図2: adjustTextと適用した散布図(アロー無し)

重なりが最小限になり、かなり見やすくなりました!

さらに、アローを付けることもできます。

f:id:Kurene:20191024012403p:plain
図3: adjustTextと適用した散布図(アロー付き

さすがにプロットする点数が数百点ともなると処理に時間がかかる&最適化しても重なってしまうため、50±30点くらいの時に使うのが良さそうです。

プロットに使ったコード

adjust_text を import し、テキストのオブジェクト配列を adjust_text に渡すだけと、使用方法は非常に簡単です。

import numpy as np
import matplotlib.pyplot as plt
from adjustText import adjust_text

np.random.seed(47)
n_samples = 50
x = np.random.normal(0.0, 1.0, (2, n_samples))
labels = [f"{k:0=8}" for k in range(0, n_samples)]

plt.clf()
plt.plot(x[0], x[1], 'bo', c="c")
texts = [ plt.text(x[0,k], x[1,k], labels[k], 
          ha='center', va='center') for k in range(0, n_samples) ]
#adjust_text(texts)
adjust_text(texts, arrowprops=dict(arrowstyle='->', color='red'))
plt.show()