人口金字塔是进行人口数据可视化时常用的一种统计图形,可以形象地描述人口年龄和性别的分布情况。最近工作上经常处理人口数据,于是试着使用ggplot2绘制了一下。在这里记录一下,顺便也熟悉一下ggplot2的用法。

  上图所示的人口金字塔是根据我国2010年人口普查的相关数据进行绘制的,绘制过程主要分为以下三部分,(1)数据爬取,(2)分面设置以及(3)图形绘制。

1、数据爬取

  如下图所示,人口普查的相关数据可以从统计局网站上找到。

  由于网站是frame结构构建的动态网页,我们这里使用RSelenium包进行了爬取。这里值得注意的是,frame的切换需要逐层进行,我们这里使用switchToFrame、goBack和goForward函数实现了不同frame之间的切换。其中使用RSelenium包进行爬虫需安装java和Selenium,可参考R语言爬取动态网页:使用RSelenium包和Rwebdriver包的前期准备。

  爬虫相关程序如下:

library(RSelenium)
library(rvest)
## 打开浏览器
remDr <- remoteDriver(browserName ="chrome")
remDr$open()
## 打开网页
url <- 'http://www.stats.gov.cn/tjsj/pcsj/rkpc/6rp/indexch.htm'
remDr$navigate(url)
## 切换frame链接到数据页面
remDr$switchToFrame(1)
xpath <- '//tbody/tr[3]/th/ul/ul[1]/ul[3]/li[1]/a'
nextBtn <- remDr$findElement(using ='xpath',value = xpath)
nextBtn$clickElement()
## 切换到数据frame
remDr$goBack()
remDr$goForward()
remDr$switchToFrame(2)
## 读取数据
webpage <- read_html(remDr$getPageSource()[[1]][1])
data_temp <- html_table(webpage, fill = TRUE)[[1]]
## 数据清洗
data <- data_temp[grep('岁', data_temp[, 1]), ]
colnames(data) <- paste(data_temp[4,], data_temp[5,])
data_use <- cbind(1: nrow(data), data[, c(1, 3, 4)])
data_use[, 3] <- (data_use[, 3] %>% as.numeric()) * -1 / 10000
data_use[, 4] <- (data_use[, 4] %>% as.numeric()) / 10000
colnames(data_use) <- c('group', 'group_name', 'male', 'female')

  数据清洗后最终得到的数据如下所示:

2、分面设置

  ggplot2中没有专门绘制人口金字塔的函数,本文开头给出的人口金字塔图其实是由四部分作图得到的,即标题、标签、男性人口、女性人口。

  然而常用的分面函数par(mfrow)和layout在ggplot2中不能使用,我们这里参考ggplot2 3.0 分面、一页多图的做法,使用grid包中的viewport函数实现ggplot2的分面操作。

vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)
}
# 分面画图
grid.newpage()  ##新建页面
pushViewport(viewport(layout = grid.layout(12, 11)))
print(p_1, vp = vplayout(2:12, 1:5))
print(p_2, vp = vplayout(2:12, 7:11))
print(p_3, vp = vplayout(2:12, 6))
print(p_4, vp = vplayout(1, 1:11))

3、图形绘制

  在这里,人口分布的条形图使用geom_bar函数实现,标题和标签则使用geom_text函数在空白背景上直接添加。代码如下:

