玩转数据可视化之R语言ggplot2

  • 🌸个人主页:JoJo的数据分析历险记
  • 📝个人介绍:小编大四统计在读,目前保研到统计学top3高校继续攻读统计研究生

本系列主要介绍R语言ggplot2的使用
参考资料:
ggplot2: Elegant Graphics for Data Analysis

文章目录

  • 玩转数据可视化之R语言ggplot2
  • 💘2.玩转数据可视化之R语言ggplot2:(二)实现分面画图(Faceting)
  • 💕2.1 Facet wrap
  • 💖2.2 Facet grid
  • 💗2.3 坐标轴刻度控制
  • 💙2.4 缺失数据分面
  • 💚2.5 分组和分面
  • 💜2.6 连续变量

💘2.玩转数据可视化之R语言ggplot2:(二)实现分面画图(Faceting)

# 加载库
library(ggplot2)

首先我们来看一个简单的分面案例,使用数据集mpg,按照class分面画displ和hwy的散点图,使用facet_wrap()函数进行分面,通过~来指定选择分面的变量

ggplot(mpg, aes(displ, hwy)) + 
geom_point() + 
  facet_wrap(~class)

r语言ggplot2中face r语言 facet_数据可视化

分面其实就是将数据集分为一部分子集,对每个子集进行绘图,并放在同一张图上。这在我们进行探索性数据分析时很有用,我们
可以分析不同图之间有什么相同点和不同点.faceting主要有以下三种方法

  • facet_null()
  • facet_wrap():对一个变量进行分面
  • facet_gird():分别从行和列对两个变量进行分面
    facet_wrap()和facet_grid()的区别如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9mf84za-1649326423002)(attachment:image.png)]

为了使得方便描述,我们在这里使用mpg的子集,cyl取值三个水平4,6,8.drv取值两个水平4,f.class不等于2seater的

mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4", "f") & class != "2seater")
head(mpg2)

A tibble: 6 × 11

manufacturer

model

displ

year

cyl

trans

drv

cty

hwy

fl

class

<chr>

<chr>

<dbl>

<int>

<int>

<chr>

<chr>

<int>

<int>

<chr>

<chr>

audi

a4

1.8

1999

4

auto(l5)

f

18

29

p

compact

audi

a4

1.8

1999

4

manual(m5)

f

21

29

p

compact

audi

a4

2.0

2008

4

manual(m6)

f

20

31

p

compact

audi

a4

2.0

2008

4

auto(av)

f

21

30

p

compact

audi

a4

2.8

1999

6

auto(l5)

f

16

26

p

compact

audi

a4

2.8

1999

6

manual(m5)

f

18

26

p

compact

💕2.1 Facet wrap

facet_wrap()绘制一系列图片在一张画布上。根据某一变量的不同取值进行绘制子图。
当某一单独的变量有不同水平时,我们研究不同水平下某些其他变量的关系,此时适合用face_wrap()
facet_warp主要有以下参数:

  • ncol和nrow,控制绘制几列几行的图,设置其中一个变量即可
  • as.table.是否像一个表一样显示图(最高值在右下角),false(最高值在右上角)
  • dir.控制绘图的方向,水平(h)还是纵向(v)
p <- ggplot(mpg2, aes(displ, hwy)) + 
  geom_blank() + #绘制空图
  xlab(NULL) + 
  ylab(NULL)
p + facet_wrap(~class, ncol = 3)
p + facet_wrap(~class, ncol = 3, as.table = FALSE)#默认是true

r语言ggplot2中face r语言 facet_r语言ggplot2中face_02

r语言ggplot2中face r语言 facet_数据_03

下面来看看dir参数

p + facet_wrap(~class, nrow = 3)
p + facet_wrap(~class, nrow = 3, dir = "v")

r语言ggplot2中face r语言 facet_数据_04

r语言ggplot2中face r语言 facet_数据可视化_05

💖2.2 Facet grid

facet_grid()是画一个二维的分面图,有两个变量进行分面

  • .~a是按列进行分面
  • b~.是按行进行分面
  • a~b按两个变量进行分面
    在这里就不再需要指定row和col了
p + facet_grid(. ~ cyl)
p + facet_grid(drv ~ .)

r语言ggplot2中face r语言 facet_数据_06

p + facet_grid(drv ~ cyl)

r语言ggplot2中face r语言 facet_坐标轴_07

💗2.3 坐标轴刻度控制

在facet_wrap()和facet_grid()中都可以设置是否共用坐标轴刻度,使用scales参数进行设置

  • scales = ‘fixed’:x和y轴坐标轴刻度都固定
  • scales = ‘free_x’:x坐标轴刻度根据数据可以变换
  • scales = ‘free_y’:y坐标轴刻度根据数据变化
  • scalse = ‘free’:x和y坐标轴都根据数据变化
    facet_grid()有一个额外的限制:在同一列的图x轴必须相同,在同一行的图y轴必须相同
p <- ggplot(mpg2, aes(cty, hwy)) + 
  geom_abline()+
geom_jitter(width = 0.1, height = 0.1) 
p + facet_wrap(~cyl)

r语言ggplot2中face r语言 facet_r语言ggplot2中face_08

p + facet_wrap(~cyl, scales = "free")

r语言ggplot2中face r语言 facet_数据可视化_09

当我们想在时间序列显示多个不同尺度的变量时,使用scales也很有效

# 如果不适用scale
ggplot(economics_long, aes(date, value)) + 
  geom_line() + 
  facet_wrap(~variable, ncol=1)

