首页 理论教育 基于ggplot分面生成政经数据可视化

基于ggplot分面生成政经数据可视化

时间:2023-11-19 理论教育 版权反馈
【摘要】:严格来讲,分面生成的多个子图表并不是独立的,它们共同组成一个完整的图表。在进行分面操作时,我们常用到facet_wrap函数。当labeller="label_both"或labeller=label_both时,分面变量的名称和取值都会显示。下面我们用营商环境数据来展示分面操作。

基于ggplot分面生成政经数据可视化

一、facet_wrap

我们可以根据数据中的变量把数据拆分成多组,并对每一组数据绘制同类型的子图表,这样的操作就是分面。严格来讲,分面生成的多个子图表并不是独立的,它们共同组成一个完整的图表。

在进行分面操作时,我们常用到facet_wrap函数。它的参数有:

facets:分面变量。例如,如果根据变量f对数据进行分组并绘制分面图,就应设定facets=vars(f),亦可写成facets=~f或facets="f"的形式;如果依次根据变量f和g分面,就设定facets=vars(f, g)、facets=~f+g或facets=c ("f", "g")。

nrow、ncol:行数和列数。子图表像矩阵中的单元格一样排列,因此我们可以设定把它们排成几行几列。

scales:控制坐标轴的一致性。默认状态下("fixed"),所有子图表的坐标轴都是一样的。如果scales="free",则每个子图表会根据自身包含的数据范围自动确定坐标轴;如果scales="free_x",则只有每个图表的Y轴会保持一致;如果scales="free_y",则只有X轴会保持一致。

labeller:对分类标签的显示方式进行微调。当labeller="label_value"(字符)或labeller=label_value(函数)时,子图表在标注自身的分类时,只显示用于分面变量的取值。当labeller="label_both"或labeller=label_both时,分面变量的名称和取值都会显示。我们可通过?label_value查到label_value等多个函数的用法。另外,labeller还可指向用户自己编写的函数,例如, labeller=function(x) label_both(x, sep="=")将把变量名和取值之间的冒号改为等号。

dir:子图表排列的方向。默认方向为水平方向("h"),可改为垂直方向("v")。

strip.position:分类标签的位置。可选项为"top"(默认)、"bottom"、"left"、"right"。

当进行分面时,theme函数中的可调整项目为:

strip.text、strip.text.x、strip.text.y:调整所有分面标签、水平放置的分面标签、垂直放置的分面标签的文字,均使用element_text。

strip.background:调整分面标签文字框的背景,需使用element_rect。

下面我们用营商环境数据来展示分面操作(图7-1-1)。

library(plothelper)

library(ggforce) # 使用geom_shape

library(dplyr) # 使用group_by和summarize

dat=read.csv("db 5dim.csv", row.names=1) # 课件中的文件

dat=as.data.frame(as.table(as.matrix(dat)))

colnames(dat)=c("Country", "Item", "Score")

Item=gsub("\\.", " ", dat$Item) # 调整项目名称字符

Item=scales::wrap_format(18)(Item)

dat$Item=factor(Item)

n=length(unique(dat$Country)) # 国家数

nitem=length(unique(dat$Item)) # 项目数

lab_name=levels(dat$Item) # 项目名称

dat=data.frame(dat, Item2=as.numeric(dat$Item))

# 代表满分的条形会被无差别地画在每个子图表中所以不要为它添加用于分面的国家名

full=rectxy(x=0, y=1: nitem, a=100, b=0.8, xytype="left")

# 代表分数的条形需添加用于分面的国家名

score=rectxy(x=0, y=dat$Item2, a=dat$Score, b=0.8, xytype="left")

score=data.frame(score, Country=rep(dat$Country, each=4))

p=ggplot(score)+

facet_wrap(vars(Country))+

geom_shape(data=full, aes(x=x, y=y, group=g), fill="khaki", alpha=0.8, radius=unit(3, "mm"))+

geom_shape(aes(x=x, y=y, group=g), fill="coral1", radius=unit(3,"mm"))+

geom_text(data=dat, aes(x=Score, y=Item2, label=round(Score, 0)), family="serif", fontface=3, size=5, hjust=1.2, color="white")

