You Yang

我们趋行在人生这个亘古的旅途,在坎坷中奔跑,在挫折里涅槃,忧愁缠满全身,痛苦飘洒一地。我们累,却无从止歇;我们苦,却无法回避。——《百年孤独》

ggplot2绘图艺术-1-如何买车?

我们在科研时候,经常需要绘制图像。 ggplot2 (R 语言)是绘图利器。之前仅仅是会应用,不能真正科学、系统地根据需要绘图。本系列文目的是全面细致地学习 ggplot2 的绘图思想和体系。

由于笔者认为R语言术语翻译后,经常会造成不必要的语义困惑,因此部分内容笔者会使用英语。

Key components

Every ggplot2 plot has three key components:

  • data
  • aesthetic mappings
  • at least one layer ( usually created with a geom function)

MPG

It includes information about the fuel economy of popular car models in 1999 and 2008, collected by the US Environmental Protection Agency, http://fueleconomy.gov.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> mpg
# A tibble: 234 x 11
manufacturer model displ year cyl trans drv cty hwy
<chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
1 audi a4 1.8 1999 4 auto~ f 18 29
2 audi a4 1.8 1999 4 manu~ f 21 29
3 audi a4 2 2008 4 manu~ f 20 31
4 audi a4 2 2008 4 auto~ f 21 30
5 audi a4 2.8 1999 6 auto~ f 16 26
6 audi a4 2.8 1999 6 manu~ f 18 26
7 audi a4 3.1 2008 6 auto~ f 18 27
8 audi a4 q~ 1.8 1999 4 manu~ 4 18 26
9 audi a4 q~ 1.8 1999 4 auto~ 4 16 25
10 audi a4 q~ 2 2008 4 manu~ 4 20 28
# ... with 224 more rows, and 2 more variables: fl <chr>,
# class <chr>
标签 释义(英) 释义(中)
displ engine displacement in litres 发动机排量
cty & hty miles per gallon (mpg) for city and highway driving 每加仑可走英里
drv front wheel (f), rear wheel (r) or four wheel (4) 驱动方式
class categorical variable describing the “type” of car: two seater, SUV, compact, etc 双座、suv、紧凑型
cyl the number of cylinders 气缸数

散点图

散点图是最基本的图。

理解 data, mapping, layer

我们来举一个简单的例子,为的是更好的理解 ggplot2 的绘图思想,以及我们应该秉着什么原则去绘图。

1
2
ggplot(mpg, aes(x = displ, y = hwy)) +  # x、y可以省略
geom_point()

point-1

  • Data : mpg

  • Aesthetic mapping : x ~ engine size(displacement 排量等同与发动机大小) y ~ fuel economy(一定燃油可以行驶的距离)

  • Layer : points

当我们理解了三要素是如何被安插的,利用这个思想,我们可以画出任何我们想得到的图形。请注意+,我们利用它来进行 Layer 和 mapping 的组合。

关于代码风格, Hadley 的代码风格应当是学习的典范:每个 command 尽量在新的一行(+后面另起一行)。

现在我们可以看出,

  1. 在高速公路上,排量越大的车它的燃油经济性就越低
  2. 但是也会发现,有些大排量汽车,它的经济效益依然很高

Color, size , shape and aes

要想探究第二条结论,我们要修缮一下 aes()

我们把上述代码改成aes(displ, hwy, colour = class)

color也可以变成 shape 、size

这里我们要说明一下,每个 aesthetic mapping 都有一个 scale 来负责创建坐标轴、标记等。我们这里只是先让大家了解思维,并非探究细节,scale 在后面我会慢慢讲解。

point-2-color

发现紧凑型车更省钱! SUV 属实是耗油巨兽,怪不得大G买得起养不起。。。

现在我们知道了,大排量、SUV 在燃油经济性上较差,小排量、经济性在燃油经济性较好。

Faceting

也许你是个刚刚接触作图的大学生,希望把所有炫技的操作都整合到一个图上,笔者当年也是如此。我们要知道图是为了更好的理解数据。

因此 aesthetics mapping 并非越多越好, less is usually more。假如我们使用了太多的mapping 你会很难找到变量之间的关系。

例如这个图:

point-3-toomuch