r语言ggplot2中face r语言 facet_坐标轴_10

从图中可以看出有些变量我们没办法得到具体随时间变化趋势

ggplot(economics_long, aes(date, value)) + 
  geom_line() + 
  facet_wrap(~variable, scales = "free_y",ncol=1)

r语言ggplot2中face r语言 facet_数据可视化_11

facet_grid()还有一个额外的参数是space,如果space为free,则每一个图的大小会根据其范围自动按比例调整
例如,图a的范围是0-2,图b的范围是0-4,那么在画图的时候,我们会分配1/3的空间给a,2/3的空间给b

head(mpg2)

A tibble: 6 × 11

manufacturer

model

displ

year

cyl

trans

drv

cty

hwy

fl

class

<fct>

<fct>

<dbl>

<int>

<int>

<chr>

<chr>

<int>

<int>

<chr>

<chr>

audi

a4

1.8

1999

4

auto(l5)

f

18

29

p

compact

audi

a4

1.8

1999

4

manual(m5)

f

21

29

p

compact

audi

a4

2.0

2008

4

manual(m6)

f

20

31

p

compact

audi

a4

2.0

2008

4

auto(av)

f

21

30

p

compact

audi

a4

2.8

1999

6

auto(l5)

f

16

26

p

compact

audi

a4

2.8

1999

6

manual(m5)

f

18

26

p

compact

# 根据cty排序
mpg2$model <- reorder(mpg2$model, mpg2$cty)#升序
mpg2$manufacturer <- reorder(mpg2$manufacturer, -mpg2$cty) # 降序
ggplot(mpg2, aes(cty, model)) + 
  geom_point() + 
 facet_grid(manufacturer ~ ., scales = "free",space='free')+
  theme(strip.text.y = element_text(angle = 0))

r语言ggplot2中face r语言 facet_r语言ggplot2中face_12

💙2.4 缺失数据分面

假设我们在分面的时候对多个数据集绘图,可能会出现某个数据集没有分面变量。这种情况发生时,ggplot默认将该数据集的数据在分面变量的每个值上都有。例如

df1 <- data.frame(x = 1:3, y = 1:3, gender = c("f", "f", "m"))
df2 <- data.frame(x = 2, y = 2)

ggplot(df1, aes(x, y)) + 
  geom_point(data = df2, colour = "red", size = 2) + 
  geom_point() + 
  facet_wrap(~gender)

r语言ggplot2中face r语言 facet_数据可视化_13

由于df2没有gender变量,因此df的值在gender的两个取值上都有值

💚2.5 分组和分面

分面方法是使用不同美学特征(例如颜色、大小、形状等)来区分不同组的另一种选择。两种方法各有优劣/
通过颜色大小来区分时,容易出现一些绘图重叠的部分,而使用分面的话,由于分面的每一部分都是数据集的一小部分,
因此不会出现重叠的问题。下面举例说明这两种方法

使用颜色来区分不同组

df <- data.frame(
  x = rnorm(120, c(0, 2, 4)),
  y = rnorm(120, c(1, 2, 1)),
  z = letters[1:3]
)

ggplot(df, aes(x, y)) + 
  geom_point(aes(colour = z))

r语言ggplot2中face r语言 facet_数据可视化_14

ggplot(df, aes(x, y)) + 
  geom_point() + 
  facet_wrap(~z)

r语言ggplot2中face r语言 facet_数据可视化_15

分面的一个优势是可以增加一些注释,例如我们可以在每个图中增加每一类的平均值,首先计算分组统计量
具体可以参考我的R语言数据分析专栏

# 计算分组统计量
library(dplyr)
df_sum <- df %>% 
  group_by(z) %>% 
  summarise(x = mean(x), y = mean(y)) %>%
  rename(z2 = z)


ggplot(df, aes(x, y)) + 
  geom_point() + 
  geom_point(data = df_sum, aes(colour = z2), size = 4) + 
  facet_wrap(~z)

r语言ggplot2中face r语言 facet_数据_16

另外一个有用的技巧是将所有数据都放到图中的背景

# 首先定义一个新数据集,删除z
df2 <- select(df, -z)
ggplot(df, aes(x, y)) + 
  geom_point(data = df2, colour = "grey70") +
  geom_point(aes(colour = z)) + 
  facet_wrap(~z,ncol=1)

r语言ggplot2中face r语言 facet_坐标轴_17

💜2.6 连续变量

如果要对连续变量进行分面,首先要做到是将其离散化。ggplot2提供了以下三种方法:

  • 将数据分为n个长度相同的桶:cut_interval(x,n)
  • 将数据分为若干桶,桶的宽度用width参数:cut_width(x,width)
  • 将数据分为n桶,每一桶包含的数据量相同:cut_number(x,n=i)
# 设置桶宽为1
mpg2$disp_w <- cut_width(mpg2$displ, 1)
# 分为六桶
mpg2$disp_i <- cut_interval(mpg2$displ, 6)
# 设置每个桶6个数据
mpg2$disp_n <- cut_number(mpg2$displ, 6)

plot <- ggplot(mpg2, aes(cty, hwy)) +
  geom_point() +
  labs(x = NULL, y = NULL)
plot + facet_wrap(~disp_w, nrow = 1)

r语言ggplot2中face r语言 facet_数据_18

plot + facet_wrap(~disp_i, nrow = 1)

r语言ggplot2中face r语言 facet_数据_19

plot + facet_wrap(~disp_n, nrow = 1)

r语言ggplot2中face r语言 facet_r语言ggplot2中face_20