### 人口金字塔
library(ggplot2)
library(grid)
## 作图
# 函数
vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)
}
# 参数
v_max <- 6500
dig_temp <- nchar(as.character(v_max))
lim_1 <- c(-v_max, 0)
lim_2 <- c(0, v_max)
by <- round(v_max/(5 * 10^(dig_temp - 2))) * 10^(dig_temp - 2)
bre_1 <- seq(from = 0, to = -v_max, by = -by)
bre_2 <- seq(from = 0, to = v_max, by = by)
lab_1 <- seq(from = 0, to = v_max, by = by)
lab_2 <- seq(from = 0, to = v_max, by = by)
mg_1 <- unit(c(0, 0.0, 0.3, 0.5), "lines")  # 上右下左
mg_2 <- unit(c(0, 0.5, 0.3, 0.0), "lines")
mg_3 <- unit(c(0, 0.0, 2.3, 0.0), "lines")
mg_l <- margin(0, 0, 0, 0, 'lines')
text_x <- rep(2, nrow(data_use))
text_y <- 1:nrow(data_use)
text_lab <- gsub('岁', '', data_use$group_name)
text_lab <- gsub('及以上', '+', text_lab)
title_x <- 2
title_y <- 2
title_lab <- '2010年人口普查'# 图形
p_1 <- ggplot(data_use) +geom_bar(aes(group, male), fill = 'skyblue', stat="identity", position="dodge") +scale_y_continuous(limits = lim_1, breaks = bre_1, labels = lab_1) +scale_x_continuous(limits = c(0, (nrow(data_use) + 1)), breaks = 1:nrow(data_use), labels = NULL, expand = expand_scale(), position = 'top') +theme(plot.margin = mg_1, axis.text = element_text(margin = mg_l)) +xlab(NULL) +ylab('男(万人)') +coord_flip() + guides(fill = FALSE)p_2 <- ggplot(data_use) +geom_bar(aes(group, female), fill = 'firebrick1', stat="identity", position="dodge") +scale_y_continuous(limits = lim_2, breaks = bre_2, labels = lab_2) +scale_x_continuous(limits = c(0, (nrow(data_use) + 1)), breaks = 1:nrow(data_use), labels = NULL, expand = expand_scale()) +theme(plot.margin = mg_2, axis.text = element_text(margin = mg_l)) +xlab(NULL) +ylab('女(万人)') +coord_flip() +guides(fill = FALSE)p_3 <- ggplot() + geom_text(aes(x = text_x, y= text_y, label = text_lab), size = 3.6) +scale_x_continuous(limits = c(0, 4), breaks = NULL, expand = expand_scale()) +scale_y_continuous(limits = c(0, (nrow(data_use) + 1)), breaks = NULL, expand = expand_scale()) +labs(x = NULL, y = NULL) + theme(plot.margin = mg_3,axis.text = element_text(margin = mg_l),panel.grid.major =element_blank(),panel.grid.minor = element_blank(),panel.background = element_blank()) p_4 <- ggplot() + geom_text(aes(x = title_x, y= title_y, label = title_lab), size = 6) +scale_x_continuous(limits = c(0, 4), breaks = NULL, expand = expand_scale()) +scale_y_continuous(limits = c(0, 4), breaks = NULL, expand = expand_scale()) +labs(x = NULL, y = NULL) + theme(plot.margin = mg_l,axis.text = element_text(margin = mg_l),panel.grid.major =element_blank(),panel.grid.minor = element_blank(),panel.background = element_blank()) # 分面画图
grid.newpage()  ##新建页面
pushViewport(viewport(layout = grid.layout(12, 11)))
print(p_1, vp = vplayout(2:12, 1:5))
print(p_2, vp = vplayout(2:12, 7:11))
print(p_3, vp = vplayout(2:12, 6))
print(p_4, vp = vplayout(1, 1:11))

  我们对上面代码中用到的函数简单进行一下总结:

  coord_flip函数用于使条形图横向分布;

  scale_x_continuous和scale_y_continuous函数用于设置坐标轴标签,其中limits、breaks、labels参数分别表示坐标轴的取值范围、标签位置以及标签文字,expand参数表示实际作图时坐标轴在limits的基础上向外扩展的大小。

  xlab和ylab函数用于设置坐标轴标题,无标题需填NULL。

  theme函数用于对绘图的整体进行调整,其中参数plot.margin设置作图的边界,axis.text设置坐标轴标签的文本格式,panel.grid.minor和       panel.grid.major设置绘图背景网格线,panel.background设置背景颜色。

