ggplot2画分面图

来源:互联网 发布:ug8.5编程加工实战视频 编辑:程序博客网 时间:2024/06/05 20:29

参考自刘顺祥文章

分面是数据可视化最实用的技术之一,ggplot2通过facet_grid()和facet_wrap()函数将分组数据横向或纵向或横纵向排列,这样更有助于图形之间的比较。

上面提到facet_grid()和facet_wrap()函数可以实现可视化的分面,具体两种之间有什么区别呢?先上几幅图,通过形象的对比,就能记住两者之间的差异和用法。

一、绘制分面图

1、加载数据

#加载ggplot2包library(ggplot2)
## Warning: package 'ggplot2' was built under R version 3.2.3
#创建模拟数据集set.seed(1234)M <- c('一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月')Month <- rep(M, each=5)Region <- rep(c('East', 'South', 'West', 'North', 'Center'), times=12)Amount <- round(runif(n=60, min=500, max=5000))df <- data.frame(Month=Month, Region=Region, Amount=Amount)

2、用facet_grid()函数绘制横向或纵向分面图

#1)绘制横向的分面图ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_grid(.~Month) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

#2)绘制纵向分面图ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_grid(Month~.) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

3、从上的结果可知,图形很难看,重新构建一组数据以绘制纵向的分面图

#1)重新构建数据set.seed(1234)Year <- rep(seq(from=2001, to=2015), times=4)Type <- rep(c("A", "B", "C", "D"), each=15)Value <- round(runif(60, min=10, max=100))df2 <- data.frame(Year=Year, Type=Type, Value=Value)#2)绘制纵向分面图ggplot(df2, mapping = aes(x=factor(Year), y=Value, group=1)) +  geom_line(colour="blue") + xlab("Year") + facet_grid(Type~.)

4、使用facet_wrap()函数绘制分面图:

#绘制横向的分面图ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_wrap(.~Month) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())
## Error in layout_base(data, vars, drop = drop): At least one layer must contain all variables used for facetting

Error in layout_base(data, vars, drop = drop) : At least one layer must contain all variables used for facetting。经查帮助,facet_wrap()函数的语法不能写成.~ Month格式!

#修改程序格式ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_wrap(~Month) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

从上可知:运行成功!然后,绘制纵向分面图

ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_wrap(Month~) + theme(axis.text.x=element_blank(), axix.ticks.x=element_blank())

又一次报错!报错内容为:语法中存在错误的’)‘。查看帮助后发现:使用facet_wrap()函数不能使用Month 语法,只能是类似于a + b或(’a’,‘b’)的形式

总结:facet_grid()和facet_wrap()函数的区别 1)facet_grid()函数会严格按照用户指定的方向分面,即横向分面必须是.x的格式,纵向分面必须是y.的格式,当然也可以y~x表示纵横两个维度的方向进行分面绘图;facet_wrap()函数不存在横向或纵向或横纵向的分面,其实他就像按照从左到右,从上到下的顺序摆放每一个分面图。

2)语法上有显著的区别,facet_grid()函数必须是y.或.x或yx的格式,而facet_wrap()函数只能是x的格式,与之等价的是加引号的分面变量名称,即’x’。

3)上面的图形中,没有展现出来,其实facet_wrap()函数可以自由排版分面行方向的个数和列方向的个数,通过nrow=和ncol=参数实现,而facet_grid()函数只能是一根筋的下来,即要么全在行方向上,要么全在列方向上,要么就在组合方向上。

5、facet_wrap()函数指定列数的分面图例子

ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_wrap(~Month, ncol=3) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

上图可知,我们控制了列数为3的分面图,当然根据实际情况,也可以随意的设置其他列数或行数。

重新定义字符变量的因子顺序:善于发现问题的朋友,一定迫不可待的问一个问题,分面图按月份绘制的话,为什么月份不是正常的“一月”到“十二月”的顺序呢?而是按照拼音的字母顺序排列。如果我想按照自定义的顺序展现我的分面图该如何操作呢?很简单,只需要从新定义字符变量的因子顺序即可:

df$Month <- factor(df$Month, levels=c('一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'))#通过facet_wrap()函数绘制分面图:按照月份的顺序绘图ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_wrap(~Month, ncol=3) +  theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

#通过facet_grid()函数绘制分面图:按照月份的顺序绘图ggplot(data=df, mapping = aes(x=Region, y=Amount, fill=Region)) +  geom_bar(stat="identity") + facet_grid(.~Month) + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank())

二、分面图的微调

关于分面图的微调,这里就说明三项常用的微调手段

1、非固定的坐标轴

set.seed(1234)height <- c(runif(100, min=60, max=195), runif(80, min=45, max=175))weight <- 1.2*height + rnorm(180, mean=10, sd=20)sex <- rep(c("M", "F"), times=c(100, 80))df3 <- data.frame(sex=sex, heigth=height, weight=weight)ggplot(data=df3, mapping = aes(x=height, y=weight)) +   geom_point(colour="blue", size=3) + facet_grid(.~sex)

让分面图横坐标轴的范围随实际数据大小进行调整:默认情况下,分面图的纵坐标和横坐标的范围是一致的

ggplot(data=df3, mapping = aes(x=height, y=weight)) + geom_point(colour="blue", size=3) + facet_grid(.~sex, scales = "free_x")

图形结果很明显,女性(F)与男性(M)的横坐标范围各不相同,男性的范围要比女性大一些。这里需要强调的是,横向分面只能控制各自的x轴是否自由设定,纵向分面只能控制各自的y轴是否自由设定,纵横交错的分面可以同时设定两轴是否自由。

2、修改分面的文本标签

分面图形的默认情况下只显示分组变量的水平,即F和M,一个陌生人可能并不知道F和M各代表什么含义,如果能够把相应的分组变量名称也加入进来就更能提高可读性,下面通过修改一点点的脚本就能实现这样的功能:

ggplot(data=df3,  mapping = aes(x=height, y=weight)) + geom_point(colour="blue", size=3) + facet_grid(.~sex, labeller = label_both, scales = "free_x")

只需将设置labeller = label_both就可以实现功能,如果你还觉得这样做不够清晰,我还想把F和M改为Female和Male,该怎么办呢?同样很简单,只需要更改原数据中水平的标签即可。

levels(df3$sex)[levels(df3$sex)=="F"] <- "Female"levels(df3$sex)[levels(df3$sex)=="M"] <- "Male"ggplot(data=df3,  mapping = aes(x=height, y=weight)) + geom_point(colour="blue", size=3) + facet_grid(.~sex, labeller = label_both, scales = "free_x")

3、修改分面标签外观

通常修改图形的外观都是通过主题theme()函数实现,毫不例外,这里也使用主题函数对分面标签外观进行修改。

ggplot(data=df3, mapping = aes(x=height, y=weight)) + geom_point(colour="blue", size=3) + facet_grid(.~sex, labeller = label_both, scales="free_x") + theme(strip.text=element_text(colour = "red", face="bold", size=rel(1.5)), strip.background=element_rect(fill="white", colour = "brown", size=rel(2), linetype = 1))

其中,参数strip.text设置分面标签的颜色、大小、字体等;参数strip.background设置分面标签背景的填充色、线框色、线型等;rel()设置字体大小或线宽为原主题的倍数。

RMarkdown文件脚本下载链接:http://pan.baidu.com/s/1o73W3kY

参考资料:http://mp.weixin.qq.com/s?__biz=MzIxNjA2ODUzNg==&mid=403104773&idx=1&sn=202868d9603006235d7928da370e7f82#rd

0 0