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:
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:
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"
)