在开始ggplot2的学习之前,可以先看下我之前的一篇博客,关于快速作图——qplot
第一步当然是加载ggplot2,读取数据,了解数据。
> library(ggplot2)
Warning message:
程辑包‘ggplot2’是用R版本3.6.3 来建造的
> mpg
# A tibble: 234 x 11
manufacturer model displ year cyl trans drv cty hwy fl class
<chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
3 audi a4 2 2008 4 manual(m6) f 20 31 p compact
4 audi a4 2 2008 4 auto(av) f 21 30 p compact
5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compact
6 audi a4 2.8 1999 6 manual(m5) f 18 26 p compact
7 audi a4 3.1 2008 6 auto(av) f 18 27 p compact
8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26 p compact
9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25 p compact
10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28 p compact
# ... with 224 more rows
> 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" ...
cty 和 hwy 分别记录城市和高速公路驾驶耗油量(英里/加仑)
1 mile=1609.344 m;1 gal=3.785412L
displ 表示发动机排量(L)
drv 表示驱动系统:前轮驱动(f)、后轮驱动(r)和四轮驱动(4)
model 表示车辆型号,共有38种车型
class 表示车辆类别
全部变量的解释可以参考:mpg数据集内容
ggplot2 图像的三个基本构成:
1、数据
2、图形属性映射
3、几何对象
for example
ggplot(mpg,aes(x=displ,y=hwy))+geom_point()
1、数据:mpg
2、图形属性映射:displ对应x轴,hwy对应y轴
3、几何对象:散点图
代码就像套公式,ggplot(mpg,aes(x=displ,y=hwy))+geom_point(),数据和图形属性映射包含在ggplot()中,而+可用来添加图层,随着学习的深入,+的东西会越来越丰富。
先补充一点,下面两行代码是一样的,默认先x后y。
ggplot(mpg,aes(x=displ,y=hwy))+geom_point()
ggplot(mpg,aes(displ,hwy))+geom_point()
然而这样做出来的图并不是我们想要的,因为不够美观。还需要进一步调整,比如:
#ggplot2通过 标度 可以将数据转换为图形属性。
ggplot(mpg,aes(displ,hwy,colour=class))+geom_point()#颜色
ggplot(mpg,aes(displ,hwy,shape=drv))+geom_point()#形状
ggplot(mpg,aes(displ,hwy,size=cyl))+geom_point()#大小
以第一个colour为例,不同类型的车一目了然。
那么,可以看出什么呢?比如发动机排量(displ)较大的双座车(2seater),油耗却不是最高的,所以固定油耗下行驶距离会更长。
ggplot(mpg,aes(x=displ,y=hwy))+geom_point(aes(colour="blue"))
ggplot(mpg,aes(x=displ,y=hwy))+geom_point(colour="blue")
为什么会这样呢?这就是“标度”的作用,可以体会一下,我不太会解释 。
最后,来了解一下“分面”。这个不用解释,目的就是把复杂的数据分一分类,做出来的图更直观。分面有两种类型,网格型和封装型,下面主要讨论更为常用的封装型。
ggplot(mpg,aes(displ,hwy))+geom_point()+facet_wrap(~class)
加上facet_wrap()即可,括号里是类别,别忘了波浪线~
聪明的你可能已经想到修改geom_point(),来画其他的图,恭喜你猜对了!
下面挑几个常用的图像类型展示一下:
ggplot(mpg,aes(displ,hwy))+geom_point()+geom_smooth()
灰色部分表示逐点置信区间用以评估不确定性。如果不需要,可以输入geom_smooth(se=FALSE)。
示例:
ggplot(mpg,aes(displ,hwy))+geom_point()+geom_smooth(method="loess",span=0.2)
ggplot(mpg,aes(displ,hwy))+geom_point()+geom_smooth(method="loess",span=1)
但是,当数据量n超过1000时,loess并不适用,那该怎么办呢?下次再介绍
我们常用的还有线性拟合,method=“lm”,这个就不存在平滑的问题了。method=“rlm”,也可进行线性拟合,对异常值不敏感,不过需要加载R包MASS,这里就不再做了。
ggplot(mpg,aes(drv,hwy))+geom_point()
不同驱动的车与耗油量的关系。上图的问题是容易出现重叠,数据多了分布看不清楚 ,太low了。
该怎么解决呢?有三种工具,扰动点图、箱线图、小提琴图。
ggplot(mpg,aes(drv,hwy))+geom_jitter()
ggplot(mpg,aes(drv,hwy))+geom_boxplot()
ggplot(mpg,aes(drv,hwy))+geom_violin()
每种方法都有优势和不足,根据自己的数据特点选择合适的方法最重要。
ggplot(mpg,aes(hwy))+geom_histogram(binwidth = 1)
ggplot(mpg,aes(hwy))+geom_freqpoly(binwidth = 1)
#binwidth为组距,如果不需要均匀组距可以修改 breaks 参数
#不调整组距的话会被默认分为30组
离散变量情形下,条形图和直方图类似:
ggplot(mpg,aes(manufacturer))+geom_bar()
还有一种条形图是经过预处理的,比较常用。比如三种药品和它们的平均疗效:
drugs <- data.frame(drug = c("a","b","c"),effect = c(4.2,9.7,6.1))
ggplot(drugs,aes(drug,effect))+geom_bar(stat="identity")
这个应该是我最常用的图了,终于到我的菜了哈哈
由于mpg数据集中时间变量只有两个取值,因此这里用economics数据集,它包含美国过去40年的经济数据,下面展示失业水平随时间变化的两张折线图。第一张显示了失业率的变化,第二张显示了失业星期数的中位数。
ggplot(economics,aes(date,unemploy/pop))+geom_line()
ggplot(economics,aes(date,uempmed))+geom_line()
可以看出两张图的区别,例如在最后一个峰值处,失业率比前一个峰值低,但失业时间却要更长。
为了考察这种关系的更多细节,可以将两个图绘制在一张图中,也就是失业率和失业时间随年份变化的路径。第一张图时间变化的方向不明显,第二张图将年份映射到颜色属性上,可以更容易看出时间的行进方向。
ggplot(economics,aes(unemploy/pop,uempmed))+geom_path()+geom_point()
year <- function(x) as.POSIXlt(x)$year+1900
ggplot(economics,aes(unemploy/pop,uempmed))+geom_path(colour="grey50")+
geom_point(aes(colour=year(date)))
可以看出,失业率和失业时间是高度相关的,但是,最近几年,失业时间长度与失业率相比有增长的趋势。
修饰坐标轴也是作图必不可少的一个环节(下面仅介绍最主要的,其他细节下次再写)。
xlab()和ylab()设置坐标轴标签:
ggplot(mpg,aes(cty,hwy))+geom_point(alpha=1/3)+
xlab("city driving (mpg)")+ylab("highway driving (mpg)")
//alpha设置透明度
//如果不要轴标签,xlab(NULL)+ylab(NULL)
ggplot(mpg,aes(drv,hwy))+
geom_jitter(width = 0.25)+
xlim("f","r")+ylim(20,30)
//Warning message:
//Removed 140 rows containing missing values (geom_point).
ggplot(mpg,aes(drv,hwy))+
geom_jitter(width=0.25,na.rm = TRUE)+
ylim(NA,30)
坐标轴显示区间改变后,区间外的取值会默认设置为 NA,可以通过na.rm=TRUE来关闭相关警告提示。
终于要输出了,好累orz
大多数情况下图像会直接进行绘制,但同样可以将图像存储为变量并对其进行修改,然后手动print:
p <- ggplot(mpg,aes(displ,hwy,colour=factor(cyl)))+
geom_point()
print(p)
ggsave("plot.png",width = 5,height = 5)
//将png文件保存到硬盘,找不到存在哪里了?使用getwd()
> summary(p)
data: manufacturer, model, displ, year, cyl, trans, drv, cty, hwy, fl, class
[234x11]
mapping: x = ~displ, y = ~hwy, colour = ~factor(cyl)
faceting: <ggproto object: Class FacetNull, Facet, gg>
compute_layout: function
draw_back: function
draw_front: function
draw_labels: function
draw_panels: function
finish_data: function
init_scales: function
map_data: function
params: list
setup_data: function
setup_params: function
shrink: TRUE
train_scales: function
vars: function
super: <ggproto object: Class FacetNull, Facet, gg>
-----------------------------------
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity