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 solution makes each group unique and arranges in the desired order, then changes the names back to your original names.
df_ex$names<-paste(df_ex$address,df_ex$clas,df_ex$No)
df_ex$names<-factor(df_ex$names,levels=c("A Good 1","B Ugly 1","C Ugly 1", "A Good 2", "C Bad 2", "B Ugly 2", "C Good 3", "A Bad 3", "B Bad 3"))
ggplot(df_ex, aes(x=names,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(breaks=df_ex$names, labels=df_ex$address)
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
<chr> <int> <fctr> <fctr>
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)) +