这是全栈数据工程师养成攻略系列教程的第十四期:14 ggplot2 基本语法和基础图形。
上一节我们掌握了R的使用并安装了ggplot2,这一节让我们了解下ggplot2的基本语法以及一些常见图形的绘制方法。
图形种类
数据可视化使用形状、色彩、大小、透明度等视觉元素来表达数据,从而实现更直观生动的展示效果。常见的图形包括散点图、折线图、条形图、直方图、箱线图、密度图等,它们都反映了两个变量之间的关系,但表现的角度和场景都有所不同。
- 散点图反映的是两个连续变量之间的关系,例如一群人的身高和体重;
- 折线图反映的是一个连续变量随另一个连续变量的变化关系,例如一只股票的股价随时间的波动情况;
- 条形图反映的是一个连续变量在另一个离散变量不同水平下的值,例如不同年龄层的平均收入;
- 直方图反映的是一个连续变量在另一个连续变量不同区间范围下的值,例如一群人中身高处于各个区间段的人数;
- 箱线图反映的是一个连续变量在另一个离散变量不同水平下的分布,例如不同学历人群的收入分布;
- 密度图反映的是一个连续变量在另一个连续变量不同取值下的概率密度,例如不同收入人群所对应的密度。
总的来说,需要结合实际应用问题,弄清楚图形的x轴和y轴分别所表示的含义,以及x轴和y轴之间的关系,才能选出最适合表达的图形。
除了图形种类之外,图形所使用形状、颜色、填充色等元素也可以有丰富的选择。设计完以上内容后,还需要为图形添加合适的坐标轴标签、标题、图例等元素,只有恰当地结合好各方面内容,并且合理地表现出数据所蕴含的结论,才能最终称作一次成功的数据可视化。
基本语法
虽然Python中也有Matplotlib和Seaborn等绘图工具包,但要么绘图效果不够美观,要么语法不够简洁统一,或者绘图定制的灵活度不高。相比之下,ggplot2语法简单、格式一致,绘图样式多样可定制,并且绘图效果美观清爽。
使用ggplot2绘图遵循以下代码格式,data表示将要绘制图形的数据框,geom_type()
表示将要绘制的图形种类,type可以是point、bar、line、boxplot、histogram等,分别表示散点图、条形图、折线图、箱线图、直方图等。另外,需要在ggplot()
或geom_type()
完成绘图元素的映射aes()
,即将数据框的列和x轴、y轴、大小、颜色等元素对应起来。
ggplot(data) + geom_type()
以下代码同时使用了散点图和拟合线,即ggplot2遵循图层的概念,可以叠加任意数量的图层,从而基于一个或多个数据框绘制多种图形。aes()
如果提供在ggplot()
中则默认对后续全部图层生效,可以理解为全局配置;如果提供在geom_type()
函数中,则仅对该图层生效,可以理解为局部配置。
# 为了使用heightweight数据集而加载包
library(gcookbook)
ggplot(heightweight, aes(x=ageYear, y=heightIn, color=sex)) + geom_point() + geom_smooth()
条形图
使用geom_bar()
绘制条形图,这里以BOD
和cabbage_exp
两个数据集为例。
BOD
只有两列Time和demand,一共6行数据。以下代码将Time映射到x轴,将demand映射到y轴,以条形图展示不同Time所对应demand值。stat='identity'
表示y轴使用变量的实际值而不是频数,因为条形图的另一种使用场景是展示不同类别记录的数量,即类别值的出现频数,例如x轴表示男和女,y轴表示相应性别的人群数量。
ggplot(BOD) + geom_bar(aes(x=Time, y=demand), stat='identity')
我们会发现绘图结果中x=6
处存在一处空缺,因为ggplot2将Time这一列当作数值型来处理,因此缺少了Time为6的记录。可以在绘图时将Time这一列转化为因子类型,即可解决绘图空缺问题。
ggplot(BOD) + geom_bar(aes(x=factor(Time), y=demand), stat='identity')
cabbage_exp
是gcookbook
包提供的一个数据集,一共6行6列,可以在R中直接输入数据集的名称查看其内容。以下代码用条形图展示了cabbage_exp
中,Cultivar取不同值所对应的记录频数。这种情况下仅需指定x轴映射,无需提供y轴和stat='identity'
。
ggplot(cabbage_exp) + geom_bar(aes(x=Cultivar))
再来一个例子,x轴为Cultivar、y轴为Weight,并且将Date映射到填充色上。
ggplot(cabbage_exp) + geom_bar(aes(x=Cultivar, y=Weight, fill=Date), stat="identity")
使用position
参数可以绘制分组条形图。
ggplot(cabbage_exp) + geom_bar(aes(x=Cultivar, y=Weight, fill=Date), stat="identity", position="dodge")
折线图
有了条形图的基础,后续的图形理解起来也就更快了,以下代码使用BOD
数据集绘制折线图。
ggplot(BOD) + geom_line(aes(x=Time, y=demand))
# 同时绘制折线图和散点图
# 将aes()写在ggplot()里面,对后续全部图层都生效
ggplot(BOD, aes(x=Time, y=demand)) + geom_line() + geom_point()
以下代码使用uspopage
数据集绘制折线图,有Year、AgeGroup、Thousands三列,一共824行数据,因此反应的是每年不同年龄层的人口数量。
# 用line的color表示不同年龄层
ggplot(uspopage) + geom_line(aes(x=Year, y=Thousands, color=AgeGroup))
# 再来试试区域图,用area的fill表示不同年龄层
ggplot(uspopage) + geom_area(aes(x=Year, y=Thousands, fill=AgeGroup))
描述数据分布
可以使用直方图、密度图、箱线图等来描述数据分布,这些图中往往包含一些经过统计和计算之后的数据,而不像条形图、折线图、散点图一样仅使用原始数据。
使用geom_histogram()
、geom_density()
、geom_boxplot()
即可分别绘制直方图、密度图和箱线图,具体使用方法参见下一节中的实战项目。
分面
使用ggplot2绘图时,可以将数据框的列映射到shape、color、size、fill等绘图元素上,从而同时展示包括x轴、y轴在内的多个变量之间的关系。除此之外,也可以使用分面实现一图多画,例如对于gender为male和female的情况分别画一张图,甚至是对多个类别型变量的全部组合情况分别作图。
使用facet_wrap()
实现分面,这里给出一个简单的例子,将之前映射到填充色的AgeGroup作为分面变量,从而画出AgeGroup取不同水平时所对应的区域图。
ggplot(uspopage) + geom_area(aes(x=Year, y=Thousands)) + facet_wrap(~AgeGroup)
R数据可视化
以上介绍了ggplot2的基本语法和几种常见的基础图形,以及如何将数据框的列映射到图形的x轴、y轴、大小、颜色、填充色等绘图元素上。关于ggplot2的更多内容可以参考我的博客,http://zhanghonglun.cn/blog/tag/r/,以上链接以r
为标签搜索相关文章,搜索结果中会有一个《R数据可视化系列》,共11篇文章,可作为进一步学习ggplot2的参考资料。
视频链接:ggplot2基本语法和基础图形