giacomoV giacomoV - 2 months ago 28
R Question

ggplot2 - barplot moving order

By default

ggplot2
keeps the orders of variables constant in a plot, for example here:
a
will stay at the bottom,
b
in the middle, and
c
at the top.

enter image description here

What I would like to produce a graph where the order changes depending on the changing proportions (
%
).

So, time is on the
x-axis
and proportion (
%
) on the
y-axis
, like in a regular barplot.

You can visualise the table like this :

code color `1` `2` `3`
1 a red 0.2 0.8 0.2
2 b blue 0.8 0.0 0.2
3 c yellow 0.0 0.2 0.6


What I would like is this:

enter image description here

The plot is ordered now according to the proportion. This enables to visualise more easily the hierarchy between the states over time. First
blue
(b) is more prominent, then
red
(a) and finally
yellow
(c). The order between the states in the plot can change.

However, I am not quite sure how to do it.

I tried using
order
:
order(n)
like :

td %>% group_by(time) %>% mutate(ord = order(n, decreasing = T))


and to explicitly provide the position to
ggplot


but it doesn't seem to work.

t %>%
count(time, code) %>% group_by(time) %>% mutate(n = n / sum(n)) %>%
ggplot(aes(time, n, fill = code)) + geom_bar(stat = 'identity') +
scale_fill_manual(values = c('red', 'blue', 'yellow')) +
scale_x_discrete(limits = factor(td$ord)) # positions #


data

t = structure(list(id = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L,
3L, 4L, 4L, 4L, 5L, 5L, 5L), .Label = c("1", "2", "3", "4", "5"
), class = "factor"), code = structure(c(2L, 1L, 1L, 2L, 3L,
3L, 2L, 1L, 3L, 2L, 1L, 3L, 1L, 1L, 2L), .Label = c("a", "b",
"c"), class = "factor"), time = structure(c(1L, 2L, 3L, 1L, 2L,
3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("1", "2",
"3"), class = "factor")), .Names = c("id", "code", "time"), row.names = c(NA,
-15L), class = "data.frame")

Answer

You could simply order your data.frame according to column n, before calling ggplot():

t %>% 
  count(time, code) %>% group_by(time) %>% mutate(n = n / sum(n)) %>%
  arrange(desc(n)) %>% # only need to add this line
  ggplot(aes(time, n, fill = code)) + geom_bar(stat = 'identity') + 
  scale_fill_manual(values = c('red', 'blue', 'yellow')) 

enter image description here

Comments