更改 ggplot 方面的因素顺序
Change order of factors within ggplot facets
我正在尝试使用 facet_grid()
绘制多个图,我希望每个方面都有一个不同因子水平的子集,以手动顺序沿 X-axis 绘制。
基本上我想在每个 X 轴上绘制前 5 个国家(手动定义),我可以使用 grid.arrange()
的替代解决方案(参见示例),但我想用 facet_grid()
或 facet_wrap()
以保持与我的其他情节相同的美学。
我可以找到一些按因子级别对方面进行排序的答案,我尝试使用顺序美学,但没有成功,所以我想知道是否有办法做这样的事情,即使我知道ggplot 中的分面设计时并未考虑修改轴。我将不胜感激对此的一些建议。
这是我想要的可重现示例(在 X-axes 上手动定义顺序)。
library(reshape)
library(ggplot2)
library(gridExtra)
# Load data
mtcars_melt <- melt(mtcars)
# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")
# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))
# Make plots
plot1 <- ggplot(set1, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot2 <- ggplot(set2, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot3 <- ggplot(set3, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
grid.arrange(plot1, plot2, plot3, ncol = 3)
这里是情节的例子:
令人反感的黑客怎么样?
这会将您的子集组合成一个新的 dataframe
。然后添加一列,将集合编号与变量连接起来,以使每个变量都是唯一的。问题是,这会影响您的 x 轴名称,因为它们是串联的名称。为了解决这个问题,我按照这个 hack R: Reorder facet_wrapped x-axis with free_x in ggplot2 删除了轴名称并改用 geom_text
。
mtcars_melt <- melt(mtcars)
# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")
# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))
names(set1)[2]<-"set1"
names(set2)[2]<-"set2"
names(set3)[2]<-"set3"
mset1<-melt(set1)
mset2<-melt(set2)
mset3<-melt(set3)
library(data.table)
new<-as.data.frame(rbindlist(list(mset1,mset2,mset3)))
names(new)[2]<-'setno'
new$lvl <- with(new,paste(variable,setno,sep="."))
new$lvl<-as.factor(new$lvl)
new$lvl<-factor(new$lvl,levels=c("mpg.set1","wt.set1","qsec.set1","mpg.set2","gear.set2","cyl.set2", "vs.set3" , "mpg.set3","drat.set3" ))
plot1 <- ggplot(new, aes(x = lvl, y = value)) + ylim(0, 35) + geom_boxplot()+
facet_wrap(~setno,scales="free_x")+
ylim(-2,NA)+
geom_text(aes(y=-1,label=variable),angle=45,size=5,hjust=1)+
theme(axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.line.x = element_blank(),
axis.ticks.x = element_blank())+
geom_hline(aes(yintercept=0))
我正在尝试使用 facet_grid()
绘制多个图,我希望每个方面都有一个不同因子水平的子集,以手动顺序沿 X-axis 绘制。
基本上我想在每个 X 轴上绘制前 5 个国家(手动定义),我可以使用 grid.arrange()
的替代解决方案(参见示例),但我想用 facet_grid()
或 facet_wrap()
以保持与我的其他情节相同的美学。
我可以找到一些按因子级别对方面进行排序的答案,我尝试使用顺序美学,但没有成功,所以我想知道是否有办法做这样的事情,即使我知道ggplot 中的分面设计时并未考虑修改轴。我将不胜感激对此的一些建议。
这是我想要的可重现示例(在 X-axes 上手动定义顺序)。
library(reshape)
library(ggplot2)
library(gridExtra)
# Load data
mtcars_melt <- melt(mtcars)
# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")
# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))
# Make plots
plot1 <- ggplot(set1, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot2 <- ggplot(set2, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot3 <- ggplot(set3, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
grid.arrange(plot1, plot2, plot3, ncol = 3)
这里是情节的例子:
令人反感的黑客怎么样?
这会将您的子集组合成一个新的 dataframe
。然后添加一列,将集合编号与变量连接起来,以使每个变量都是唯一的。问题是,这会影响您的 x 轴名称,因为它们是串联的名称。为了解决这个问题,我按照这个 hack R: Reorder facet_wrapped x-axis with free_x in ggplot2 删除了轴名称并改用 geom_text
。
mtcars_melt <- melt(mtcars)
# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")
# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))
names(set1)[2]<-"set1"
names(set2)[2]<-"set2"
names(set3)[2]<-"set3"
mset1<-melt(set1)
mset2<-melt(set2)
mset3<-melt(set3)
library(data.table)
new<-as.data.frame(rbindlist(list(mset1,mset2,mset3)))
names(new)[2]<-'setno'
new$lvl <- with(new,paste(variable,setno,sep="."))
new$lvl<-as.factor(new$lvl)
new$lvl<-factor(new$lvl,levels=c("mpg.set1","wt.set1","qsec.set1","mpg.set2","gear.set2","cyl.set2", "vs.set3" , "mpg.set3","drat.set3" ))
plot1 <- ggplot(new, aes(x = lvl, y = value)) + ylim(0, 35) + geom_boxplot()+
facet_wrap(~setno,scales="free_x")+
ylim(-2,NA)+
geom_text(aes(y=-1,label=variable),angle=45,size=5,hjust=1)+
theme(axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.line.x = element_blank(),
axis.ticks.x = element_blank())+
geom_hline(aes(yintercept=0))