ggplot2 パッケージによる可視化の際のラベルの重なりを防ぐ

概要
ggrepel パッケージを使うと、ggplot2 パッケージによる可視化の際に、ラベルとラベルが重なって見にくくなることを防ぐことができる。

はじめに

R の ggplot2 パッケージで散布図などを作るときに、データ点に対してラベルをつけたいということがあるだろう。そういったときに便利なのが、ggrepel パッケージである [1] 。この ggrepel パッケージを使えば、ラベル同士が重なることが抑制される [2] 。なお、以下では散布図の場合を扱うが、ggrepel パッケージは他の種類の可視化にも利用することができる。例えば、Matt Strimas-Mackey 氏は Mapping the Longest Commericial Flights in R という記事の中で、地図上のラベルが重ならないようにするためにこのパッケージを用いている。

使い方

まずは、必要なパッケージを読みこもう。もし ggrepel パッケージをインストールしていなければ、install.packages("ggrepel") のようにしてインストールしておこう。

library("ggplot2")
library("ggrepel")

あとは、以下のように、ggplot() で ggplot 用のオブジェクトを作り、それに geom_point() を加えて普通の散布図を作る。そして、最後に geom_text_repel()を加えるだけで、見やすい形でラベルを出力することができる。

ggplot(USArrests, aes(x = UrbanPop, y = Rape, label = rownames(USArrests))) +
  geom_point() +
  geom_text_repel()

このコードの出力結果は以下の通り。

データ点やラベルが重ならないように散布図が描かれている。
データ点やラベルが重ならないように散布図が描かれている。

上記のコードでは、USArrests というデータセットを用いている。このデータセットは、1975年の米国で逮捕された人の情報が州ごとに載っている。今回は、都市に住む人口の割合 (UrbanPop) をX軸に、10万人当たりの強姦での逮捕者数 (Rape) をY軸にとった散布図を描こうとしている。また、このデータセットでは、列名として州名が使われているので、rownames(USArrests) とすることで、ラベルに使う州名が取得できる。そして、州名をラベルに使うことを指定するために、上記のコードの最初の部分では、label = rownames(USArrests) としているのだ。

枠付きのラベルの出力

また、geom_text_repel() の代わりに、geom_label_repel() を使ってラベルを出力することもできる。これを使うと、ラベルの文字の下に長方形の枠が表示される。

ggplot(USArrests, aes(x = UrbanPop, y = Rape, label = rownames(USArrests))) +
  geom_point() +
  geom_label_repel()

このコードの出力結果は以下の通り。

長方形の枠をつけた形での出力例。
長方形の枠をつけた形での出力例。

一部のラベルのみ表示する

先ほどの例ではすべての州名をラベルとして表示したが、一部だけ表示したいという場合もあるだろう。

その場合は、表示したくない州の文字列を空にしてしまえば良い。例えば、以下の例では、Alaska, Vermont, Nevada, Rhode Island の4州以外の表示を消している。

states <- rownames(USArrests)
selected_states <- c("Alaska", "Vermont", "Nevada", "Rhode Island")
states[!states %in% selected_states] <- ""
ggplot(USArrests, aes(x = UrbanPop, y = Rape, label = states)) +
  geom_point() +
  geom_text_repel()

このコードを実行すれば、以下のように4州だけのラベルが出てくる。

Alaska, Vermont, Nevada, Rhode Island の4州だけのラベルが表示された例。
Alaska, Vermont, Nevada, Rhode Island の4州だけのラベルが表示された例。

ggrepel パッケージを使わない場合

ggrepel パッケージを使わずに、ggplot2 パッケージの素の機能だけを使って、データ点とラベルとを表示することは可能である。しかし、以下に示すように、何も設定しないとラベルがデータ点と同じ場所に描かれてしまい、重なって表示される。

ggplot(USArrests, aes(x = UrbanPop, y = Rape, label = rownames(USArrests))) +
  geom_point() +
  geom_text()
ggrepel パッケージを使わずに重なってしまった例。ラベルの表示位置を手動で調整することも不可能ではないが、面倒である。
ggrepel パッケージを使わずに重なってしまった例。ラベルの表示位置を手動で調整することも不可能ではないが、面倒である。

ここで ggrepel パッケージを使わずに重ならないようにすることも可能だが、いささか調整が面倒である。だから、特に理由がなければ、ggrepel パッケージを使った方が楽だろう。

脚注
  1. 英語の “repel” は、「おいはらう」や「はねのける」といった意味。 []
  2. ただし、ラベルが大量にある状況などでは、どうしても重なりが残ってしまうことがある。 []