Order of Legend Entries in Ggplot2 Barplots with Coord_Flip()

Order of legend entries in ggplot2 barplots with coord_flip()

This has little to do with ggplot, but is instead a question about generating an ordering of variables to use to reorder the levels of a factor. Here is your data, implemented using the various functions to better effect:

set.seed(1234)
df2 <- data.frame(year = rep(2006:2007),
variable = rep(c("VX","VB","VZ","VD"), each = 2),
value = runif(8, 5,10),
vartype = rep(c("TA","TB"), each = 4))

Note that this way variable and vartype are factors. If they aren't factors, ggplot() will coerce them and then you get left with alphabetical ordering. I have said this before and will no doubt say it again; get your data into the correct format first before you start plotting / doing data analysis.

You want the following ordering:

> with(df2, order(vartype, variable))
[1] 3 4 1 2 7 8 5 6

where you should note that we get the ordering by vartype first and only then by variable within the levels of vartype. If we use this to reorder the levels of variable we get:

> with(df2, reorder(variable, order(vartype, variable)))
[1] VX VX VB VB VZ VZ VD VD
attr(,"scores")
VB VD VX VZ
1.5 5.5 3.5 7.5
Levels: VB VX VD VZ

(ignore the attr(,"scores") bit and focus on the Levels). This has the right ordering, but ggplot() will draw them bottom to top and you wanted top to bottom. I'm not sufficiently familiar with ggplot() to know if this can be controlled, so we will also need to reverse the ordering using decreasing = TRUE in the call to order().

Putting this all together we have:

## reorder `variable` on `variable` within `vartype`
df3 <- transform(df2, variable = reorder(variable, order(vartype, variable,
decreasing = TRUE)))

Which when used with your plotting code:

ggplot(df3, aes(x=variable, y=value, fill=vartype)) +
geom_bar() +
facet_grid(. ~ year) +
coord_flip()

produces this:

reordered barplot

Changing the order of bars in a bar plot after using coord_flip() in ggplot2

Have you tried just turning study into a factor and reversing its order before plotting it? I don't have a reproducible example to test this out but it might work, since coord_flip reverses the (now reversed) order.

library(tidyverse)

data.quality %>%
mutate(study = fct_rev(study)) %>%
ggplot(aes(x = study, y = score)) +
geom_bar(stat = "identity", fill = "#66c2a5") +
coord_flip() +
scale_y_continuous(name = "Total quality score", limits = c(0, 7),
breaks = 0:7) +
scale_x_discrete(name = element_blank()) +
theme(axis.ticks.y = element_blank())

Flip ordering of legend without altering ordering in plot

You're looking for guides:

ggplot(dTbl, aes(x=factor(y),y=x, fill=z)) +
geom_bar(position=position_dodge(), stat='identity') +
coord_flip() +
theme(legend.position='top', legend.direction='vertical') +
guides(fill = guide_legend(reverse = TRUE))

I was reminded in chat by Brian that there is a more general way to do this for arbitrary orderings, by setting the breaks argument:

ggplot(dTbl, aes(x=factor(y),y=x, fill=z)) +
geom_bar(position=position_dodge(), stat='identity') +
coord_flip() +
theme(legend.position='top', legend.direction='vertical') +
scale_fill_discrete(breaks = c("r","q"))

Ordering Legend in Multi-Bar ggplot2 Chart

Option 1 - Order: C, B and A


To reverse the legend labels you only need to add: guides(fill = guide_legend(reverse = TRUE)). Keeping the original order of the bars: C, B and A.

ggplot(d, aes(x = Category,
y = Valuelst,
fill = GroupTitle)) +
geom_bar(stat = "identity", position = "dodge") +
coord_flip() +
scale_fill_manual("Legenda",
values = c(
"GroupC" = "#deebf7",
"GroupB" = "#3182bd",
"GroupA" = "#9ecae1"
)) +
guides(fill = guide_legend(reverse = TRUE))

Sample Image

Option 2 - Order: A, B and C


To reverse the order of the bars, we just reorder the levels before plotting.

d$GroupTitle <- factor(d$GroupTitle, levels = c("GroupC","GroupB","GroupA"))

# make graph
ggplot(d, aes(x = Category,
y = Valuelst,
fill = GroupTitle)) +
geom_bar(stat = "identity", position = "dodge") +
coord_flip() +
scale_fill_manual("Legenda",
values = c(
"GroupC" = "#deebf7",
"GroupB" = "#3182bd",
"GroupA" = "#9ecae1"
)) +
guides(fill=guide_legend(reverse=TRUE))

Sample Image

Flip order of data in grouped bar plot after coord_flip

If you are familiar with the forcats package, fct_rev() is very handy for reversing factor levels while plotting, and the legend order / colour mappings can be reversed back easily to match the original version before flipping your coordinates:

library(forcats)
library(ggplot2)

