ggplot2多图Panel 组合【facet_wrap() and facet_grid()】

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]就提供了极大的便利。
本文主要介绍:

  1. 根据一个变量分组展示
  2. 根据两个变量分组
  3. 更改head title空隙
  4. 更改head title位置
  5. 长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") 
image.png

接下来,根据性别,将一个图分成两个部分:

## 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~.)

image.png

其实跟按性别画两个柱状图一样。只不过上述是拆成两个部分了。

# 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") 

image.png

根据两个变量分组

那么我们再增加一个变量,看看效果。

## 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)

image.png

还可以增加到三个变量。

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
image.png

更改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))
  )

image.png

更改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")
image.png

image.png

长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)

image.png

这样需要用到 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)

image.png

关于设置y坐标参考比例,更改 facet_wrap的图出现的顺序及 facet_grid的设置,篇幅有效,下期再说。

参考

  1. How to Fit Long Text into Ggplot2 facet Titles
  2. Easy multi-panel plots in R using facet_wrap() and facet_grid() from ggplot2
  3. ggplot2 barplots : Quick start guide - R software and data visualization
  4. WHY YOU SHOULD MASTER THE SMALL MULTIPLE CHART
    5.Beautiful plotting in R: A ggplot2 cheatsheet

你可能感兴趣的:(ggplot2多图Panel 组合【facet_wrap() and facet_grid()】)