controlling order of facet_grid/facet_wrap in ggplot2?
I don't think I can really satisfy your "without making a new data frame" requirement, but you can create the new data frame on the fly:
ggplot(transform(iris,
Species=factor(Species,levels=c("virginica","setosa","versicolor")))) +
geom_histogram(aes(Petal.Width))+ facet_grid(Species~.)
or, in tidyverse idiom:
iris %>%
mutate(across(Species, factor, levels=c("virginica","setosa","versicolor"))) %>%
ggplot() +
geom_histogram(aes(Petal.Width))+
facet_grid(Species~.)
I agree it would be nice if there were another way to control this, but ggplot
is already a pretty powerful (and complicated) engine ...
Note that the order of (1) the rows in the data set is independent of the order of (2) the levels of the factor. #2 is what factor(...,levels=...)
changes, and what ggplot
looks at to determine the order of the facets. Doing #1 (sorting the rows of the data frame in a specified order) is an interesting challenge. I think I would actually achieve this by doing #2 first, and then using order()
or arrange()
to sort according to the numeric values of the factor:
neworder <- c("virginica","setosa","versicolor")
library(plyr) ## or dplyr (transform -> mutate)
iris2 <- arrange(transform(iris,
Species=factor(Species,levels=neworder)),Species)
I can't immediately see a quick way to do this without changing the order of the factor levels (you could do it and then reset the order of the factor levels accordingly).
In general, functions in R that depend on the order of levels of a categorical variable are based on factor level order, not the order of the rows in the dataset: the answer above applies more generally.
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"))
Is it possible to reorder only the facets of facet_wrap, without reordering the underlying factor levels?
Copy the data into a new column with the order you want. Use the new column for faceting, the old column for the the color.
df$facet = factor(df$Case, levels = c("L", "B", "R", "BC"))
ggplot(df, aes(x = x, y = y, color = Case)) +
geom_line() +
facet_wrap(~facet, nr = 2)
Ordering of ggplot2 facets changes after adding to a facet
The dataframe for the line, column drv must have same factor levels as original dataframe mpg2:
p + geom_hline(data = data.frame(xint = 20,
drv = factor("r", levels = levels(mpg2$drv))),
aes(yintercept = xint), linetype = "dotted", color = "blue")
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)
)
Order facet_wrap plots by descending order
You can reorder the factor levels of C
according to the values of B
(in descending order) using forcats::fct_reorder
or base reorder
inside the facet_wrap
:
library(tidyverse)
## data
M <- data.frame(
A = LETTERS[1:10],
B = round(rnorm(10,200,50)),
C = letters[15:24]
)
## using fct_reorder
ggplot(M, aes(x = A, y = B)) +
geom_bar(stat = "identity") +
facet_wrap(facets = ~fct_reorder(C, B, .desc = TRUE))
## using base reorder
ggplot(M, aes(x = A, y = B)) +
geom_bar(stat = "identity") +
facet_wrap(facets = ~reorder(C, -B)) ## -B to get descending order
Reordering plots when using facet_wrap and gather
Try reordering the levels of the factor you use for facetting:
df$key <- factor(df$key, levels=c("first facet", "second facet", (in the order you want the facets))
Note that this will be cleaner if you assign your gathered data frame to a variable, then reorder the facets, then call ggplot.
order a facet_grid or facet_wrap grid by modality in ggplot2
You can try using an interaction eg pasting both variables together.
library(tidyverse)
# Calculate the maximum on both values
gr <- my.df %>%
mutate(group=paste(use, es.type, sep="\n")) %>%
group_by(group) %>%
summarise(Max=sum(value)) %>%
arrange(-Max)
# Plot the data, but specifiying the order of the facets via
# the factor levels with respect to the order in `gr`.
my.df %>%
mutate(group=factor(paste(use, es.type, sep="\n"), levels=gr$group)) %>%
ggplot()+
geom_bar(aes(x = site, y = value, fill = site), stat="identity")+
facet_wrap(~group)+
theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank())
--
In base R you can do before plotting:
my.df$group <- paste(my.df$use, my.df$es.type, sep="\n")
gr <- aggregate(value ~ group, my.df, sum)
gr <- gr[order(gr$value, decreasing = T), ]
my.df$group <- factor(my.df$group, levels = gr$group)
Related Topics
In Ggplot2, What Do the End of the Boxplot Lines Represent
Case-Insensitive Search of a List in R
Combine Points with Lines with Ggplot2
Add a Box for the Na Values to the Ggplot Legend for a Continuous Map
Ordering of Points in R Lines Plot
Rle-Like Function That Catches "Run" of Adjacent Integers
Set One or More of Coefficients to a Specific Integer
For the Same Code, Labels (Q1, Median) Appear on One Computer But Don't Appear on Another Computer
Combined Plot of Ggplot2 (Not in a Single Plot), Using Par() or Layout() Function
Ggplot2: Color Individual Words in Title to Match Colors of Groups
Remove Empty Documents from Documenttermmatrix in R Topicmodels
How to Determine If You Have an Internet Connection in R
How to Determine the Namespace of a Function
Generate Correlated Random Numbers from Binomial Distributions
Efficiently Computing a Linear Combination of Data.Table Columns
Read and Rbind Multiple CSV Files
Is There an R Function to Reshape This Data from Long to Wide