ggplot2で離散スケールの一部の色だけ変更したい

データセットmtcarsをfactorにしたcarbで色分けしてプロットするため、次のようなコードを書いたとする。

library(ggplot2)
ggplot(mtcars, aes(x = hp, y = qsec, colour = factor(carb))) +
  geom_point()

結果はこうなる。

f:id:Rion778:20210824124507p:plain

ここで、carb == 3の場合のみ色を黒色にしたいとする。どうするべきか?

考えられる方法はいくつかある。

  1. scale_color_manual()ですべての色を指定する
  2. データセットを分割し、geom_point()を複数回呼び出す
    • 最初に思いついた方法だったが、いくらか欠点がある。例えば複数回呼び出したgeom_point()の間で色を変更してしまうと凡例がうまく表示されなくなる。おそらく他にも不都合が出る場合があるだろう。
  3. scale_color_manual()で一部の色を指定する
    • このような機能があるわけではないので、多少ステップが必要になる。次に説明する。

scale_color_manual()で一部の色を指定する

scale_color_manual()values =に色名をベクトルで与えればその色に設定してくれるので、色名のベクトルのうち変更の必要のない部分を標準の(あるいは任意の好きな)パレットから取得するようにすればよい。

ggplot2で利用されているパレットの実際の色名を取得するには、scalesパッケージが使える。

例えばデフォルトのカラーパレットの色はhue_pal()関数で取得できる。要素が3つの場合に設定される色を知りたければhue_pal()(3)のようにする。

> scales::hue_pal()(3)
[1] "#F8766D" "#00BA38" "#619CFF"

冒頭の例に戻って、factor(carb)で色分けした場合の色は次のように取得できる。

l <- mtcars$carb |> unique() |> length() # carbの異なる要素の数を知る
colour <- scales::hue_pal()(l) # パレットの色を取得

carb == 3はプロットでいうと3番目になっているので、そこを黒に書き換えれば良い。必ずしもカラーコードを16進数で指定する必要はない。

colour[3] <- "black"

あとはscale_color_manual()を利用すれば色の変更が完了する。

ggplot(mtcars, aes(x = hp, y = qsec, colour = factor(carb))) +
  geom_point() +
  scale_color_manual(values = colour)

f:id:Rion778:20210824130020p:plain

参考