# unflipped version
p1 <- ggplot(data = df,
aes(x = Group, y = Score, fill = Sub)) +
geom_col(position="dodge") #geom_col is equivalent to geom_bar(stat = "identity")

# flipped version
p2 <- ggplot(data = df,
aes(x = fct_rev(Group), y = Score, fill = fct_rev(Sub))) +
geom_col(position="dodge") +
coord_flip() +
scale_fill_viridis_d(breaks = rev, direction = -1)

gridExtra::grid.arrange(p1, p2, nrow = 1)

plot comparison

Coord_flip() changes ordering of bars within groups in grouped bar plot

One "hacky" way to do this is to set the position_dodge width to be a negative number. .9 is the default, so -.9 would create the same appearance but in reverse.

library(ggplot2)

all_Q <- structure(list(group = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"), correct_per = c(90.4761904761905, 100, 100,
87.5, 83.3333333333333, 90.9090909090909, 84.6153846153846, 87.5, 80.9523809523809, 88.6363636363636, 100, 70.8333333333333, 63.4146341463415, 76.7441860465116, 76.9230769230769, 62.5), nr_correct = c(38L, 44L, 26L, 21L, 35L, 40L, 22L, 21L, 34L, 39L, 26L, 17L, 26L, 33L, 20L, 15L), nr_incorrect = c(4L, 0L, 0L, 3L, 7L, 4L, 4L, 3L, 8L, 5L, 0L, 7L, 15L, 10L, 6L, 9L), length = c(42L, 44L, 26L, 24L, 42L, 44L, 26L, 24L, 42L, 44L, 26L, 24L, 41L, 43L, 26L, 24L), qid = c("8", "8", "8", "8", "9", "9", "9", "9", "10", "10", "10", "10", "11", "11", "11", "11")), .Names = c("group", "correct_per", "nr_correct", "nr_incorrect", "length", "qid"), row.names = c(NA,
-16L), class = c("tbl_df", "tbl", "data.frame"))

ggplot(all_Q, aes(x = qid, y = correct_per, fill = group)) +
geom_bar(stat = "identity", position = position_dodge(-.9)) +
scale_x_discrete(limits = as.character(11:8)) +
coord_flip()

Alterantively, you could reorder the levels of the factor, then reverse the legend.

all_Q$group <- factor(all_Q$group, levels = rev(levels(all_Q$group)))

ggplot(all_Q, aes(x = qid, y = correct_per, fill = group)) +
geom_bar(stat = "identity", position = "dodge") +
scale_x_discrete(limits = as.character(11:8)) +
coord_flip() +
guides(fill = guide_legend(reverse = TRUE))

Result:

Sample Image

In ggplot2 bar chart legend elements in wrong order and one player's bar colors are off

Try this

win_dfL %>%
ggplot(aes(x=Pitcher, y=Wins, fill=Season)) +
geom_bar(stat="identity", color="black", width = .85, position = position_stack(reverse = TRUE)) +
scale_fill_manual(values=c("#A0522D",
"#FAD5A5",
"red",
"white",
"gray",
"#C04000",
"#FF7518",
"yellow")) +
# Horizontal bar plot
coord_flip() +
guides(fill = guide_legend(override.aes = list(color = NA)))

Sample Image

position = position_stack(reverse = TRUE) within geom_bar reverses the color sequence, and guides(fill = guide_legend(override.aes = list(color = NA))) gets rid of the borders in the legend.

how to synchronise the legend the with order of the bars in ggplot2?

I have solved the issue with:
"

scale_fill_manual( values = cols,

guide = guide_legend(reverse = TRUE))

"

The plot itself is here:

plot_adjusted_rates <- ggplot2::ggplot(adj_comorb_forcats,
ggplot2::aes(comorbidities, age_standardise_rate_in_comorb, country)) +
ggplot2::coord_flip() +
ggplot2::geom_bar(ggplot2::aes(fill = country), width = 0.4,
position = position_dodge(width = 0.5), stat = "identity") +
ggplot2::scale_fill_manual( values = cols,

guide = guide_legend(reverse = TRUE)) +
ggplot2::labs(
x = "Pre-existing conditions", y = "Percentage") +
ggplot2::theme(axis.title.y = ggplot2::element_text(margin = ggplot2::margin(t = 0, r = 21, b = 0, l = 0)),
plot.title = ggplot2::element_text(size = 12, face = "bold"),
plot.subtitle = ggplot2::element_text(size = 10),
legend.position = "bottom" , legend.box = "horizontal") +
ggplot2::theme_bw()

plot_adjusted_rates

With the answer given above - I get my country variable with NA. Therefore, I believe it is better use the scale_fill_manual parameters given by ggplot2

And visual plot is right here:

Sample Image

As observed, the legend is in sync with bar charts colour.



Related Topics



Leave a reply



Submit