R语言的一大特色是绘制精美的的统计图,而其中R包ggplot2专为绘图而生
一起简单了解一下ggplot2的基本语法
目录 图层 一开始先明确ggplot2的绘图逻辑,和PS类似,采用图层叠加 的方式,不同的图层用 ' ' 相连,多个图层最终结合成一幅图
library (ggplot2) ggplot(data=mtcars,aes(x=wt,y=mpg))
以mtcars 为例,以wt为x轴,mpg为y轴用ggplot()
先建立一个最基础的图层
ggplot(data=mtcars,aes(x=wt,y=mpg)) geom_point()
通过 ' ' 在基础图层上添加上散点(geom_point()
) ,得到一幅简单的散点图,后面还能添加更多的图层得到复杂的图形
映射 映射即视觉通道映射,通俗来说就是将数据映射到图形的某一成分中,数据会以指定的形式在图形中得以呈现
使用到函数aes()
,除了最基础的x,y轴的映射,还有其他映射类型color,fill,alpha,size,shape,linetype等等
ggplot(data=mtcars,aes(x=wt,y=mpg,color=as.factor(am))) geom_point()
x,y轴不变加上颜色映射类型 ,并传入因子型的数据,得到了两种颜色二分类的散点图
ggplot(data=mtcars,aes(x=wt,y=mpg,shape=as.factor(cyl))) geom_point()
x,y轴不变加上形状映射类型 ,传入cyl的三分类数据,得到有三种不同形状的散点图
ggplot(data=mtcars,aes(x=wt,y=mpg,size=qsec,alpha=hp)) geom_point()
也可以同时加上两种互不干扰的映射,透明度映射 和点大小映射
这里只是演示了关于点的映射,相对的还有线、图形、文本的映射,后面遇到再介绍
几何图形和统计变换 通常可以使用geom_
类函数来绘制指定的统计图
图形 函数 点图 geom_point() 折线图 geom_line() 箱线图 geom_boxplot() 密度图 geom_density() 柱状图 geom_bar() 小提琴图 geom_violin() ... ...
library (gridExtra)library (ggplot2) p1 <- ggplot(mtcars, aes(wt, mpg)) geom_point() p2 <- ggplot(economics, aes(date, unemploy)) geom_line() p3 <- ggplot(mpg, aes(class, hwy)) geom_boxplot() p4 <- ggplot(diamonds, aes(carat)) geom_density() p5 <- ggplot(mpg, aes(class)) geom_bar() p6 <- ggplot(mtcars, aes(mpg, factor(cyl))) geom_violin() grid.arrange(p1,p2,p3,p4,p5,p6,nrow=2 ,ncol=3 )
以上为6种常见图形的实例
以geom_point()
为例,简单介绍一下参数
##?geom_point## geom_point( mapping = NULL , data = NULL , stat = 'identity' , position = 'identity' , ... , na.rm = FALSE , show.legend = NA , inherit.aes = TRUE )
mapping、inherit.aes = TRUE 可使用aes()
指定相关映射ggplot(mtcars, aes(wt, mpg)) geom_point(aes(shape=factor(cyl)),color='green' ,size=3 ) geom_smooth()
geom_point
里面能重新指定映射(全局和局部的关系),也能添加参数改变图形属性,在点图的基础上还可以叠加光滑曲线(geom_smooth()
)
geom_
(几何图形)和stat_
(统计变换)都能作为一种叠加图层的方法,且两者绘图效果相似。
geom_
侧重图形的绘制,通过参数stat 指定统计方法stat_
侧重统计变换,通过参数geom 指定绘图类型两者能够相互转换,在帮助文件上也会同时写出两种绘图方法
geom_bar( mapping = NULL , data = NULL , stat = 'count' , position = 'stack' , ... , width = NULL , na.rm = FALSE , orientation = NA , show.legend = NA , inherit.aes = TRUE ) stat_count( mapping = NULL , data = NULL , geom = 'bar' , position = 'stack' , ... , width = NULL , na.rm = FALSE , orientation = NA , show.legend = NA , inherit.aes = TRUE )
geom_bar
stat = 'count' 、stat_count
geom = 'bar' 两种方法所得到的柱形图相同。
geom_bar
,指定count 统计变换方法,将数据转换成频数从而得到柱形图stat_count
默认count 的统计变换方法,指定bar 绘图方法从而得到柱形图标尺(Scale) 之前介绍的图大都都是按照默认参数生成的,scale_
类函数可以修改图形的细节
坐标轴 1、坐标轴刻度及标签
对于连续性变量 ,通常使用函数scale_x_continuous
、scale_y_continuous
scale_x_continuous( name = waiver(), breaks = waiver(), minor_breaks = waiver(), n.breaks = NULL , labels = waiver(), limits = NULL , expand = waiver(), oob = censor, na.value = NA_real_ , trans = 'identity' , guide = waiver(), position = 'bottom' , sec.axis = waiver() )
name 修改轴标题,使用函数labs()
也能达到相同效果library (gridExtra) p1 <- ggplot(mtcars, aes(wt, mpg)) geom_point() scale_x_continuous(name='AAA' ) p2 <- ggplot(mtcars, aes(wt, mpg)) geom_point() labs(x='BBB' ) grid.arrange(p1,p2,ncol=2 )
breaks 将数据进行指定分组,搭配参数label 可以修改组名ggplot(mpg, aes(displ, hwy)) geom_point() scale_x_continuous(breaks = c(2 , 4 , 6 ),label = c('two' , 'four' , 'six' ))
limits 限定坐标轴的刻度范围,和函数xlim
效果一样library (gridExtra) p1 <- ggplot(mtcars, aes(wt, mpg)) geom_point() scale_x_continuous(name='AAA' ,limits=c(1 ,7 )) ##限定x轴刻度在1到7 p2 <- ggplot(mtcars, aes(wt, mpg)) geom_point() xlim(1 ,8 ) grid.arrange(p1,p2,ncol=2 )
library (gridExtra) df <- data.frame( x = rnorm(10 ) * 100000 , y = seq(0 , 1 , length.out = 10 ) ) p1 <- ggplot(df, aes(y, x)) geom_point() scale_x_continuous(labels = scales::percent,name='percent' ) p2 <- ggplot(df, aes(y, x)) geom_point() scale_x_continuous(labels = scales::dollar,name='dollar' ) grid.arrange(p1,p2,ncol=2 )
scales::percent
、scales::dollar
分别指定x轴刻度的类别,分别为百分比和美元
'asn' , 'atanh' , 'boxcox' , 'date' , 'exp' , 'hms' , 'identity' , 'log' , 'log10' , 'log1p' , 'log2' , 'logit' , 'modulus' , 'probability' , 'probit' , 'pseudo_log' , 'reciprocal' , 'reverse' , 'sqrt' , 'time'
p1 <- ggplot(mtcars, aes(wt, mpg)) geom_point() scale_x_continuous(name='None' ) p2 <- ggplot(mtcars, aes(wt, mpg)) geom_point() scale_x_continuous(name='log2' ,trans='log2' ) grid.arrange(p1,p2,ncol=2 )
position 设定坐标轴的位置,x轴 “top”、“bottom” ,y轴 'left'、'right'对于离散型数据
scale_x_discrete()
、scale_y_discrete()
函数的用法和连续型变量的用法类似,参数几乎通用
ggplot(diamonds, aes(cut)) geom_bar() scale_x_discrete('Cut' ,labels = c('Fair' = 'F' ,'Good' = 'G' ,'Very Good' = 'VG' ,'Perfect' = 'P' ,'Ideal' = 'I' ))## 轴标题、刻度标签替换
对于时间变量
一般使用函数scale_x_date()
、scale_y_date()
scale_x_date( name = waiver(), breaks = waiver(), date_breaks = waiver(), labels = waiver(), date_labels = waiver(), minor_breaks = waiver(), date_minor_breaks = waiver(), limits = NULL , expand = waiver(), oob = censor, guide = waiver(), position = 'bottom' , sec.axis = waiver() )
library (gridExtra) last_month <- Sys.Date() - 0 :29 ## 生成从今天起往前30天的时间序列 df <- data.frame( date = last_month, price = runif(30 ) ) ## 为30个时间序列随机生成一个对应的值 base <- ggplot(df, aes(date, price)) geom_line() p1 <- base scale_x_date(date_labels = '%b %d' ) labs(title='p1' ) p2 <- base scale_x_date(date_breaks = '1 week' , date_labels = '%W' ) labs(title='p2' ) p3 <- base scale_x_date(date_minor_breaks = '1 day' ) labs(title='p3' ) p4 <- base scale_x_date(limits = c(Sys.Date() - 7 , NA )) labs(title='p4' ) grid.arrange(p1,p2,p3,p4,ncol=2 )
p1中通过参数'date_labels '可以格式化输出时间序列
p2中通过参数“date_breaks ”指定主坐标的间隔
p3中通过参数'date_minor_breaks '指定主坐标间的分隔距离
图形标题 函数labs()
能为图形修改或添加各种文字属性
labs( ..., title = waiver(), subtitle = waiver(), caption = waiver(), tag = waiver(), alt = waiver(), alt_insight = waiver() )
p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) geom_point() p p_re <- p labs(x='XXX' ,y='YYY' ,title='title' ,subtitle='subtitle' , tag='tag' ,caption='caption' ,colour='colour' ,alt='This is alt' ) p_re############## > get_alt_text(p_re) [1 ] 'This is alt'
以上两图对比,展示出tag、title、subtiltle等的显示位置
关于参数alt ,相当于对图形变量的描述,不会展示在具体图形中,需要用函数get_alt_text()
来调用
颜色 1、颜色渐变
scale_colour_gradient( ... , low = '#132B43' , high = '#56B1F7' , space = 'Lab' , na.value = 'grey50' , guide = 'colourbar' , aesthetics = 'colour' )
guide 图例的形式,连续型“colourbar”、离散型'legend'aesthetics 设定颜色映射通道 “fill”、'colour'ggplot(mpg, aes(displ, hwy, color = hwy)) geom_point() scale_color_gradient(low = '#132B43' , high = '#56B1F7' ,guide='colourbar' )
一幅从'#132B43'到'#56B1F7'的渐变点图
2、调用调色板颜色
scale_colour_brewer( ... , type = 'seq' , palette = 1 , direction = 1 , aesthetics = 'colour' )
type seq (sequential)、div (diverging)、qual (qualitative)palette 指定调色版,可字符指定调色板,也可数字指定调色板列表中的种类(顺序未知)。也可自己创建调色板。library (RColorBrewer) display.brewer.all() ## 默认可选调色板类型
direction 颜色变换方向,1 正向,-1 反向library (gridExtra) dsamp <- diamonds[sample(nrow(diamonds), 1000 ), ] d <- ggplot(dsamp, aes(carat, price)) geom_point(aes(colour = clarity)) labs(title='default' ) d1 <- ggplot(dsamp, aes(carat, price)) geom_point(aes(colour = clarity)) scale_color_brewer(palette='BuGn' ) labs(title='BuGn' ) d2 <- ggplot(dsamp, aes(carat, price)) geom_point(aes(colour = clarity)) scale_color_brewer(palette='Set1' ) labs(title='Set1' ) d3 <- ggplot(dsamp, aes(carat, price)) geom_point(aes(colour = clarity)) scale_color_brewer(palette='PiYG' ) labs(title='PiYG' ) grid.arrange(d,d1,d2,d3,nrow=2 )
调整映射参数 scale_alpha()
、scale_shape()
、scale_size()
p1 <- ggplot(mpg, aes(displ, hwy)) geom_point(aes(alpha = year)) p2 <- ggplot(mpg, aes(displ, hwy)) geom_point(aes(alpha = year)) scale_alpha(range = c(0.4 , 0.8 )) grid.arrange(p1,p2)
将透明度映射范围限定在0.4~0.8
dsmall <- diamonds[sample(nrow(diamonds), 100 ), ] d <- ggplot(dsmall, aes(carat, price)) geom_point(aes(shape = cut)) d1 <- ggplot(dsmall, aes(carat, price)) geom_point(aes(shape = cut)) scale_shape(solid=F ) grid.arrange(d,d1)
参数solid 可改变点的填充
p1 <- ggplot(mpg, aes(displ, hwy, size = hwy)) geom_point() p2 <- ggplot(mpg, aes(displ, hwy, size = hwy)) geom_point() scale_size(range=c(0 ,10 )) p3 <- ggplot(mpg, aes(displ, hwy, size = hwy)) geom_point() scale_size_binned() grid.arrange(p1,p2,p3)
参数range 指定点的大小范围
函数scale_size_binned()
使图例分箱,更易观察
坐标系 ggplot2中提供了很多修改坐标系的函数
1、coord_cartesian
默认的直角坐标系
coord_cartesian( xlim = NULL , ylim = NULL , expand = TRUE , default = FALSE , clip = 'on' )
p1 <- ggplot(mtcars, aes(disp, wt)) geom_point() geom_smooth() p2 <- ggplot(mtcars, aes(disp, wt)) geom_point() geom_smooth() coord_cartesian(expand=F ) grid.arrange(p1,p2)
clip 边界外能否显示点,默认'on'不显示,'off'显示p1 <- ggplot(mtcars, aes(disp, wt)) geom_point() geom_smooth() coord_cartesian(expand=F ,clip='off' ) labs(title = 'clip=\'off\'' ) p2 <- ggplot(mtcars, aes(disp, wt)) geom_point() geom_smooth() coord_cartesian(expand=F ) labs(title = 'clip=\'on\'' ) grid.arrange(p1,p2)
2、coord_fixed()
调整x轴与y轴的比例长度
coord_fixed(ratio = 1 , xlim = NULL , ylim = NULL , expand = TRUE , clip = 'on' )
ratio 默认比例为1,即x轴与y轴上每个长度单位都一一对应p1 <- ggplot(mtcars, aes(mpg, wt)) geom_point() labs(title='default' ) p2 <- ggplot(mtcars, aes(mpg, wt)) geom_point() coord_fixed() labs(title='ratio=1' ) p3 <- ggplot(mtcars, aes(mpg, wt)) geom_point() coord_fixed(ratio=5 ) labs(title='ratio=5' ) grid.arrange(p1,p2,p3)
3、coord_flip()
x轴,y轴调换
p1 <- ggplot(diamonds, aes(cut, price)) geom_boxplot() p2 <- ggplot(diamonds, aes(cut, price)) geom_boxplot() coord_flip() grid.arrange(p1,p2)
4、coord_polar
极坐标系变换
coord_polar(theta = 'x' , start = 0 , direction = 1 , clip = 'on' )
pie <- ggplot(mtcars, aes(x = factor(1 ), fill = factor(cyl))) geom_bar(width = 1 ) p1 <- pie coord_polar() p2 <- pie coord_polar(theta='y' ) grid.arrange(p1,p2)
通过将柱形图进行坐标系转换,并将y值映射就可得到饼图
direction 绘制的顺序,1顺时针,-1逆时针玫瑰图的绘制,将柱形图进行极坐标转换
p1 <- ggplot(mpg,aes(class,fill=model)) geom_bar() theme(legend.position='none' ) p2 <- ggplot(mpg,aes(class,fill=model)) geom_bar() coord_polar() theme(legend.position='none' ) grid.arrange(p1,p2)
主题 ggplot2默认出图是灰底的图,自带函数theme_
有已配置好的主题可供选择,也可使用函数theme()
自定义自己的主题
library (patchwork) mtcars2 <- within(mtcars, { vs <- factor(vs, labels = c('V-shaped' , 'Straight' )) am <- factor(am, labels = c('Automatic' , 'Manual' )) cyl <- factor(cyl) gear <- factor(gear) }) p <- ggplot(mtcars2) geom_point(aes(x = wt, y = mpg, colour = gear)) p1 <- p theme_gray() labs(title='theme_gray' ) p2 <- p theme_bw() labs(title='theme_bw' ) p3 <- p theme_linedraw() labs(title='theme_linedraw' ) p4 <- p theme_light() labs(title='theme_light' ) p5 <- p theme_dark() labs(title='theme_dark' ) p6 <- p theme_minimal() labs(title='theme_minimal' ) p7 <- p theme_classic() labs(title='theme_classic' ) p8 <- p theme_void() labs(title='theme_void' ) p9 <- p theme_test() labs(title='theme_test' ) (p1 / p4 / p7) | (p2 / p5 / p8) | (p3 / p6 / p9)
以上为9种预设的主题
theme(......)
可自定义的范围太大了,先挖个坑,之后单独填
注释 注释是一个特殊的图层,不继承全局设置,使用函数annotation()
对统计图进行注释
annotate( geom, x = NULL , y = NULL , xmin = NULL , xmax = NULL , ymin = NULL , ymax = NULL , xend = NULL , yend = NULL , ... , na.rm = FALSE )
主要参数是 geom 指定需要添加注释的类型,如,文字(text)、矩形(rect)等。后面的参数根据 geom 的不同而不同 ggplot(mtcars, aes(x = wt, y = mpg)) geom_point() annotate('text' , x = 4 , y = 20 , label = 'text' , size = 10 , colour = 'green' )
简单的向(4,20)处添加文本'text',还可以对文字样式进行自定义
ggplot(mtcars, aes(x = wt, y = mpg)) geom_point() annotate('rect' , xmin = 3 , xmax = 4.2 , ymin = 12 , ymax = 21 ,alpha = .2 ,fill='green' )
绘制一个矩形,并指定透明度和填充颜色
ggplot(mtcars, aes(x = wt, y = mpg)) geom_point() annotate('segment' , x = 2.5 , xend = 4 , y = 15 , yend = 25 ,colour = 'blue' ,size=1 )
'segment'指定两点绘制线段
geom_()
类函数中,geom_abline()
(指定斜率、截距)、geom_hline()
(绘制横线)、geom_vline()
(绘制竖线)也能绘制指定直线图例 1、连续型变量
guide_colourbar()
或 guide_colorbar()
guide_colorbar( title = waiver(), title.position = NULL , title.theme = NULL , title.hjust = NULL , title.vjust = NULL , label = TRUE , label.position = NULL , label.theme = NULL , label.hjust = NULL , label.vjust = NULL , barwidth = NULL , barheight = NULL , nbin = 300 , raster = TRUE , frame.colour = NULL , frame.linewidth = 0.5 , frame.linetype = 1 , ticks = TRUE , ticks.colour = 'white' , ticks.linewidth = 0.5 , draw.ulim = TRUE , draw.llim = TRUE , direction = NULL , default.unit = 'line' , reverse = FALSE , order = 0 , available_aes = c('colour' , 'color' , 'fill' ), ... )
barwidth 、barheight 调整连续型图例的宽度和高度p <- ggplot(mtcars,aes(drat,mpg,fill=qsec)) geom_point() p1 <- p guides(fill = guide_colourbar(title='title' ,label=F , title.position='bottom' ,barwidth=1 , frame.colour = 'black' ,ticks = F )) grid.arrange(p,p1)
使用函数时,需嵌套入函数guides()
且指定映射
2、离散型变量
guide_legend( title = waiver(), title.position = NULL , title.theme = NULL , title.hjust = NULL , title.vjust = NULL , label = TRUE , label.position = NULL , label.theme = NULL , label.hjust = NULL , label.vjust = NULL , keywidth = NULL , keyheight = NULL , direction = NULL , default.unit = 'line' , override.aes = list(), nrow = NULL , ncol = NULL , byrow = FALSE , reverse = FALSE , order = 0 , ... )
keywidth 、keyheight 每个离散点外围框框的大小
p1 <- ggplot(mtcars, aes(drat, mpg, colour = factor(cyl))) geom_point() p2 <- ggplot(mtcars, aes(drat, mpg, colour = factor(cyl))) geom_point() guides(colour=guide_legend(title = 'title' ,keyheight=2 )) grid.arrange(p1,p2)
分面(Facetting) 根据数据的分组信息绘制多幅子图,做到将高维数据降维表示的目的
函数facet_grid()
、facet_wrap()
两种方式表示分面
1、facet_grid()
网格状的分面,指定变量定义行和列
facet_grid( rows = NULL , cols = NULL , scales = 'fixed' , space = 'fixed' , shrink = TRUE , labeller = 'label_value' , as.table = TRUE , switch = NULL , drop = TRUE , margins = FALSE , facets = NULL )
rows 、cols 分别指定行列分面对象,搭配函数vars()
使用,或使用简便格式 行分组变量~列分组变量 ,空着用 . 表示
scales 设置是否共用坐标轴,fixed共用坐标轴、free不共用
p<-ggplot(mpg, aes(cty, hwy)) geom_point(size=2 ,alpha=0.4 ) p1 <- p facet_grid(rows=vars(fl)) p2 <- p facet_grid(.~fl) p3 <- p facet_grid(vars(drv),vars(fl)) p4 <- p facet_grid(drv~fl,scales='free' ) grid.arrange(p1,p2,p3,p4,ncol=2 )
2、facet_wrap()
先按分组变量生成多个子图,再按顺序排列
简便格式 ~ 分组变量1 分组变量2
facet_wrap( facets, nrow = NULL , ncol = NULL , scales = 'fixed' , shrink = TRUE , labeller = 'label_value' , as.table = TRUE , switch = NULL , drop = TRUE , dir = 'h' , strip.position = 'top' )
p <- ggplot(mpg, aes(displ, hwy)) geom_point() p1 <- p facet_wrap(vars(class)) p2 <- p facet_wrap(vars(class), nrow = 4 ) p3 <- p facet_wrap(~cyl drv) p4 <- p facet_wrap(vars(cyl, drv), labeller = 'label_both' ) grid.arrange(p1,p2,p3,p4,nrow=2 )
基础语法就先简单介绍这些。
还有很多ggplot2的细节,比如自定义主题、各种geom_
的具体使用等,等实际用到再记录一下,或者之后再单独研究研究。