class: center, middle, inverse, title-slide # R 数据可视化 ## ggplot2 功能包 ### Chris Qi ### 2018 --- background-image: url(https://www.dropbox.com/s/zk8948u32y01sj8/logo.png?dl=1) background-size: 700px background-position: 50% 50% --- background-image: url(https://www.dropbox.com/s/zk8948u32y01sj8/logo.png?dl=1) background-size: 200px background-position: 95% 3% --- # 数据可视化进阶:ggplot2 ggplot2, R语言最为强大的作图软件包,没有之一 * 由Hadley Wickham于2005 年创建 * 经过多次优化改进, 现在成为最流行的数据可视化工具 --- # 层 (Layer) * data: 感兴趣的变量 (data frame) * Aesthetics: x-axis/ y-axis/ color/ fill/ size/ label/ alpha/ shape * Geometrics: point/ line/ histogram/ bar/ boxplot * Facets: columns/ rows * Statistics: binning/ smoothing/ descriptive/ inferential * Coordinates: cartesian/ fixed/ polar/ limits * Themes: non-data ink --- ggplot2 功能包的两大函数: -- * qplot() * 类似于base基本系统的plot, 参数包含了 aesthetics/ geom/ facets * 隐藏了绘图细节 -- * ggplot() * 是核心,可以实现qplot()无法实现的功能 * 调用ggplot()本身并不能实现绘图,要在其基础上添加层(如geom_point()) 才可以 --- ## qplot() quickly plotting 方法 使用`airquality`的数据,运用`qplot()`绘图: --- qplot():最基本的散点图 ```r library(ggplot2) qplot(Wind, Temp, data=airquality) ``` <!-- --> --- qplot(): 添加颜色,每个月一种颜色 ```r airquality$Month<-as.factor(airquality$Month) qplot(Wind, Temp, data=airquality, color=Month) ``` <!-- --> --- qplot():所有数据点统一为一种颜色 ```r qplot(Wind, Temp, data=airquality, color=I("red")) ``` <!-- --> --- qplot():改变数据点的形状,每个月份一种形状 ```r qplot(Wind, Temp, data=airquality, shape=Month) ``` <!-- --> --- qplot():改变数据点的大小,每个月份一种大小 ```r qplot(Wind, Temp, data=airquality, size=Month) ``` ``` ## Warning: Using size for a discrete variable is not advised. ``` <!-- --> --- qplot():统一大小 ```r qplot(Wind, Temp, data=airquality, size=I(3)) ``` <!-- --> --- 在qplot中,很多细节都有默认值,但是我们可以修改,例如: ```r qplot(Wind, Temp, data=airquality, size=I(1), xlab="wind (mph)", ylab="Temp", main="wind vs. temp") ``` <!-- --> --- 在当前的图上加入其他重要信息,几何客体:点,平滑 ```r qplot(Wind, Temp, data=airquality, geom = c("point", "smooth")) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 加上月份,会发生什么? ```r qplot(Wind, Temp, data=airquality,color=Month, geom = c("point", "smooth")) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 加入“面”这个参数 ```r qplot(Wind, Temp, data=airquality, facets = Month~.) ``` <!-- --> --- 换一下月份的位置,会发生什么? ```r qplot(Wind, Temp, data=airquality, facets = .~Month) ``` <!-- --> --- 只使用一个变量,qplot猜测我们想做柱状图 ```r qplot(airquality$Wind) ``` ``` ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` <!-- --> --- ```r qplot(Wind, data=airquality, facets = Month~.) ``` ``` ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` <!-- --> --- ```r qplot(Wind, data=airquality, fill=Month) ``` ``` ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` <!-- --> --- 指定几何客体为密度曲线(轮廓线) ```r qplot(Wind, data=airquality, geom="density") ``` <!-- --> --- 按月份画风速这一变量的密度曲线 ```r qplot(data=airquality, Wind, geom="density", color=Month) ``` <!-- --> --- ## ggplot() 为什么要使用ggplot() * 用户能在更抽象层面上控制图形,使创造性绘图更容易 * 采用图层的设计方式,有利于结构化思维 * 图形美观 --- ## ggplot() 的基本概念 * 数据(Data)和映射(Mapping) * 标度(Scale) * 几何对象(Geometric) * 统计变换(Statistics) * 坐标系统(Coordinate) * 图层(Layer) * 分面(Facet) --- ## aes() 美学映射 aes是aesthetic mapping的缩写,也即“美学映射”。文档里对aes是这么描述的: Generate aesthetic mappings that describe how variables in the data are mapped to visual properties (aesthetics) of geoms. 也就是aes是把数据映射到可见属性的函数,这些属性包括图像的横坐标,纵坐标,颜色,大小等。 将数据中的变量映射到图形美学属性。美学映射控制了二者之间的关系。 .center[] --- ## ggplot() 的基本概念 标度(Scale) 标度负责控制映射后图形属性的显示方式。具体形式 上来看是图例和坐标刻度。Scale和Mapping是紧密相 关的概念。 .center[] --- ## ggplot() 的基本概念 几何对象(Geometric) 几何对象代表我们在图中实际看到的图形元素,如点、 线、多边形等。 --- ## ggplot() 的基本概念 统计变换(statistics) 对原始数据进行某种计算,例如对二元散点图加上一 条回归线。 --- ## ggplot() 的基本概念 坐标系统(Coordinate) 坐标系统控制坐标轴幵影响所有图形元素,坐标轴可 以进行变换以满足不同的需要。 --- ## ggplot() 的基本概念 图层(Layer) 数据、映射、几何对象、统计变换等构成一个图层。 图层可以允许用户一步步的构建图形,方便单独对图 层进行修改。 --- ## ggplot() 的基本概念 分面(Facet) * 条件绘图,将数据按某种方式分组,然后分别绘图。 * 分面就是控制分组绘图的方法和排列形式。 --- ## ggplot() 的基本概念 小结: ggplot2的基本概念 * 数据(Data)和映射(Mapping) * 标度(Scale) * 几何对象(Geometric) * 统计变换(Statistics) * 坐标系统(Coordinate) * 图层(Layer) * 分面(Facet) --- ## 常用图形 * 散点图 * 直方图 * 箱(线)图 --- ```r str(mpg) ``` ``` ## Classes 'tbl_df', 'tbl' and 'data.frame': 234 obs. of 11 variables: ## $ manufacturer: chr "audi" "audi" "audi" "audi" ... ## $ model : chr "a4" "a4" "a4" "a4" ... ## $ displ : num 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ... ## $ year : int 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ... ## $ cyl : int 4 4 4 4 6 6 6 4 4 4 ... ## $ trans : chr "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ... ## $ drv : chr "f" "f" "f" "f" ... ## $ cty : int 18 21 20 21 16 18 18 18 16 20 ... ## $ hwy : int 29 29 31 30 26 26 27 26 25 28 ... ## $ fl : chr "p" "p" "p" "p" ... ## $ class : chr "compact" "compact" "compact" "compact" ... ``` --- 底层画布 ```r library(ggplot2) ggplot(data=mpg, mapping=aes(x=cty, y=hwy)) ``` <!-- --> --- 等价表达 ```r ggplot(mpg, aes(x=cty, y=hwy)) ``` <!-- --> --- 散点图 ```r ggplot(mpg, aes(x=cty, y=hwy)) + geom_point() ``` <!-- --> --- 将年份映射到颜色属性,将底层画布存储成p,方便后面引用: ```r p <- ggplot(mpg,aes(x=cty, y=hwy, colour=factor(year))) p + geom_point() ``` <!-- --> --- 增加平滑曲线 ```r p + geom_point() + stat_smooth() ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 用标度来修改颜色取值 ```r p + geom_point(aes(colour=factor(year)))+ stat_smooth()+ scale_color_manual(values =c('blue','red')) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 将排量映射到散点大小 ```r p + geom_point(aes(colour=factor(year),size=displ))+ stat_smooth()+ scale_color_manual(values =c('blue2','red4')) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 通过改变图形透明度和错位来展示数据密度,重合的点 ```r p + geom_point(aes(colour=factor(year),size=displ), alpha=0.5,position = "jitter") + stat_smooth()+ scale_color_manual(values =c('blue2','red4')) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 用坐标控制图形显示的范围 ```r p + geom_point(aes(colour=factor(year),size=displ), alpha=0.5,position = "jitter")+ stat_smooth()+ scale_color_manual(values =c('blue2','red4'))+ coord_cartesian(xlim = c(15, 25),ylim=c(15,40)) ``` ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 用坐标控制图形显示的范围, 按年份分面板显示 ```r p + geom_point(aes(colour=factor(year),size=displ), alpha=0.5,position = "jitter")+ stat_smooth()+ scale_color_manual(values =c('blue2','red4'))+ coord_cartesian(xlim = c(15, 25),ylim=c(15,40))+ facet_wrap(~ year,ncol=1) ``` --- 用坐标控制图形显示的范围, 按年份分面板显示 ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 添加标题,横轴与纵轴的说明 ```r p + geom_point(aes(colour=factor(year),size=displ), alpha=0.5,position = "jitter")+ stat_smooth()+ scale_color_manual(values =c('blue2','red4'))+ coord_cartesian(xlim = c(15, 25),ylim=c(15,40))+ facet_wrap(~ year,ncol=1)+ ggtitle("Miles Per Gallon of Different Displacements")+ xlab("mpg in city")+ ylab("mpg at highway") ``` --- 添加标题,横轴与纵轴的说明 ``` ## `geom_smooth()` using method = 'loess' and formula 'y ~ x' ``` <!-- --> --- 直方图(连续性变量) ```r p <- ggplot(mpg,aes(hwy)) p + geom_histogram() ``` ``` ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` <!-- --> --- 改进:边框和颜色 ```r p <- ggplot(mpg,aes(hwy)) p + geom_histogram(color="black", fill="red") ``` ``` ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` <!-- --> --- 调整直方的宽度 ```r p <- ggplot(mpg,aes(hwy)) p + geom_histogram(color="black", fill="red", binwidth=2) ``` <!-- --> --- 添加平均值的竖线 ```r p <- ggplot(mpg,aes(hwy)) p + geom_histogram(color="black", fill="red", binwidth=2)+ geom_vline(aes(xintercept=mean(hwy)), color="blue", linetype="dashed", size=1) ``` <!-- --> --- 根据年份修改直方图 ```r p <- ggplot(mpg,aes(hwy, color=factor(year))) p + geom_histogram(fill="white", binwidth=2) ``` <!-- --> --- 修改图例的位置 ```r p <- ggplot(mpg,aes(hwy, color=factor(year))) p + geom_histogram(fill="white", binwidth=2)+ theme(legend.position="top") ``` <!-- --> --- 条形图 (分类变量) ```r ggplot(mpg, aes(x=class))+ geom_bar() ``` <!-- --> --- 根据年份分别绘制条形图,position控制位置调整方式 ```r ggplot(mpg, aes(class,fill=factor(year)))+ geom_bar(position='identity',alpha=0.5) ``` <!-- --> --- 并立方式 ```r ggplot(mpg, aes(class,fill=factor(year)))+ geom_bar(position='dodge') ``` <!-- --> --- 叠加方式 ```r ggplot(mpg, aes(class,fill=factor(year)))+ geom_bar(position='stack') ``` <!-- --> --- 相对比例 ```r ggplot(mpg, aes(class,fill=factor(year)))+ geom_bar(position='fill') ``` <!-- --> --- 分面显示 ```r ggplot(mpg, aes(class,fill=class))+ geom_bar()+ facet_wrap(~year,ncol=1) ``` <!-- --> --- 箱线图 ```r ggplot(mpg, aes(class,hwy,fill=class)) + geom_boxplot() ``` <!-- --> --- 饼图 ```r ggplot(mpg, aes(x = factor(1), fill = factor(class))) + geom_bar(width = 1) + coord_polar(theta = "y") ``` <!-- --> --- 总结: * 有明确的起始(以ggplot函数开始)与终止(一句语句一幅图) * 图层之间的叠加是靠“+”号实现的,越后面其图层越高。 * ggplot2的核心理念是将绘图与数据分离,数据相关的绘图与数据无关的绘图分离 * ggplot2是按图层作图 * ggplot2保有命令式作图的调整函数,使其更具灵活性 * ggplot2将常见的统计变换融入到了绘图中。