ggplot2多图Panel 组合【facet_wrap() and facet_grid()】
今天就说下ggplot在绘制多图时候的一些骚操作。R里面的ggplot绘图很强大,有时候一张图可能满足不了我们的需求,需要分组展示,同时放在同一个Panel内。这时候ggplot里面的(facet_wrap() and facet_grid()
)[https://www.r-graph-gallery.com/ggplot2-package.html]就提供了极大的便利。
本文主要介绍:
- 根据一个变量分组展示
- 根据两个变量分组
- 更改head title空隙
- 更改head title位置
- 长head title处理
以ISLR
中的Credit
数据集为例子,展示,如何进行facet_wrap() and facet_grid()
绘制多图放在同一Panel。
根据一个变量分组展示
首先预览一下Credit
数据有哪些变量,然后我们利用Age
进行分组,产生新变量用于绘制条形图。
library(tidyverse)
library(ISLR)
rm(list = ls())
data("Credit")
head(Credit)
ID Income Limit Rating Cards Age Education Gender Student Married Ethnicity Balance
1 1 14.891 3606 283 2 34 11 Male No Yes Caucasian 333
2 2 106.025 6645 483 3 82 15 Female Yes Yes Asian 903
3 3 104.593 7075 514 4 71 11 Male No No Asian 580
4 4 148.924 9504 681 3 36 11 Female No No Asian 964
5 5 55.882 4897 357 2 68 16 Male No Yes Caucasian 331
6 6 80.180 8047 569 4 77 10 Male No No Caucasian 1151
我们首先绘制不同年龄组的收入水平。
## age group
Credit=Credit %>%
mutate(Age_group=cut(Age,
breaks = c(0,20,40,60,80,Inf),
labels = c("0-20","20-40","40-60","60-80",">80")))
## plot
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = "(split age into 4 groups)",
y = "Income", x = "Age",fill="Age Group")
接下来,根据性别,将一个图分成两个部分:
## plot one fig by gender
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = "(split age into 4 groups)",
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(Gender~.)
其实跟按性别画两个柱状图一样。只不过上述是拆成两个部分了。
# plot with gender in one figure
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Gender),stat="identity",position = position_dodge())+
labs(title = "The Incomes in different age group",
subtitle = "(split age into 4 groups)",
y = "Income", x = "Age",fill="Gender")
根据两个变量分组
那么我们再增加一个变量,看看效果。
## plot one fig by gender+Ethnicity
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = "(Gender+Ethnicity)",
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~Gender+Ethnicity)
还可以增加到三个变量。
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = "(Gender+Ethnicity+Married)",
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~Gender+Ethnicity+Married)->p2
p2
更改head title空隙
上述增加两个或三个变量时候,就出现了问题,每个Panel的标题占位太大,挡住了图形显示。
所以需要调整head title空隙。
## plot one fig by gender+Ethnicity+Married
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = "Margins between text on the strip",
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~Gender+Ethnicity+Married)+
theme(
strip.text.x = element_text(margin = margin(0, 0, 0, 0))
)
更改head title位置
也可以根据需要,将head title放在底部,右边,左边。这时候需要增加一个参数:strip.position = "bottom"
## plot one fig by gender
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = 'strip.position = "right"',
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~Gender+Married, strip.position = "right")
## plot one fig by gender
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = 'strip.position="bottom"',
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~Gender, strip.position="bottom")
长head title处理
有时候,会出现facet_wrap
分图的变量名字很长,这时候,不管放在哪里他都是看不见全称的。
我们新建一个year、变量里面包含很长的名字。
Year=c("This is a very long variable name This is a very","This is another really long veriable name a really long","THis is a shorter name","Short name","This is also a long variable name again","Short name","Short name","Another kind of long variable name")
Credit=Credit %>% as.tbl() %>%
mutate(year=rep(Year,50))
# plot with year
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = 'title too long"',
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~year)
这样需要用到 stringr::str_wrap().
参数。
# Helper function for string wrapping.
# Default 20 character target width.
swr = function(string, nwrap=20) {
paste(strwrap(string, width=nwrap), collapse="\n")
}
swr = Vectorize(swr)
# Create line breaks in Year
Credit$year = swr(Credit$year)
# plot with year
ggplot(Credit)+
geom_bar(aes(x=Age_group,y=Income,fill=Age_group),stat="identity")+
labs(title = "The Incomes in different age group",
subtitle = 'title too long"',
y = "Income", x = "Age",fill="Age Group") +
facet_wrap(~year)
关于设置y坐标参考比例,更改 facet_wrap的图出现的顺序及 facet_grid的设置,篇幅有效,下期再说。
参考
- How to Fit Long Text into Ggplot2 facet Titles
- Easy multi-panel plots in R using facet_wrap() and facet_grid() from ggplot2
- ggplot2 barplots : Quick start guide - R software and data visualization
- WHY YOU SHOULD MASTER THE SMALL MULTIPLE CHART
5.Beautiful plotting in R: A ggplot2 cheatsheet