ggplot2的逻辑

使用一个工具,要先了解其设计逻辑.
R graphics 像是画家一点一点画图,什么都要要自己设置。matplotlib把图形拆分为一个一个对象,通过设置的对象属性来画图, 这两个绘图逻辑都很容易理解。而ggplot2则更反应数据的本质。

ggplot2的中的gg是 <<grammar of graphics>>, 这本书描述了一种数据可视化的思想,把数据可视化为data, transformation, mapping,scale, guides, display 等步骤。ggplot2 是这种 数据可视化思想 的R实现。ggplot2 底层包是grid包,grid只提供低层次的绘图函数,是lattice,ggplot2高级绘图包的基础。

数据可视化 就是 从数据到图。我们从解剖数据和图开始

1.数据的维度 variable

ggplot2 绘图的数据须是data.frame 类。以mtcars为例
data.frame 数据是有维度的,每一列代表一个维度,我们这里把每一列称之为一个variable.


image.png
2. 图形的组成 轴

以常见的图为例

ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl))
ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=factor(cyl)))

image.png

这幅图对应了三个变量,mpg,wt,cyl,分别对应X轴,Y轴,和颜色bar,他们都对应一个连续变量。从"内涵"上说,他们都对应一个data.frame的一列,即“一个variable”.
"外形"上说,都有断点,断点都有label, 都有子的名字。
因此 颜色bar和X轴,Y轴是一样的,我们都把他们称为图形的"轴"。这里的轴就是ggplot2的aesthetics组件, 之所以此处称之为“轴”,是因为对初学者来说,aesthetics直译是“美学”,有些让人不知所云。
这副point图包括了三个轴,X轴,Y轴,颜色轴,每个轴都有自己的name,分别为mpg,wt,cyl,轴上都有breaks和对应的label, name,breaks,label 是轴的三个基本属性。
轴是图形的有效部分,承载了原data.frame的信息,是图形的“信息部分”。其他如背景线,标签位置,颜色调整等只是图形的修饰,并不承担信息。ggplot2的优点之一就是 只需要关注图形的信息部分,其他修饰有默认设置。

3.映射mapping(数据有维,图形有轴)

上图,每个轴实际上表示了一个dataframe的variable。mtcars的mpg信息完全反映在X轴,wt信息完全反映在y轴,cyl信息完全反映在颜色轴。
因此,数据有维,图形有轴,ggplot2的基本绘图思想,就是把data.frame的variable投射到图形的轴上。这个过程叫映射mapping。
继续以上图为例,我们来看颜色轴,cyl的信息完映射aes到了图形的颜色轴。
ggplot2对图形的轴有内置的默认设置,以color轴为例,对于point图,color轴默认有2个,一个连续的色带,一个是离散的点. aes(color=cyl)做的事情就是把 cyl信息 转变为color信息。
可以想象,在data.frame中cyl是连续变量,所以aes会把cyl信息映射到连续的色带,就是默认的蓝色色带。
这个过程很容易理解。对应好后,给色带指定break和label.

image.png

如果数据改变了,连续变量cyl多了一个9,那么9会对应到色带的最高点,4对应的颜色还是不变.
如果cyl是离散变量,那么就会按factor顺序对应到内置的离散颜色轴,这个轴只有8个颜色,随意如果变量factor有9个level,那么第9个level会和第1个level映射后的颜色相同。

4.geom 几何图形

geom是图形函数,指定了图形类型。如上geom_point 是声明画一个点图,那么就应该知道每个点的属性。geom_point的参数包括 x,y,color,shape,size,alpha等,这正是画点图所需要的每个点的属性,有了这些信息,geom_point就可以画出图形了。显然,在这几个参数中,x,y是必须的。
ggplot2在绘图前主要工作就是把variable转换成这些图形需要的轴。

p <- ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl))
p$data  ## 即原始绘图数据data.frame
dim(p$data)  ## 32行
g <- ggplot_build(p)  ## 查看stat后的信息。g$plot即为图形
stated <- g$data[[1]]  ## geom的绘图信息
dim(stated )  ## 32行

image.png

数据是这样的,原来的data.frame 数据aes后实际上变成了点图(geom_point)所需的信息,
如上图,这个数据实际上完全等价于图形,geom_point就是根据这个表达渲染出图形的。

5.geom的轴:aesthetic组件

所谓 aesthetics组件, 就是图形的“轴”, ggplot2中常用的有
颜色类:color(颜色或边框颜色)、fill(填充颜色)和alpha(透明度)
形状类:linetype(线型)、size(点的大小或线的宽度)和shape(形状)
位置类:x、y、xmin、xmax、ymin、ymax、xend、yend
分组:group
不同的geom有不同的轴。ggplot2是2d平面绘图,所以x,y是几乎对所有geom必须的.

6.stat+geom

每个geom同时也是一个stat(统计变换),这句话怎么理解呢?
以上画的点图,这个太容易理解,很直观,几乎不需要stat.我们看个略复杂点的。
继续以mtcats为例。geom_bar

