Rebecca S
Rebecca S

Reputation: 1

Centering labels using stat_summary

I see a lot of posts on doing this with geom_text, but not how to do this with stat_summary. I try adding on to the "text" label, position = position_stack(0.5), but it just returns "cannot display this visual".

library(ggplot2)

Aggregating Data

ag<- aggregate(dataset$Value, by = list(PvA=dataset$PvA, Area=dataset$Area, Unit=dataset$Unit), FUN=sum)
ag

plotting

b<-ggplot(dataset, aes(x=PvA, y=Value, fill=Attribute)) + 
     stat_summary_bin(aes(fill=Attribute), fun.y = sum, geom="bar", position="stack", color="black")+
     stat_summary_bin(aes(label=..y..), fun.y=sum,  geom="text", color = "white", data=subset(dataset, Value >1))
b

Dataset Sample (link to Dropbox download, txt file)

Current Result

Upvotes: 0

Views: 2110

Answers (1)

camille
camille

Reputation: 16832

What you've got is actually more complicated than it seems like it needs to be. I'll illustrate with a subset of the mpg dataset, rather than downloading yours.

Instead of calculating simple summaries in stat_summary_bin, you can do them yourself before plotting (gives you control over what's going on), or you can have geom_bar do it. geom_bar is like geom_col, except it internally runs a stat_count. If you use the same stat in geom_text, you can access this calculated count to make labels. Then to center the labels, instead of the shorthand position = "stack", you use position = position_stack(vjust = 0.5).

Note that stat(count) is the replacement to ..count.., which was briefly called calc(count). I'm using the dev version from github; the CRAN version might still be ..count.. notation.

library(tidyverse)

df <- mpg %>% filter(manufacturer %in% c("chevrolet", "dodge"))

ggplot(df, aes(x = manufacturer, fill = class)) +
  geom_bar(position = "stack") +
  geom_text(aes(label = stat(count)), stat = "count", position = position_stack(vjust = 0.5))

The second way—my preference because it gives a little more control—is to calculate the counts and then pipe it into ggplot. Calling count gets you:

df %>%
  count(manufacturer, class)
#> # A tibble: 6 x 3
#>   manufacturer class       n
#>   <chr>        <chr>   <int>
#> 1 chevrolet    2seater     5
#> 2 chevrolet    midsize     5
#> 3 chevrolet    suv         9
#> 4 dodge        minivan    11
#> 5 dodge        pickup     19
#> 6 dodge        suv         7

Then you can pipe that into a simplified ggplot call. This gets the same plot, except that count will instead be labeled n.

df %>%
  count(manufacturer, class) %>%
  ggplot(aes(x = manufacturer, y = n, fill = class)) +
    geom_col(position = "stack") +
    geom_text(aes(label = n), position = position_stack(vjust = 0.5))

Upvotes: 2

Related Questions