I\'d like to produce a facet_wrap where the order of factors within facets is based on the one of the column factor order. The heart of the problem is each group has duplica
This old question has already an accepted answer. But as it is being used as a dupe target, I feel obliged to suggest a slightly improved and more concise variant.
It's based on the recent enhancements of the ggplot2
package, namely the labels
parameter to scale_x_discrete()
, and Hadley's forcats
package released to CRAN in August 2016. The proposed solution enhances the accepted answer by using material from this answer.
df_ex
as provided by the OP needs to be modified to include a variable which guarantees an overall sort order across all facets:
library(dplyr) # version 0.5.0 used
df_ex <- df_ex %>% mutate(ordered = paste0(No, address) %>%
forcats::fct_inorder())
The additional column to df_ex
now looks as follows:
address No clas ordered
1 A 1 Good 1A
2 B 1 Ugly 1B
3 C 1 Ugly 1C
4 A 2 Good 2A
5 C 2 Bad 2C
6 B 2 Ugly 2B
7 C 3 Good 3C
8 A 3 Bad 3A
9 B 3 Bad 3B
As df_ex
already had been sorted in the desired order using arrange()
, fct_inorder()
returns the new column ordered
with the levels in the same order as their first appearance.
Instead of address
, ordered
is plotted on the x-axis. The parameter scales = "free_x"
to facet_wrap()
ensures that unused levels will be dropped from the facets. However, the labels on the x-axis need to be be replaced by supplying a named vector to the labels
parameter of scale_x_discrete()
.
library(ggplot2) # version 2.2.1 used
ggplot(df_ex, aes(x=ordered,y="",fill=clas)) + #x axis bias voltage dependence
geom_tile() +
scale_fill_manual(values=c('Good'="green","Bad"="Blue","Ugly"="black"))+
facet_wrap(~No,ncol=1,scales = "free_x")+
theme(legend.position = "top",axis.text.y = element_text(size = 20,angle = 90),axis.text.x = element_text(size=12,face="bold",colour = "black"),
axis.title.y = element_text(face="bold",size = 20, colour = "black"),
axis.title.x = element_text(face="bold",size = 20 , colour = "black"),
strip.text = element_text(size=26, face="bold"),
strip.background = element_rect(fill="#FFFF66", colour="black", size=0.5),
plot.title=element_text(face="bold",color="red",size=14),
legend.title = element_text(colour="black", size=26,face="bold"),
legend.text = element_text(colour="black", size=18))+
labs(x = "address",y = "") +
scale_x_discrete(labels = setNames(df_ex$address, df_ex$ord)) +