一.基本概念
"一张统计图形就是从数据到几何对象(geometric object, 缩写为geom, 包括点、线、条形等)的图形属性(aesthetic attributes, 缩写为aes, 包括颜色、形状、大小等)的一个映射。此外, 图形中还可能包含数据的统计变换(statistical transformation, 缩写为stats), 最后绘制在某个特定的坐标系(coordinate system, 缩写为coord)中, 而分面(facet, 指将绘图窗口划分为若干个子窗口)则可以用来生成数据中不同子集的图形。" 源自ggplot2的作者[Hadley Wickham]。
1.数据data和映射mapping
将数据中的变量映射到图形属性,映射控制了两者之间关系。
2.标度scale
标度负责控制映射后图形属性的显示方式。具体形式上来看是图例和坐标刻度。 Scale和Mapping是紧密相关的概念。
3.几何对象Geom
几何对象代表我们在图中实际看到的图形元素,如点、线、多边形等。
4.统计变换Stat
对原始数据进行某种计算,例如对二元散点图加上一条回归线。
5.坐标系统Coord
坐标系统控制坐标轴幵影响所有图形元素,坐标轴可以进行变换以满足不同的需要。
6.图层Layer
数据、映射、几何对象、统计变换等构成一个图层。图层可以允许用户一步步的构建图形,方便单独对图层进行修改。
7.分面Facet
条件绘图,将数据按某种方式分组,然后分别绘图。分面就是控制分组绘图的方法和排列形式。
8.主题theme
theme()函数中的选项可以调整字体、背景、颜色、网格线。
mytheme <- theme(plot.title=element_text(
+face="bold.italic", size="14", color="brown"), #指定图的标题应该为粗斜体棕色14号
+axis.title=element_text(face="bold.italic", size=10, color="brown"),#轴的标题为粗斜体的棕色10
+axis.text=element_text(face="bold", size=9, color="darkblue"),#轴标签为粗体的深蓝色9号
+panel.background=element_rect(fill="white",color="darkblue"),#图片区域有白色的填充和深蓝色的边框
+panel.grid.major.y=element_line(color="grey",linetype=1),#主水平网格应该是灰色的实线
+panel.grid.minor.y=element_line(color="grey", linetype=2),#次水平网格应该是灰色的虚线
+panel.grid.minor.x=element_blank(), #垂直网格不输出
+legend.position="top") #图例展示在顶部
设置完成后使用 myeheme
ggplot(Salaries, aes(x=rank, y=salary, fill=sex)) +geom_boxplot() +labs(title="Salary by Rank and Sex", x="Rank", y="Salary") +mytheme #使用之前 mytheme设置的内容
9.存储和输出
在ggplot2中,有更简单的保存方法,ggsave()能更方便保存
选项包括保存哪副图形,保存在哪里,以什么形式保存。
myplot<-ggplot(data=mtcars,aes(x=mpg))+geom_histogram()
ggsave(file="mygraph.png",plot=myplot,width=5,height=4)
即将myplot保存为名为mygraph.png的5英寸*4英寸PNG格式的图片
如果忽略plot=选项,最近创建的图形会被保存。
二.简单示例
1)散点图
1.数据
在ggplot2中, 所接受的数据集必须为数据框(data.frame)格式
library(ggplot2)
str(mpg)
head(mpg)
2.映射
aes()函数是ggplot2中的映射函数, 所谓的映射即为数据集中的数据关联到相应的图形属性过程中一种对应关系
每个点都有自己图像上的属性,比如x坐标,y坐标,点的大小、颜色和形状,这些都叫做aesthetics,即图像上可观测到的属性,通过aes函数来赋值
p <- ggplot(data=mpg, mapping=aes(x=cty, y=hwy))
p
summary(p)
3.几何对象
通过”+”以图层的方式加入点的几何对象
p + geom_point()
summary(p + geom_point())
注1:2、3步可合并为
ggplot(data=mpg, aes(x=cty, y=hwy)) + geom_point()
注2:改变横纵坐标名称
ggplot(data=mpg, aes(x=cty, y=hwy)) + geom_point() + xlab("A") + ylab("B")
注3:geom_point()中参数的用法
#shape
ggplot(data=mpg, aes(x=cty, y=hwy)) + geom_point(shape=17)
#size
ggplot(data=mpg, aes(x=cty, y=hwy)) + geom_point(size=2.5)
#color
ggplot(data=mpg, aes(x=cty, y=hwy)) + geom_point(color="red")
4.将年份映射到颜色/形状/大小属性(按年份分组)
将分组变量(因子或字符变量,可通过factor()强制性将非因子变量转为因子变量)赋值给颜色或形状或大小属性(变量赋值必须在aes里面),实现分组散点图的绘制。
①颜色
ggplot(mpg,aes(x=cty, y=hwy, colour=factor(year)))+geom_point()
②大小
ggplot(mpg,aes(x=cty, y=hwy, size=factor(year)))+geom_point()
③形状
ggplot(mpg,aes(x=cty, y=hwy, shape=factor(year)))+geom_point()
5.增加平滑曲线
geom_smooth可以增加一条线,而stat_smooth是可以添加一个置信区间范围的(利用方差值)。
①stat_smooth
ggplot函数中赋予的值是全局性质的,如果不希望全局生效,放到后面+对应的图层中去。
如:
CASE1:stat_smooth对不同颜色的点,各自拟合曲线
ggplot(mpg,aes(x=cty, y=hwy, colour=factor(year)))+geom_point()+stat_smooth()
CASE2:stat_smooth对所有点,拟合一条曲线
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year)))+stat_smooth()
#等价形式
ggplot() +geom_point(data=mpg, aes(x=cty, y=hwy, colour=factor(year)))+stat_smooth(data=mpg, aes(x=cty, y=hwy))
②geom_smooth
geom_smooth():这个函数就是为散点图添加一条平滑的曲线(包含直线),它有个参数method, 指定曲线平滑方法,可选"lm", "glm", "gam", "loess", "rlm",默认会使用"loess"。
ggplot(mpg,aes(x=cty, y=hwy))+ geom_point(aes(colour=factor(year))) + geom_smooth(method = lm)
#等价形式
ggplot(mpg,aes(x=cty, y=hwy))+ geom_point(aes(colour=factor(year))) + stst_smooth(method = lm)
更改平滑曲线为一条红色虚线
ggplot(mpg,aes(x=cty, y=hwy))+ geom_point(aes(colour=factor(year))) + geom_smooth(method = lm,colour="red",linetype=2)
其中linetype依次为1=实线,2=虚线,3=点,4=点破折号,5=长破折号,6=双破折号
6.自定义颜色/形状
scale_color_brewer()或者scale_color_manual()函数自定义点的颜色;scale_shape_manual()函数自定义点的形状;
下面我们将分组变量year同时赋值给颜色和形状属性。
①改变颜色
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year)))+stat_smooth(method = lm)+scale_color_manual(values =c('blue','red'))
②改变颜色,通过Accent(调色板)
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year)))+stat_smooth(method = lm)+scale_color_brewer(palette = "Accent")
③改变形状
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(shape=factor(year)))+stat_smooth(method = lm)+scale_shape_manual(values = c(2, 9))
④同时改变颜色和形状
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),shape=factor(year)))+stat_smooth(method = lm)+scale_color_brewer(palette = "Accent")+scale_shape_manual(values = c(2, 9))
7.将连续型变量(排量)映射到颜色/大小属性
①大小
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(size=displ))+stat_smooth()
②大小,指定我们size的变化范围,即控制点的绝对大小的范围,默认点的大小为1-6ms,可更改为2-8ms
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(size=displ))+stat_smooth()+scale_size_continuous(range = c(2, 8))
③大小,同时将年份按颜色分组
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+stat_smooth()
④颜色
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(color=displ))+stat_smooth()
⑤颜色(通过人为设置色阶)
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(color=displ))+stat_smooth()+ scale_color_gradient(low="lightblue", high="darkblue")
8.分面facet
分面设置在ggplot2应该也是要经常用到的一项画图内容,在数据对比以及分类显示上有着极为重要的作用。
facet_wrap和facet_grid不同在于facet_wrap是基于一个因子进行设置,facets表示形式为:~ 变量
而facet_grid是基于两个因子进行设置,facets表示形式为:变量 ~ 变量(行 ~ 列),如果把一个因子用点表示,也可以达到facet_wrap的效果,也可以用加号设置成两个以上变量
例如:变量+变量~变量 的形式,表示对三个变量设置分面。
①facet_wrap
facet_wrap(facets, nrow = NULL, ncol = NULL, scales = "fixed", shrink = TRUE, as.table = TRUE, drop = TRUE)
下面对参数进行说明:
· nrow,ncol : 分面所设置成的行和列,参数为数值,表示几行或者几列
· scales : 参数fixed表示固定坐标轴刻度,free表示反馈坐标轴刻度,也可以单独设置成free_x或free_y(把scales 设置成free之后,可以看出每个分面都有自己的坐标刻度,当然我们也可以单独对x轴或y轴设置)
· shrink : 也和坐标轴刻度有关,如果为TRUE(默认值)则按统计后的数据调整刻度范围,否则按统计前的数据设定坐标
· drop : 表示是否去掉没有数据的分组,默认情况下不显示,逻辑值为FALSE
CASE1:
#利用facet分别显示不同年份的数据
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(colour=class,size=displ))+ stat_smooth()+scale_size_continuous(range = c(2, 8))+facet_wrap(~ year, ncol=1)
facet_wrap()是关键,facet与wrap两个词组合,就是逐面地包起来。里面我们选择按照year这个变量来分层,就可以将1999与2008分开。一定要注意!这里在year前面有个~,回归中的用法。而最后的ncol = 1代表着我们的小窗口是1列,指定了1列之后,默认就是两行(因为年份一共只有两种)。
colour = class。class也是数据集中的一个变量,代表不同种类的汽车,而因为汽车的种类非常多,所以颜色也就变的很多。
CASE2:
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(colour=class,size=displ))+ stat_smooth()+scale_size_continuous(range = c(2, 8))+facet_wrap(~ year)
如果不加ncol=1,会默认横着排列
CASE3:
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(colour=class,size=displ))+ stat_smooth()+scale_size_continuous(range = c(2, 8))+facet_wrap(~ year,nrow=1)
或者想要指定几行,则使用nrow = 1
②facet_grid
facet_grid(facets, margins = FALSE, scales = "fixed", space = "fixed", shrink = TRUE, labeller = "label_value", as.table = TRUE, drop = TRUE)
下面对参数进行说明:
· scales 、shrink、drop 同上
· as.table :和小图排列顺序有关的选项。如果为TRUE(默认)则按表格方式排列,即最大值(指分组level值)排在表格最后即右下角,否则排在左上角
· margins :通过TRUE或者FALSE表示否设置而一个总和的分面变量,默认情况为FALSE,即不设置
· space :表示分面空间是否可以按数据进行缩放,参数和scales一样
CASE1:
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(colour=class,size=displ))+ stat_smooth()+scale_size_continuous(range = c(2, 8))+facet_grid(.~ year)
一行多列
CASE2:
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(colour=class,size=displ))+ stat_smooth()+scale_size_continuous(range = c(2, 8))+facet_grid(year~ .)
一列多行
9.其他调整
①更改透明度alpha
当数据量非常大时,会导致数据重叠点非常严重,可通过使用半透明的点避免。alpha参数控制点的透明度。从0(完全透明)到1(不透明)。
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(size=2,color="red",alpha=0.005))
②用坐标控制图形显示范围xlim,ylim
ggplot(mpg,aes(x=cty, y=hwy))+geom_point(aes(size=2,color="red",alpha=0.005))+coord_cartesian(xlim = c(15, 25),ylim=c(15,30))
③调整坐标轴coord
CASE1:横纵坐标交换coord_flip()
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+stat_smooth()
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+stat_smooth()+ coord_flip()
CASE2:转换为极坐标系coord_polar()
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+stat_smooth()+ coord_polar()
④去除掉拟合曲线的置信区间 se=FALSE
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+stat_smooth(se=FALSE)
⑤增加标题 opts
CASE1:使用ggtitle
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+ggtitle("汽车油耗与型号")
CASE2:使用ggtitle,并居中hjust
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+ggtitle("汽车油耗与型号")+theme(plot.title = element_text(hjust = 0.5))
hjust 其实就是左右移动的意思,0.5
CASE3:使用labs
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+labs(title="汽车油耗与型号")
⑥增加标题横纵坐标名称 labs
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+labs(y='每加仑高速公路行驶距离',x='每加仑城市公路行驶距离')
⑦改变图例位置 theme
决定放哪儿的参数是:theme()中的legend.position,默认状态theme(legend.position = "right"),然后我们可以通过“right”, “left”, “top”, “bottom”,把他放在上/下/左,或者去掉“none”
ggplot(mpg,aes(x=cty,y=hwy))+geom_point(aes(colour=factor(year),size=displ))+theme(legend.position = "left")
⑧改变图例名称、大小guides
ggplot(mpg, aes(x=cty, y=hwy))+ geom_point(aes(colour=class,size=displ))+ guides(size=guide_legend(title='排量'),colour = guide_legend(title='车型',override.aes=list(size=5)))
⑨去掉背景theme
ggplot(mpg, aes(x=cty, y=hwy))+ geom_point(aes(colour=class,size=displ))
ggplot(mpg, aes(x=cty, y=hwy))+ geom_point(aes(colour=class,size=displ))+theme(panel.background=element_blank())
⑩共用同一坐标轴,作对比
ggplot(mpg, aes(x=cty))+geom_point(aes(y=hwy,colour="red"))+geom_point(aes(y=displ,colour="green"))
等价形式
ggplot()+geom_point(aes(x=mpg$cty,y=mpg$hwy),color="red")+geom_point(aes(x=mpg$cty,y=mpg$displ),color="green")
2)直方图
1.一般形式
ggplot(mpg,aes(x=hwy))+geom_histogram()
2.内置的统计变换
geom_histogram()默认使用stat_bin(按照区间统计频数)这个统计变换, 而这个统计变换会生成(1)count:每个组里观测值的数目, (2)density:每个组里观测值的密度和(3)x:组的中心位置这三个变量
①调整分箱(bin),即直方图的宽度binwidth
ggplot(mpg,aes(x=hwy))+geom_histogram(binwidth =0.5)
②调整纵坐标为密度density
将原本的频数直方图变成频率密度直方图,density表示y坐标用密度而不是用默认count来代替,density前后都用..标出的原因是为了避免和dataframe中已有的列名有重复。这样表示赋值并不是dataframe中的列名含义,而是系统的参数含义
ggplot(mpg,aes(x=hwy,y=..density..))+geom_histogram(binwidth =0.5)
3.调整每个年份对应一个直方图facet_wrap
CASE1:
ggplot(mpg,aes(x=hwy)) +geom_histogram()+facet_wrap(~year, ncol=1)
CASE2:
ggplot(mpg,aes(x=hwy)) +geom_histogram()+facet_grid(year~.)
注:这里的year如果改成factor(year),会报错
4.元素位置的调整
元素位置的调整共有5种包括了(1)dodge:并排方式; (2)fill:堆叠图像元素, 并将高度标准化为1,(3)identity:不做任何调整; (4)jitter:给点增加扰动避免重合和(5)stack:堆叠图像元素。
①fill=factor(year)
fill=factor(year)表示按年进行填充颜色。为什么不用前面说到的colour = ?这是ggplot绘图中,对于线与点这种面积为0的结构,它的颜色就直接使用colour =进行指定,而对条形和密度区域,例如条形图,柱状图,扇形图(特殊的柱状图),箱线图等等有面积的图形,其面积的颜色,我们需要用fill =来指定。
ggplot(mpg,aes(x=hwy,fill=factor(year)))+geom_histogram()
#等价形式
ggplot(mpg)+geom_histogram(aes(x=hwy,fill=factor(year)))
②dodge
也可以将其分开,side-by-side地画直方图,即并排
ggplot(mpg,aes(x=hwy,fill=factor(year)))+geom_histogram(position="dodge")
③fill
还可以使用position="fill",按照相对比例来画。垂直的堆叠并规范其高度相等。
ggplot(mpg,aes(x=hwy,fill=factor(year)))+geom_histogram(position="fill")
④identity
很多情况下, 采用固定的x轴和y轴值来进行作图, 此时需要用stat = “identity” 来申明, 即表示不对数据进行统计变换
ggplot(mpg,aes(x=hwy,y=class))+geom_histogram(stat = "identity")
⑤jitter
对于点来说,是减少点重叠
ggplot(mpg,aes(x=hwy,fill=factor(year)))+geom_histogram(position = "jitter")
⑥stack
ggplot(mpg,aes(x=hwy,fill=factor(year)))+geom_histogram(position="stack")
5.增加密度曲线
stat_density()表示添加统计学中的密度曲线,进行密度估计。geom = 'line'指定为线形, position = 'identity'表示一个一一映射, size = 1.5 是强制修改线的尺寸,为原先的1.5倍。最后的aes(colour = factor(year))为修改拟合密度曲线的颜色,这里就是用的colour =而不是fill =
ggplot(mpg,aes(x=hwy)) + geom_histogram(aes(fill = factor(year), y = ..density..),alpha = 0.3, colour = 'black') + stat_density(geom = 'line', position = 'identity', size = 1.5,aes(colour = factor(year))) + facet_wrap(~ year, ncol = 1)
等价形式
geom_density=stat_density(geom="line")
ggplot(mpg,aes(x=hwy)) + geom_histogram(aes(fill = factor(year), y = ..density..),alpha = 0.3, colour = 'black') + geom_density(position = 'identity', size = 1.5,aes(colour = factor(year))) + facet_wrap(~ year, ncol = 1)
3)条形图
条形图和直方图是很像的,直方图把连续型的数据按照一个个等长的分区(bin)来切分,然后计数,画条形图。而条形图是分类数据,按类别计数。
1.一般形式
ggplot(mpg,aes(x=class))+geom_bar()
2.根据计数排序后绘制的条形图
class2<-mpg$class
class3<-reorder(class2,class2,length)
ggplot(mpg,aes(x=class3))+geom_bar(aes(fill=class3))
其中 reorder函数:首参选定因子向量,次参选定排序依据的数据向量,FUN参数选定汇总函数
例如:
iss
即根据count列对spray列中的因子水平进行重排序,汇总数据为mean
3.根据年份分别绘制条形图,position控制位置调整参数
p<-ggplot(mpg,aes(class3,fill=factor(year)))
p+geom_bar(position='identity',alpha=0.5)
CASE1:(并立方式)
p+geom_bar(position='dodge')
CASE2:(叠加方式)
p+geom_bar(position='stack')
CASE3:(相对比例)
p+geom_bar(position='fill')
CASE4:(分面显示)
p+geom_bar(aes(fill=class3))+facet_wrap(~year)
4)饼图
饼图实际上就是柱状图,只不过是使用极坐标而已。
首先x轴,只有一个柱子,柱子的宽度我们设置为1,geom_bar(width = 1),也就是铺满整个图,而柱子按照class变量来分类,并且是堆叠的(默认是堆叠条形图)。这时的图,也就是p4是一个“千层饼”。然后我们按照y轴为原点,用coord_polar(theta = "y"),就成了我们的饼图了。
p <- ggplot(mpg, aes(x = factor(1), fill = factor(class))) + geom_bar(width = 1)
p
y映射为角度(此时x恒等于1,即半径相同)
p + coord_polar(theta = "y")
5)靶心图
p <- ggplot(mpg, aes(x = factor(1), fill = factor(class))) + geom_bar(width = 1)
p + coord_polar()
#等价形式
p + coord_polar(theta = "x")
6)玫瑰图/鸡冠花图
绘制 Coxcomb Plots (鸡冠花图,又名玫瑰图),width的值可以调整各个扇形区域之间的距离。
ggplot(mpg, aes(x = factor(mpg$class)))+geom_bar(width = 0.7,aes(color=factor(mpg$class))) + coord_polar()
增添颜色
ggplot(mpg, aes(x = factor(mpg$class),fill=mpg$class))+geom_bar(width = 0.7) + coord_polar()
7)箱线图
width为箱线图的宽度。
ggplot(mpg, aes(class,hwy,fill=class))+geom_boxplot()
8)小提琴图
使用geom_violin()绘制小提琴图,同样改变透明度。小提琴图相比于箱线图多了各个类别分布的信息,是图像变得更加漂亮。
然后我们用geom_jitter()添加扰动点,其实就是将数据点等间隔的排列,显得更加高大上。其中的shape = 21指定的是扰动点的形状,我们用21号,也就是空心点(默认是实心点)。
ggplot(mpg, aes(class,hwy,fill=class))+geom_violin(alpha = 0.3) + geom_jitter(shape = 21)
9)地毯图
快速查看每个坐标轴上数据的分布密疏情况
地毯图的放置,b=底部,l=左部,t=顶部,r=右部,bl=左下部
ggplot(mpg, aes(class,hwy,fill=class))+geom_boxplot()+geom_rug(side="l",color="red")
10)多重图
将多个图形放到单个图形最简单的方式是gridExtra包中的grid.arrange()函数
install.packages("gridExtra")
library(gridExtra)
p1<-ggplot(mpg, aes(class,hwy))+geom_boxplot()
p2<-ggplot(mpg, aes(class))+geom_bar()
p3<-ggplot(mpg,aes(x=cty, y=hwy))+geom_point()
grid.arrange(p1,p2,p3,ncol=3)