Home > Blockchain >  ggplot stacked bar chart in horizontal direction. What is the influence of the y-aesthetic?
ggplot stacked bar chart in horizontal direction. What is the influence of the y-aesthetic?

Time:07-09

So I have this data:

structure(list(names = structure(1:4, .Label = c("v1", "v2", 
"v3", "v4"), class = "factor"), count = c(55, 13, 2, 2), share = c(0.76, 
0.18, 0.03, 0.03), label = c("76 %", "18 %", NA, NA), color = c("#df91a3", 
"#A5AA99", "#A5AA99", "#A5AA99")), row.names = c("v1", "v2", 
"v3", "v4"), class = "data.frame")

It looks like this:

   names count share label   color
v1    v1    55  0.76  76 % #df91a3
v2    v2    13  0.18  18 % #A5AA99
v3    v3     2  0.03  <NA> #A5AA99
v4    v4     2  0.03  <NA> #A5AA99

And now I would like to create a stacked bar chart with ggplot. That stacks the groups (from the names column) from left to right.

So I initially did the following:


pl_not_works = ggplot(df)  
  geom_col(
    aes(x = share,
        y = 1,
        group = names),
    color = "black",
    fill = df$color,
    position = ggplot2::position_fill()
  ) 

This does not work and produces the following plot:

enter image description here

I did set the y-aesthetic to 1 as I thought that all the bars could be centered around 1 (or any other y-value) and that this would not change. By googling and remembering some old stuff, I changed y=1 toy = "a" like this:

pl_works = ggplot(df)  
  geom_col(
    aes(x = share,
        y = "a",
        group = names),
    color = "black",
    fill = df$color,
    position = ggplot2::position_fill()
  ) 

which works as expected and produces this plot:

enter image description here

I then used the two plots and threw them into the layer_data() function and this is the output for both (top: did not work, bottom: did work)

> ld_not_works
# A tibble: 4 × 15
      x     y group PANEL flipped_aes  ymin  ymax    xmin   xmax colour fill     size linetype alpha works
  <dbl> <dbl> <int> <fct> <lgl>       <dbl> <dbl>   <dbl>  <dbl> <chr>  <chr>   <dbl>    <dbl> <lgl> <chr>
1  0.76   1       1 1     FALSE         0     1    0.692  0.828  black  #df91a3   0.5        1 NA    n    
2  0.18   1       2 1     FALSE         0     1    0.112  0.248  black  #A5AA99   0.5        1 NA    n    
3  0.03   1       3 1     FALSE         0.5   1   -0.0375 0.0975 black  #A5AA99   0.5        1 NA    n    
4  0.03   0.5     4 1     FALSE         0     0.5 -0.0375 0.0975 black  #A5AA99   0.5        1 NA    n    
> ld_works
# A tibble: 4 × 15
      x y          group PANEL flipped_aes  xmin  xmax ymin       ymax       colour fill    size linetype alpha works
  <dbl> <mppd_dsc> <int> <fct> <lgl>       <dbl> <dbl> <mppd_dsc> <mppd_dsc> <chr>  <chr>  <dbl>    <dbl> <lgl> <chr>
1  1    1              1 1     TRUE         0.24  1    0.55       1.45       black  #df91…   0.5        1 NA    y    
2  0.24 1              2 1     TRUE         0.06  0.24 0.55       1.45       black  #A5AA…   0.5        1 NA    y    
3  0.06 1              3 1     TRUE         0.03  0.06 0.55       1.45       black  #A5AA…   0.5        1 NA    y    
4  0.03 1              4 1     TRUE         0     0.03 0.55       1.45       black  #A5AA…   0.5        1 NA    y    

For the working one, the one where I set the y-aesthetic to a character vector, the Axes seem to be flipped, although I did not tell it to do so.

So my question is what is going on here, why does it matter if I put a numeric or a character vector to the y-aesthetic and what is the best way to create a horizontal stacked bar chart?

CodePudding user response:

The reason why y = "a" works but y = 1 does not is that "a" is interpreted as a factor, whereas 1 is interpreted as a number. This matters, since geom_col tries to guess the orientation from the data types. This is spelled out in the Orientation section of the help file:

This geom treats each axis differently and, thus, can thus have two orientations. Often the orientation is easy to deduce from a combination of the given mappings and the types of positional scales in use. Thus, ggplot2 will by default try to guess which orientation the layer should have

If you want to override the guess, you can use the orientation argument:

ggplot(df)  
  geom_col(
    aes(x = share,
        y = 1,
        group = names),
    color = "black",
    fill = df$color,
    position = ggplot2::position_fill(),
    orientation = "y"
  ) 

enter image description here

  • Related