備忘ログ

チラシの裏的備忘録&メモ

ggplot2の棒グラフの上や下に値をラベルとして書き込む方法のメモ

ggplot2の棒グラフの上や下に値をラベルとして書き込む方法のメモ。とりあえず簡単なgeom_col()の場合で書いていく。

上に書くだけならgeom_text()で位置を調整して書けばいい。

例えば次のようなデータの場合。

library(ggplot2)
df <- data.frame(X = LETTERS[1:4],
                 value = c(10, 20, 30, 40))
df
##   X value
## 1 A    10
## 2 B    20
## 3 C    30
## 4 D    40
ggplot(df, aes(x = X, y = value)) +
  geom_col()

この棒グラフの上に値を書き込みたいと思いたい場合、geom_text()を使い、そのままの位置に書くと棒グラフに被るので、棒グラフの上に描画するようにvjustnudge_yを使ってラベルの位置を調整しながら次のようにかける。

ggplot(df, aes(x = X, y = value)) +
  geom_col() +
  geom_text(aes(label = value), nudge_y = 2)

ggplot(df, aes(x = X, y = value)) +
  geom_col() +
  geom_text(aes(label = value), vjust = -0.5) +
  ylim(0, 42)

nudge_yvjustの違いは上のコードを見てもらえば分かる通り、nudge_yの場合はいい塩梅に描画範囲を調整してくれるが、vjustは描画範囲を調整してくれないので、自分で調整する必要がある。

じゃあ、いつもnudge_yでいいじゃないかとなるかもしれないが一部画面ではvjustのほうが都合がいい場合がある。

例えば次のようなデータで横棒グラフを描く場合を考える。

df <- data.frame(X1 = rep(LETTERS[1:4], 3),
                 X2 = rep(LETTERS[24:26], each = 4),
                 value = seq(10, by = 10, length.out = 12))
head(df)
##   X1 X2 value
## 1  A  X    10
## 2  B  X    20
## 3  C  X    30
## 4  D  X    40
## 5  A  Y    50
## 6  B  Y    60
ggplot(df, aes(x = X1, y = value, fill = X2)) +
  geom_col(position = position_dodge())

このとき、nudge_yだと次のようになる。

ggplot(df, aes(x = X1, y = value, fill = X2)) +
  geom_col(position = position_dodge()) +
  geom_text(aes(label = value), position = position_dodge() ,nudge_y = 2)
## Error in `geom_text()`:
## ! Both `position` and `nudge_x`/`nudge_y` are supplied.
## ℹ Only use one approach to alter the position.

position = position_dodge()を使ってずらしたいと思ったとおりにいかない(ここでposition = position_dodge()をしないと積み上げグラフの位置で数字が書かれてしまう)。ドキュメントにもちゃんと、positionnudge_xは一緒に使えないと書いている。

ここで、vjustを使うと思ったとおりに行く。

ggplot(df, aes(x = X1, y = value, fill = X2)) +
  geom_col(position = position_dodge()) +
  geom_text(aes(label = value), 
            position = position_dodge(0.85), 
            vjust = -0.5) +
  ylim(c(0, 130))

こんな感じに行く。

さらに正負の値が混じった次のようなデータを考える。

df <- data.frame(X = c("A", "B", "C", "D"),
                 value = c(10, 20, -10, -20))

ggplot(df, aes(x = X, y = value)) + 
  geom_col()

このとき、正の値の場合は棒グラフの上に、負の値の場合は棒グラフの下に描画したいと思った場合を考える。単純にnudge_yなどで位置を書くと正負の場合分けができない。

ggplot(df, aes(x = X, y = value)) + 
  geom_col() +
  geom_text(aes(label = value), nudge_y = 2)

結論から言うとifelse()などで条件づけするとかける。

ggplot(df, aes(x = X, y = value)) + 
  geom_col() +
  geom_text(aes(label = value), nudge_y = ifelse(df$value >= 0, 2, -2))

これで思ったグラフがかける。