boshek
boshek

Reputation: 4406

Label only one bar in ggplot2

I am trying to only label a subset of bars in ggplot2. I thought the following would work but it defaults to labelling the centre of the group.

library(tidyverse)
#> -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
#> v ggplot2 3.3.5     v purrr   0.3.4
#> v tibble  3.1.6     v dplyr   1.0.7
#> v tidyr   1.1.4     v stringr 1.4.0
#> v readr   2.1.1     v forcats 0.5.1
#> -- Conflicts ------------------------------------------ tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag()    masks stats::lag()
df <- iris |>
  pivot_longer(-Species) |>
  count(Species, name, wt = value, name = "value")

df |>
  ggplot(aes(x = name, y = value, fill = Species)) +
  geom_col(position = position_dodge()) +
  geom_text(data = df[df$Species == "setosa", ], aes(label = value))

So here I am looking to label the setosa label.

Upvotes: 2

Views: 1744

Answers (1)

stefan
stefan

Reputation: 124093

First you have to add position_dodge(width = .9 to dodge the text labels by the same amount as the bars, where .9 is the default width of geom_col.

However, to make the dodging work all groups have to present in your data so you have to use the whole dataframe for geom_text too. To label only one group use e.g. an ifelse to set the labels for the other categories to an empty string.

library(ggplot2)
library(dplyr)
library(tidyr)

df <- iris |>
  pivot_longer(-Species) |>
  count(Species, name, wt = value, name = "value")

df |>
  ggplot(aes(x = name, y = value, fill = Species)) +
  geom_col(position = position_dodge()) +
  geom_text(aes(label = ifelse(Species == "setosa", value, "")), 
            position = position_dodge(width = .9), vjust = 0)

Upvotes: 3

Related Questions