p+scale_y_continuous(name=NULL, breaks=1: nitem, labels=lab_name, expand=expansion(0.02))+

scale_x_continuous(name=NULL, breaks=c(0, 60, 80, 100), expand= expansion(c(0.01, 0.1)))+

labs(title="Business Environment Evaluation")+

theme(panel.background=element_blank(),

panel.grid=element_blank(),

axis.ticks=element_line(color="powderblue"),

axis.text=element_text(size=14, family="serif", color="powderblue", lineheight=0.8),

strip.text=element_text(face=3, family="serif", color="powderblue", size=18, hjust=0),

strip.background=element_blank(),

plot.background=element_rect(fill="grey25", color="grey25"),(www.xing528.com)

plot.title=element_text(size=21, family="serif", color="powderblue")

)

图7-1-1 使用facet_wrap进行分面

## 注意labeller函数的另一种用法用于分面的变量原本是G但通过构建查询表check可以把"1"显示为"A"把"2"显示为"B"……

dat=data.frame(x=0, y=0, lab=letters[1: 4], G=1: 4)

check=c("1"="A", "2"="B", "3"="C", "4"="D")

ggplot(dat)+geom_text(aes(x, y, label=lab))+

facet_wrap(vars(G), labeller=labeller(G=check))

#==========

# 练习在分面时为子图表添加不同的文字和渐变矩阵

#==========

# 为不同的子图表添加不同的文字时需要先生成一个包含分面变量的数据框

add_lab=data.frame(Country=c("India", "United States", "Germany","Cambodia"), text=c("c1", "c2", "c3", "c4"))

p+geom_text(data=add_lab, aes(x=50, y=3, label=text), size=8)

# 添加渐变矩阵

m1=matrix(c("red", "blue"))

m2=matrix(c("orange", "green"))

m3=matrix(c("black", "cyan"))

m4=matrix(c("purple", "yellow"))

# 用annotation_raster无法为不同子图表添加不同的渐变矩阵

p+annotation_raster(m1, xmin=0, xmax=50, ymin=0, ymax=3, interpolate= TRUE)

# 使用plothelper包中的geom_multi_raster需要先生成一个tibble数据框

add_raster=tibble::tibble(Country=c("India", "United States","Germany", "Cambodia"), xmin=0, xmax=50, ymin=0, ymax=3, r=list(m1, m2, m3, m4))

p+geom_multi_raster(data=add_raster, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, raster=r))

二、facet_grid

当两个变量f和g同时用于分面时,我们既可以如上文所述使用facet_wrap,也可使用facet_grid。后者的参数有:

rows、cols:用于按行、按列排列子图表的变量,写成facet_grid(rows=vars(f), cols=vars(g))或facet_grid(f~g)的形式。行和列都可以接受一个以上的值,例如:facet_grid(f~g+h)。

scales、labeller:与facet_wrap中的同名参数用法相同。

space:每个子图表所占的面积,是否根据其坐标轴范围自动伸缩。默认为不自动伸缩,但可改为"free_x"(X轴自动伸缩)、"free_y"(Y轴自动伸缩)或"free"(X轴和Y轴均自动伸缩)。

switch:标签的位置默认为上方和右方。设置switch为"x"、"y"或"both"可对这两个位置进行调整。

我们用一份关于美国共和党总统竞选初选的调查数据进行示范。数据中的PRIMVOTE为受访者支持的候选人,REGION和GENDER是分面变量。

dat=read.csv("primary.csv", row.names=1)# 课件中的文件

# 整理数据

dat=group_by(dat, PRIMVOTE, REGION, GENDER)

dat=summarize(dat, Number=n())

dat=as.data.frame(dat)

# 使用facet_wrap

ggplot(dat)+coord_flip()+

facet_wrap(vars(REGION, GENDER), nrow=2, labeller=function(x) label_value(x, multi_line=FALSE))+

geom_bar(aes(x=PRIMVOTE, y=Number), stat="identity")

# 使用facet_grid

ggplot(dat)+coord_flip()+

facet_grid(rows=vars(REGION), cols=vars(GENDER), switch="y")+

geom_bar(aes(x=PRIMVOTE, y=Number), stat="identity")

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