R语言可视化:使用ggplot2绘制人口金字塔相关推荐

  1. R语言可视化包ggplot2绘制分组的条形图(bar plot、柱状图)实战:多变量柱状图

    R语言可视化包ggplot2绘制分组的条形图(bar plot.柱状图)实战:多变量柱状图 目录

  2. R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression Line)

    R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression Line) 目录 R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression ...

  3. R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Group)

    R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Group) 目录 R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Grou ...

  4. R语言可视化包ggplot2绘制平滑曲线、回归线实战:geom_smooth() 函数

    R语言可视化包ggplot2绘制平滑曲线.回归线实战:geom_smooth() 函数 目录 R语言可视化包ggplot2绘制平滑曲线.回归线实战:geom_smooth() 函数

  5. R语言可视化包ggplot2绘制甘特图(gantt chart)实战

    R语言可视化包ggplot2绘制甘特图(gantt chart)实战 目录 R语言可视化包ggplot2绘制甘特图(gantt chart)实战 #仿真数据

  6. R语言可视化包ggplot2绘制饼图(pie chart)实战

    R语言可视化包ggplot2绘制饼图(pie chart)实战 目录 R语言可视化包ggplot2绘制饼图(pie chart)实战 #ggplot2绘制一个基本饼图

  7. R语言可视化包ggplot2绘制排序条形图实战:按照分类因子排序、按照数值排序

    R语言可视化包ggplot2绘制排序条形图实战:按照分类因子排序.按照数值排序 目录

  8. R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战

    R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战 目录 R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战 #导入包

  9. R语言可视化包ggplot2包绘制多个图形并将多个图像垂直堆叠c成一个图像实战(grid.arrange)

    R语言可视化包ggplot2包绘制多个图形并将多个图像垂直堆叠c成一个图像实战(grid.arrange) 目录

  10. R语言可视化【ggplot2】

    R语言可视化[ggplot2] 文章的文字/图片/代码部分/全部来源网络或学术论文或课件,文章会持续修缮更新,仅供学习使用. 目录 R语言可视化[ggplot2] 一.可视化介绍 二.不同情况适用的图 ...

最新文章

  1. 近期苹果、Facebook等科技巨头股价缘何不断下跌?
  2. 去除文本框点击的背影
  3. Linux LNMP环境的搭建 详细步骤
  4. 漂亮的NavMenu导航控件
  5. 第0章:战胜恐惧和懊悔
  6. 云服务器的主要用途是什么?
  7. (2)python_enumerate
  8. 服务器是怎样进行中断的,企业如何减少服务器中断风险
  9. ASP.NET 主题和外观
  10. UVA 1153 Keep the Customer Satisfied 顾客是上帝(贪心)
  11. 第二章 01 节 常用信号及其基本特征
  12. oracle12 client 64位,oracle官方64位客户端-instantclient-basic-windows.x64-12.2.0.1.0.zip
  13. Android 设备接入扫码枪,Android 设备接入扫码枪
  14. Linux db2 54048,db2中SQLCODE=-1585,SQLSTATE=54048报错问题的解决
  15. 科研学术论文搜索利器:Publish or Perish
  16. spring boot 访问路径404是会转到/error路径,倒是拦截器失效
  17. java获取月和日_java – 如何获取dateformat来大写月和日
  18. 区块链超级记帐本架构概览
  19. 文献计量之洛特卡定律
  20. 周鸿袆:教你打造十页完美商业计划书

热门文章

  1. echarts 象形柱图pictorialBar
  2. GB28181协议视频安防平台EasyGBS国标配置查询步骤及信令示例
  3. 最快往服务器拷贝数据,往小米路由器硬盘拷贝数据最快速的方法
  4. Design an Instagram
  5. 计算机基础知识复习题,计算机基础知识理论复习题及答案.doc
  6. 采样频率为什么一定要大于原始信号两倍
  7. 【POJ3180 奶牛舞会】
  8. 请编写C程序,输入5个不同的且为字符格式的学生编号,将其先由大到小排序,再将最大的学生编号和最小的学生编号互换位置,然后输出此时5位学生的编号。 输Л 输入5位学生的编号(只含数字字、英文字母或空格)
  9. python 矩阵乘法 跳过nan_奇怪的numpy矩阵运算bug
  10. 云桌面与PC之间,优先选谁?