R语言可视化:使用ggplot2绘制人口金字塔
人口金字塔是进行人口数据可视化时常用的一种统计图形,可以形象地描述人口年龄和性别的分布情况。最近工作上经常处理人口数据,于是试着使用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绘制人口金字塔相关推荐
- R语言可视化包ggplot2绘制分组的条形图(bar plot、柱状图)实战:多变量柱状图
R语言可视化包ggplot2绘制分组的条形图(bar plot.柱状图)实战:多变量柱状图 目录
- R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression Line)
R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression Line) 目录 R语言可视化包ggplot2绘制线性回归模型曲线实战( Linear Regression ...
- R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Group)
R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Group) 目录 R语言可视化包ggplot2绘制分组回归线实战(Regression Line by Grou ...
- R语言可视化包ggplot2绘制平滑曲线、回归线实战:geom_smooth() 函数
R语言可视化包ggplot2绘制平滑曲线.回归线实战:geom_smooth() 函数 目录 R语言可视化包ggplot2绘制平滑曲线.回归线实战:geom_smooth() 函数
- R语言可视化包ggplot2绘制甘特图(gantt chart)实战
R语言可视化包ggplot2绘制甘特图(gantt chart)实战 目录 R语言可视化包ggplot2绘制甘特图(gantt chart)实战 #仿真数据
- R语言可视化包ggplot2绘制饼图(pie chart)实战
R语言可视化包ggplot2绘制饼图(pie chart)实战 目录 R语言可视化包ggplot2绘制饼图(pie chart)实战 #ggplot2绘制一个基本饼图
- R语言可视化包ggplot2绘制排序条形图实战:按照分类因子排序、按照数值排序
R语言可视化包ggplot2绘制排序条形图实战:按照分类因子排序.按照数值排序 目录
- R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战
R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战 目录 R语言可视化包ggplot2绘制Bump Chart(凹凸图)实战 #导入包
- R语言可视化包ggplot2包绘制多个图形并将多个图像垂直堆叠c成一个图像实战(grid.arrange)
R语言可视化包ggplot2包绘制多个图形并将多个图像垂直堆叠c成一个图像实战(grid.arrange) 目录
- R语言可视化【ggplot2】
R语言可视化[ggplot2] 文章的文字/图片/代码部分/全部来源网络或学术论文或课件,文章会持续修缮更新,仅供学习使用. 目录 R语言可视化[ggplot2] 一.可视化介绍 二.不同情况适用的图 ...
最新文章
- 近期苹果、Facebook等科技巨头股价缘何不断下跌?
- 去除文本框点击的背影
- Linux LNMP环境的搭建 详细步骤
- 漂亮的NavMenu导航控件
- 第0章:战胜恐惧和懊悔
- 云服务器的主要用途是什么?
- (2)python_enumerate
- 服务器是怎样进行中断的,企业如何减少服务器中断风险
- ASP.NET 主题和外观
- UVA 1153 Keep the Customer Satisfied 顾客是上帝(贪心)
- 第二章 01 节 常用信号及其基本特征
- oracle12 client 64位,oracle官方64位客户端-instantclient-basic-windows.x64-12.2.0.1.0.zip
- Android 设备接入扫码枪,Android 设备接入扫码枪
- Linux db2 54048,db2中SQLCODE=-1585,SQLSTATE=54048报错问题的解决
- 科研学术论文搜索利器:Publish or Perish
- spring boot 访问路径404是会转到/error路径,倒是拦截器失效
- java获取月和日_java – 如何获取dateformat来大写月和日
- 区块链超级记帐本架构概览
- 文献计量之洛特卡定律
- 周鸿袆:教你打造十页完美商业计划书
热门文章
- echarts 象形柱图pictorialBar
- GB28181协议视频安防平台EasyGBS国标配置查询步骤及信令示例
- 最快往服务器拷贝数据,往小米路由器硬盘拷贝数据最快速的方法
- Design an Instagram
- 计算机基础知识复习题,计算机基础知识理论复习题及答案.doc
- 采样频率为什么一定要大于原始信号两倍
- 【POJ3180 奶牛舞会】
- 请编写C程序,输入5个不同的且为字符格式的学生编号,将其先由大到小排序,再将最大的学生编号和最小的学生编号互换位置,然后输出此时5位学生的编号。 输Л 输入5位学生的编号(只含数字字、英文字母或空格)
- python 矩阵乘法 跳过nan_奇怪的numpy矩阵运算bug
- 云桌面与PC之间,优先选谁?