ggplot2で特定の点の目盛りだけ目立たせる

前に質問を受けてつぶやいたやつですが、備忘録的にブログにも書いておきます。

theme()に渡す要素は、すべてではないですがベクトルとして渡すことができます。

たとえば、3つあるデータ系列のうち真ん中の系列だけ赤くてでかい軸ラベルにするには、次のように指定します。

library(ggplot2)

ggplot(iris) +
  geom_boxplot(aes(Species, Sepal.Length)) +
  theme(axis.text.x = element_text(
    size   = c(     10,    20,      10),
    colour = c("black", "red", "black")
  ))

f:id:yutannihilation:20171119162044p:plain

この例で分かるように、スタイル指定を特定の部分だけ変えたい場合は、軸ラベルの数と同じ長さのベクトルを渡す必要があります。なので、あらかじめ軸ラベルの数が分からないと使いこなすことは困難です。

エラーにはならないものの、必要な数より少ない場合はリサイクルされてしまいます。

d <- data.frame(x = 1:10,
                y = 1:10)

ggplot(d) +
  geom_point(aes(x, y)) +
  theme(axis.text.x = element_text(
    size   = c(     10,    20),
    colour = c("black", "red")
  ))

f:id:yutannihilation:20171119162836p:plain

なので、めんどくさいですが、あらかじめ自分でbreaksを計算して、それを指定するようにしましょう。たとえばx = 4の軸ラベルだけを目立たせることを考えてみます。

# breakを計算
breaks <- scales::extended_breaks()(d$x)

# breakの分だけsizeとcolourを複製
sizes  <-  rep(10L, length(breaks))
colours <- rep("black", length(breaks))

# 目立たせるbreakを挿入する場所を計算
point <- 4
idx_to_insert_point <- max(which(breaks < point))

# それぞれ値を挿入
breaks <- append(breaks, values = point, after = idx_to_insert_point)
sizes <- append(sizes, values = 20L, after = idx_to_insert_point)
colours <- append(colours, values = "red", after = idx_to_insert_point)

ggplot(d, aes(x, y)) +
  geom_point() +
  geom_line() +
  scale_x_continuous(breaks = breaks) +
  theme(axis.text.x = element_text(
    size   = sizes,
    colour = colours
  ))

f:id:yutannihilation:20171119164735p:plain

どうでしょうか。ゼロからやるのはちょっとめんどくさそうなので、よく使うようなら関数化/パッケージ化しとくといいかもしれませんね。