dat<-mtcars
dat$cyl <- paste0("cyl",dat$cyl)
ggplot(dat)+geom_bar(aes(x =cyl))

image.png

然后就出了这个很粗糙的图,虽然粗糙,但是已经包含了所有需要的信息。geom_bar,我们先看下 ?geom_bar所需要的轴,在geom_bar的帮助文档中Aesthetics部分有x,y,alpha,color,fill,froup,linetype,size。实际上,我们要画个bar图,那么我们需要的信息是:多少个bar,每个bar的X轴位置,高度(Y轴位置),alpha,color,fill,froup,linetype,size信息。其中x,y是必须的,其他可以用默认值。
似乎有点不对,只是一个离散变量cyl映射到了x轴啊,y轴信息从哪来的,别急,这幅图的真实映射是这样的。
X轴对啥,是分类变量cyl的levle. 真实的x轴对应如分类 x= c("cyl4","cyl5","cyl6")
y轴是x轴每个level的count. 真实的Y轴对应连续变量 y=c(11,7,14)
其他aesthetics参数使用默认值,然后geom_bar就可以渲染出上图。
在这个从 x= cy l到 x=cyl的level, y=cyl的count, 中间需要有一个统计变换的,这部分工作是由stat完成的,也就是geom_bar的stat参数,geom_bar默认的是stat="count".
画不同的geom需要不同stat,对于多数geom来说,geom外观就已经决定了应该如何stat,所以多数geom只能对应一个stat.
ggplot2还把stat单独作为函数,也就是一系列stat函数,同样,stat后的信息就是画图所需要的data.frame信息,加上geom参数信息,就包括了渲染图形所需要的信息,就可以画图图形了。这是stat为什么也能画图的原因。上图图形的stat信息,3个bar的信息如下图。
image.png

7.aesthetic写在aes内与写在aes外

geom的aesthetic,如color,写在aes内和外

ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl)) ## 需要的图
ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color="blue") ##所有点红色
ggplot(mtcars)+geom_point(aes(x=mpg,y=wt),color="blue") ##所有点蓝色

我们来
上述第一句哈,是mtcars的cyl 映射到 color轴,可以得到正确的颜色。
第二句实际上是geom_point(mapping=aes(x=mpg,y=wt,color="blue"))。 'blue' 映射到color轴,'blue'实际上是从c('blue'),是个长度为1的字符串,离散型变量,所以映射函数会把从c('blue')映射到 离散型的默认color轴,第一个颜色是红色,所以所有点是红色。注意映射函数接受长度为1或者长度和x,y等长的vector.
第三句话,geom_point(mapping=aes(x=mpg,y=wt),color="blue")写在aes外,不需要经映射函数处理,在geom内,相当于给geom直接指定了'blue'颜色(上述stated数据的color列),'blue'是R内置的颜色。如果在上述geom_bar中,color可以接受长度为1或者3的vector.
所以可以在原data.frame加上一列color等,填充自己需要的颜色,然后不aes,就是对应的颜色。

结合6和7部分,你也可以自己stat原data.frame到 geom 需要的变量, 然后直接把这些变量不aes,赋予geom的轴,直接出图。

8.scale系列函数

还是以颜色轴为例,变量cyl映射为 一条 蓝色色带(geom_point默认),但是我不喜欢这条蓝色色带,我想使用别的颜色怎么办?这就需要scale.scale本身由“按比例”的意思。
scale是更改默认的轴,并重新建立映射关系。每个轴都有两种形式,离散的和连续的。
所以scale系类函数基本形式都是这样的
scale_aesthetics(轴)_discrete or continuous.
而形如scale_color_brewer只是scale_color_discrete的其中一种快捷函数。
所有的轴都有三个共同的参数,name,breaks,label.
修改轴的name是很常见的操作,所有有几个快捷函数。
labs(aesthetics=" newname")可以修改某个轴的名字
xlab("newname"),修改X轴名字,实际上是scale_x_discrete or continuous(name=""newname"")
同理,ggplot2中scale相关快捷函数有很多。
以下三种写法是一样的

ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl))+scale_color_continuous(name="newname")
ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl))+xlab("newname")
ggplot(mtcars)+geom_point(aes(x=mpg,y=wt,color=cyl))+labs(x='newname')

9 图层叠加

ggplot2的另一个强大之处是图层叠加。此处指信息载体的”geom_xxxx" 的叠加。但是这个时候应该注意的是ggplot2是2D绘图,不同的"geom_xxxx"至少要使用共同的x轴,y轴,有时还有使用共同的颜色轴等。这个时候要注意,后面的“geom__xxxx”的x,y轴会覆盖前面的“geom_xxxx”的x,y轴。这个在作图前要规划好。

综上ggplot2的强大之处在于其逻辑性,绘图时使我们能“关注数据”,而非图形细节。相比之选使用graphics,不得不把更多精力放在图形上,而非数据上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351