How to change the order of facet labels in ggplot (custom facet wrap labels)
Don't rely on the default ordering of levels imposed by factor()
or internally by ggplot
if the grouping variable you supply is not a factor. Set the levels explicitly yourself.
dat <- data.frame(x = runif(100), y = runif(100),
Group = gl(5, 20, labels = LETTERS[1:5]))
head(dat)
with(dat, levels(Group))
What if I want them in this arbitrary order?
set.seed(1)
with(dat, sample(levels(Group)))
To do this, set the levels the way you want them.
set.seed(1) # reset the seed so I get the random order form above
dat <- within(dat, Group <- factor(Group, levels = sample(levels(Group))))
with(dat, levels(Group))
Now we can use this to have the panels drawn in the order we want:
require(ggplot2)
p <- ggplot(dat, aes(x = x)) + geom_bar()
p + facet_wrap( ~ Group)
Which produces:
Reformat label / preserve order of Multi-factor facets in ggplot2::facet_wrap() based on factor level
Wow, that was a lot trickier than I expected... One solution would be to combine them into a different field:
tmp.d |>
arrange(sector, subsector) |> # arrange by factor levels
mutate(
facet =
paste0(sector, ": ", subsector) |>
fct_inorder(ordered = TRUE) # use that order for the new field
) |>
ggplot(aes(x = year, y = value, group = 1)) +
geom_path()+
facet_wrap(facets = ~facet) # here
This also works if a ", " is acceptable:
ggplot(tmp.d, aes(x = year, y = value, group = 1)) +
geom_path()+
facet_wrap(
facets = sector~subsector,
labeller =
labeller( # here
sector = label_value, #
subsector = label_value, #
.multi_line = FALSE #
)
)
A similar thing can be done with purrr::partial()
which substitutes out defaults but again you get a comma. I think it would be worth creating an issue on their github page to add a sep
argument to the label_*()
functions
... +
facet_wrap(
facets = sector~subsector,
labeller = purrr::partial(label_value, multi_line = FALSE)
)
How to change facet labels?
Change the underlying factor level names with something like:
# Using the Iris data
> i <- iris
> levels(i$Species)
[1] "setosa" "versicolor" "virginica"
> levels(i$Species) <- c("S", "Ve", "Vi")
> ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)
ggplot ordering facet labels by value
This is another approach inspired by the following github repository: https://github.com/dgrtwo/drlib/blob/master/R/reorder_within.R
You have to create the following functions, in order to manage facets' order:
reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
new_x <- paste(x, within, sep = sep)
stats::reorder(new_x, by, FUN = fun)
}
scale_x_reordered <- function(..., sep = "___") {
reg <- paste0(sep, ".+$")
ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}
then you may apply them on your data:
ggplot(mydata, aes(reorder_within(firstFactor, desc(value), secondFactor), value)) +
geom_bar(stat = 'identity') +
scale_x_reordered() +
facet_wrap(~ secondFactor, scales = "free_x",ncol=1) +
xlab("make")
and this is the result:
Fixing the order of facets in ggplot
Make your size a factor in your dataframe by:
temp$size_f = factor(temp$size, levels=c('50%','100%','150%','200%'))
Then change the facet_grid(.~size)
to facet_grid(.~size_f)
Then plot:
The graphs are now in the correct order.
R Changing Order of Facets
dfx$group <- factor(dfx$group, levels = c("SLG","BA"))
Related Topics
Why Is the Parallel Package Slower Than Just Using Apply
Select Groups Which Have At Least One of a Certain Value
How Does Predict.Lm() Compute Confidence Interval and Prediction Interval
Add Correct Century to Dates With Year Provided as "Year Without Century", %Y
Proper/Fastest Way to Reshape a Data.Table
Unique on a Dataframe With Only Selected Columns
Custom Sorting (Non-Alphabetical)
How to Format a Number as Percentage in R
How to Merge 2 Vectors Alternating Indexes
Filtering a Data Frame on a Vector
Create Sequence of Repeated Values, in Sequence
Increment by 1 For Every Change in Column
How to Delete Rows from a Dataframe That Contain N*Na