这是一个过于糟糕的图,永远不建议我们这样绘图。但是既然画了,让我们从中发现一些东西,别忘记我们还要买车。

  • font (前驱车)最省油,随后是 rear (后驱),最后是四驱(大部分是吉普和 SUV )。
  • cylinder 越多越费油

我们没法在一段时间做好许多事情,做好一件事情就是成功。我们不知道如何去表达很多信息时候,那么唯一良好的做法就是一步步来。ggplot2 给我们的方法是使用faceting。用一系列图片让一个阅读者从无知到熟悉,这就是绘图的艺术。

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

post-4-facetingClass

我们能看到基本分为3个梯度。从省油到不省油顺序基本是紧凑型、中级大小和两座、卡车和 SUV 。faceting的使用让我们一目了然。当一个图表达不了,我们是就多画几个图。

geom:添加一个 smooth

smooth 可以做一个拟合曲线,有不同的方法

method = gam / lm / rlm

span = 1 区间的宽度

  • gam是广义相加模型

  • lm是直线模型

  • rlm 类似 lm 但使用了一个健壮的拟合算法,这样离群值就不会对拟合产生太大影响。

1
2
3
ggplot(mpg, aes(displ, hwy)) +
geom_point( ) +
geom_smooth(method = "gam")

point-5-gam

这里是用 gam 做的广义加性模型,随着排量的增大,燃油经济性明显的降低,虽然我们早就得知了这个结论,现在更明确了,(好像没什么p用),但到了更高的地方,反而会出现上升的趋势,可能是因为离群值的原因。

假如使用 rlm 的方法,就可以看出明显是下降的趋势,并没有向上的趋势。

Distribution 三兄贵

geom_jitter()

抖动点图,添加了一些随机噪音点,为了避免偶然性(这里不知道如何翻译,原文是“adds a little random noise to the data which can help avoid overplotting”)

1
2
3
4
5
6
ggplot(mpg, aes(drv, hwy)) + 
# jitter 和 point 的参数基本完全一样
geom_jitter(color = '#2878B5', # 深蓝色
size = 3.5, # 点大小
alpha = 0.5, # 透明度
width = 0.30) # 间距

point-6-jitter

geom_boxplot()箱线图,有5个特征值

1
2
3
ggplot(mpg, aes(drv, hwy)) + 
geom_boxplot(color = '#FA7F6F', # color 是箱线图outline的颜色
fill = '#82B0D2') # fill 是内部颜色

point-7-boxplot

个人认为 color 使用默认就好,而 fill 可以使用一些低饱和度的配色。(没错,就是喜欢蓝色)

geom_violin() 小提琴图,与箱线图一样

point-8-violin

让我们观察一下,得出的结论与我们常规认识是一致的。

注:要想提取 mpg 数据集的 drv 这一列,使用mpg[,6]

  • 前驱车大部分最经济,而且前驱车经济性大致成正态分布.
  • 四驱车大部分是最耗油的,但是有两个“肚子”,有小部分四驱车经济性可以与前驱车持平
  • 后驱车处于中间地位,且耗油呈分布均匀态势

Histogram,freqpoly and bar

histogram 和 freqpoly 是同一类图,我们需要注意的是 bar 和 histogram 的差别,前者横坐标是离散型、后者横坐标是连续型。不要太多介绍,有需要请查阅文献。

Histogram show the distribution of continuous(连续型) variables

Bar shows the distribution of categorical(离散型) variables

这里举个书上的例子,例子的目的不是为了画柱状图,而是强调 faceting 的应用,请务必牢记它的作用

1
2
3
4
5
6
ggplot(mpg, aes(displ, fill = drv)) + 
# fill 是填色,color 是线的颜色
# 如果想设定具体颜色,要调用 scale 后面会讲到
geom_histogram(binwidth = 0.5) +
facet_wrap(~drv, ncol = 1)
# ncol = 1 代表从上到下排列图,假如不写默认是从左到右

point-9-his&facet

我们了解了 ggplot2 画图的基本逻辑,重点是三要素的整合,后续我们会学到关于 scale 的调用。

真正应用时候数据是千奇百怪的。绘图要表达什么?如何表达出来?这是我们后面要学习的内容,千万不能止步于本文。

回到最初那个问题,其实mpg还能分析很多问题,我们仅仅对于省油这一问题进行了讨论。

我们最后发现:买车要想省油钱,就买紧凑型前驱车!