title: "ggplot2双轴图"
author: "wintryheart"
date: "2019年5月11日"
output:
html_document:
toc: TRUE
toc_float: TRUE
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)
ggplot2双轴图问题
ggplot2在设计时,并不支持双轴图。设计者认为双轴图并不易读,容易被误导。
但是,qqplot2还是可以通过scale_y_continueous中的sec.axis参数来实现双轴图。
下面就以中国农村贫困人口数据来举例说明。数据来源于 2018年《中国统计年鉴》。
加载数据
load("c:/users/wintryheart/documents/poor2018.RData")
#加载自建的贫困人口数据集
attach(poor)
knitr::kable(poor[1:5,], caption="基于不同贫困标准的中国农村贫困人口和贫困率")
# knitr包的kable函数默认生成的是markdown格式的表格。
基于不同贫困标准的中国农村贫困人口和贫困率
year | p1978 | r1978 | p2008 | r2008 | p2010 | r2010 |
---|---|---|---|---|---|---|
1978 | 25000 | 30.7 | NA | NA | 77039 | 97.5 |
1980 | 22000 | 26.8 | NA | NA | 76542 | 96.2 |
1981 | 15200 | 18.5 | NA | NA | NA | NA |
1982 | 14500 | 17.5 | NA | NA | NA | NA |
1983 | 13500 | 16.2 | NA | NA | NA | NA |
注:p2010为按2010年贫困标准的历年贫困人口数,r2010为相应的贫困率。
library(ggplot2)
r1 <- ggplot(data=poor,aes(x=year)) #共建X轴
添加图层
- 构建两条散点图。(由于有些年份没有数据,所有没法用geom_line画线条图。)
- 虽然ggplot2会自动用不同的颜色区分两条散点图,但是为了更容易区分,第二条散点图的点形设置为小三角(pch=17)。点的大小也调大一点(size=3)。
- 由于主轴的数据比较大(贫困人口大部分数据值大于10000);而贫困率的数据比较小,所以为了能让贫困率的数据在主轴上能区分显示出来,需要按主轴的取值范围放大。主轴取值范围为[0,100000],贫困率的取值范围为[0,100],如果贫困率的值不放大,则在图中贫困率所有值都在接近于x轴的水平位置。因此在作图时次轴贫困率的取值放大1000倍(r2010*1000)。
r2 <- r1 + geom_point(aes(y=p2010, color="贫困人口"), size=3) +
geom_point(aes(y=r2010*1000, color="贫困率"), pch=17, size=3)
修改X轴和y轴坐标轴刻度,并添加第二Y轴。
- scale_y_continuous的第一个参数breaks是修改主轴的。第二个参数sec.axis是建立次轴的。
- sec_axis()函数中第一个参数表示主轴和次轴的大小关系。 ~./1000的意思,次轴=主轴除以1000,次轴比主轴小1000倍。这样正好还原了贫困率的取值范围。
- 若主轴和次轴的取值大小是加减关系,如次轴比主轴小100,则表示为~.+100。
- sec_axis()函数中name是轴标签,其它参数与主轴设置一样。
r3 <- r2 + scale_y_continuous(breaks = seq(0,100000,25000),
sec.axis = sec_axis(~./1000, name = "贫困率",
breaks=seq(0,100,10), labels = paste(seq(0,100,10),"%", seq="")
)
) +
scale_x_continuous(breaks = seq(1975,2020,5))
修改其它图形属性
r4 <- r3 + labs(x="年份", y="贫困人口:万人", title="按2010年贫困标准看中国农村贫困人口变化", color="")
r5 <- r4+ theme(plot.title = element_text(hjust=0.5), legend.position="bottom")
多重图
从上图可以看出,双轴图的确不是一个很好的展示信息的选择。将贫困人口和贫困率分别做图,然后用gridExtra包中的grid.arrange()函数组合在一起更能清晰地表达信息。
library(gridExtra)
g1 <- ggplot(poor, aes(x=year))
g2 <- g1 + geom_point(aes(y=p2010), size=3) + labs(x="年份", y="贫困人口:万人", title="贫困人口变化")
g3 <- g1 + geom_point(aes(y=r2010), pch=17, size=3) + labs(x="年份", y=paste("贫困率:","%"), title="贫困率变化")
grid.arrange(g2, g3, ncol=2)