首页 理论教育 基于ggplot的政经数据可视化:主题设置

基于ggplot的政经数据可视化:主题设置

时间:2023-11-19 理论教育 版权反馈
【摘要】:主题,是指图表背景色、面板背景色、坐标轴的宽度等附属元素的属性。图表是否美观、合理,在一定程度上取决于主题的设置。本节分为三个部分,首先介绍成套主题,其次介绍可在theme函数中直接修改的主题,最后介绍在theme函数中通过element_*系列函数修改的主题。为了简化操作,程序编写者设计了一些成套的主题。

基于ggplot的政经数据可视化:主题设置

主题,是指图表背景色、面板背景色、坐标轴的宽度等附属元素的属性。图表是否美观、合理,在一定程度上取决于主题的设置。本节分为三个部分,首先介绍成套主题,其次介绍可在theme函数中直接修改的主题,最后介绍在theme函数中通过element_*系列函数修改的主题。

一、成套主题

主题设置涉及许多项目,有时我们只有对多个项目同时进行修改,才会看到理想的效果。比如,我们把背景色改为黑色,那么就应该同时把坐标轴标题之类的文字由默认的黑色改成浅色,这样才能让这些文字显示出来。为了简化操作,程序编写者设计了一些成套的主题。

library(ggplot2)

dat=read.csv("ip small.csv", row.names=1) # 前边的章节使用过的工业生产指数数据

p=ggplot(data=dat, aes(ID, Value, color=Area))+geom_line(size=1)

## ggplot2中的内置主题

p+theme_bw() # 黑白主题

p+theme_bw()+theme(panel.background=element_rect(fill="#DFCCFF")) #

使用成套主题后仍可以用后边会讲到的theme函数修改个别属性

p+theme_minimal() # 简单主题

p+theme_classic() # 经典主题

p+theme_void() # 去掉各种附属元素我们以后将多次用到这个设置

ggplot()+geom_blank(data=dat, aes(ID, Value)) # geom_blank是图层函数而并非主题设置函数笔者将其放在这里是因为它能起到根据数据生成画布的作用它的功能相当于用数据画一个散点图只不过所有的点都是透明的

## ggthemes等R包也提供了一些有用的成套主题

# install.packages("ggthemes")

library(ggthemes)

p+theme_economist() #经济学人风格

p+theme_par() # 模仿base作图系统

p+theme_stata() # 模仿Stata

p+theme_wsj() #华尔街日报风格

二、theme函数:直接修改

用theme函数对主题进行修改的操作可分为两类。

dat=read.csv("ip big.csv", row.names=1) # 前边的章节使用过的工业生产指数数据

dat$Date=as.Date(dat$Date)

# 为进行示范我们有意生成两个图例

p=ggplot(dat)+geom_line(aes(Date, Value, color=Area, linetype= Area), size=1.2)+

scale_color_discrete(guide=guide_legend(title="legend 1"))+

scale_linetype_discrete(guide=guide_legend(title="legend 2"))

# 第1类直接为参数指定一个值

p+theme(aspect.ratio=0.5)

# 第2类用参数指定由element_*函数生成的值

p+theme(axis.text.x=element_text(angle=30, size=12))

下面我们首先介绍直接设定的方法。

总结起来,能够直接设置的项目有:

## legend.position图例位置

# 选项为"none""bottom""top""left""right"也可以是长度为2的向量此时给出的数值不是坐标值而是图例的中心点在整个面板中的位置水平位置和垂直位置均用0至1的数值来表示因此c(0.5, 0.5)就代表把图例画在面板中间

p+theme(legend.position="bottom")

p+theme(legend.position=c(0.5, 0.5)) # 整个图例的中心位于面板左边

## legend.direction图例中格子的排列方向

# 选项为"horizontal"或"vertical"当图表包含多个图例时如果只想修改单个图例请在guide_legend/colorbar里修改direction参数

p+theme(legend.position="bottom", legend.direction="vertical")

## legend.spacing多个图例之间的距离

# 用unit函数进行设定并选择适当的数值和"cm""inches""mm"等单位,以免把图例挤到图表外

p+theme(legend.position="bottom", legend.direction="vertical", legend.spacing=unit(3, "cm"))

## legend.spacing.xlegend.spacing.y调整图例标题格子或标尺标签之间的距离

# 用unit函数调整

p+theme(legend.spacing.y=unit(10, "mm"), legend.spacing.x=unit(5,"mm")) # 此处的图例标题在其他部分的上边用legend.spacing.y调整标签在格子的右边用legend.spacing.x调整

ggplot(dat)+geom_line(aes(ID, Value, color=Area))+

scale_color_discrete(guide=guide_legend(label.position="top"))+

theme(legend.spacing.y=unit(2, "mm")) # 此处的图例标题在标签上边标签在格子上边因此均用legend.spacing.y调整

## legend.key.sizelegend.key.widthlegend.key.height同时修改格子的宽度和高度修改宽度仅修改高度

# 用unit函数调整

p+theme(legend.key.width=unit(2, "cm"), legend.key.height= unit(0.3, "cm"))

## legend.title.alignlegend.text.align图例标题和标签的对齐方式 # 取值为0至1之间的数值

p+theme(legend.title.align=0.5, legend.text.align=1)

## legend.justification对整个图例的位置进行调整

# 当图例在左边或右边时可选项为"center""top"或"bottom"当图例在上边或下边时可选项为"center""left"或"right"

p+theme(legend.justification="top")

p+theme(legend.position="bottom", legend.direction="vertical", legend.justification="left")

# 取值也可为在0至1之间长度为2的向量当图例在左边或右边时仅第二个数值有效用于调整上下位置当图例在上边或下边时仅第一个数值起作用用于调整左右位置

p+theme(legend.justification=c(999, 0))

p+theme(legend.position="bottom", legend.direction="vertical",legend.justification=c(0.2, 999))

## legend.box多个图例的排列

# 当为"horizontal"时所有图例在同一行当为"vertical"时在同一列

p+theme(legend.position="bottom", legend.box="vertical")

## legend.box.spacing图例到绘图区的距离

# 用unit函数调整正值使图例远离面板负值使两者贴近不过负值可能会使面板无法完整显示

p+theme(legend.box.spacing=unit(-2, "cm"))

## panel.ontop是否把面板放在最上层

# 改变此设置唯一有意义的情境就是用半透明从半透明的面板改变色调

p+theme(panel.background=element_rect(fill=scales::alpha("purple", 0.1)), panel.ontop=TRUE)

## axis.ticks.length坐标轴刻度线的长度

# 用unit函数调整

p+theme(axis.ticks.length=unit(0.2, "cm"))

## plot.margin画布边缘

# 用unit函数调整需依次给出上左的数值注意这个参数会修改整个图表的边缘而不会修改各个分面的边缘后边的章节会介绍分面的操作

p+theme(legend.position="bottom", legend.box="vertical", plot. margin=unit(c(0, 0.5, 0, 0), "inches")) # 对边缘作调整常用于确保坐标轴标签可以完整显示

## plot.tag.position标记的位置

# 选项为"top""topleft"默认)、"topright""left""right""bottom""bottomleft""bottomright"这八个位置

p+labs(tag="Figure 1")+theme(plot.tag.position="left")

## aspect.ratio面板的高宽比

# 请参阅本章第一节讲解coord_fixed函数的部分

## plot.title.position and plot.caption.position标题包含副标题和注释的对齐位置

# 选项为"panel"默认或"plot"

p+labs(title="ABCDE", subtitle="abcde")+theme(plot.title.position="plot")

三、theme函数:用element_*函数修改

初学ggplot的读者可能会对下面要讲解的主题设置方式不太习惯。比如,我们要修改标题类文字的大小时,不能使用title.size=20之类的代码,而必须使用title=element_text(size=20)。在程序编写者看来,图表各种附属元素均可以被归为文字、线条、矩形三类。因此,调整背景色就相当于调整矩形的填充色,调整坐标轴的线形就相当于调整线条的线形。就此而言,用element_text、element_line和element_line函数进行调整反而让人感到更加明晰。

## 此类主题设置的书写形式是

p+theme(panel.background=element_rect(fill="yellow"))

# 待修改的项目是panel.background即面板背景色);对其进行修改相当于对矩形填充色进行修改因此应使用element_rect待修改的属性是填充色因此参数为fill

# 注意多数情况下我们可按任意顺序调整主题不过也有例外

p+theme_void()+theme(panel.background=element_rect(fill="yellow")) #正确先去掉各种元素再修改元素

p+theme(panel.background=element_rect(fill="yellow"))+theme_void() #错误先修改元素再去掉元素这会导致上一步的修改无效

# 用element_blank可删除我们指定的元素而不会像theme_void那样删除多个附属元素

p+theme(panel.background=element_blank(), axis.title=element_blank()) # 删除面板和坐标轴标题

1. element_text

用element_text修改的附属元素有:

text:文字类元素。注意:并非文字的所有属性均可作一次性调整,比如,当使用text调整大小和颜色时,坐标轴标签的颜色就不会被改变。

title:标题类文字。

plot.title、plot.subtitle、plot.caption、plot.tag、legend.title:图表标题、副标题、注释、标记、图例标题。

axis.title、axis.title.x、axis.title.x.top、axis.title.y、axis.title.y.right:坐标轴标题、X轴标题、上侧X轴标题、Y轴标题、右侧Y轴标题。

axis.text、axis.text.x、axis.text.x.top、axis.text.y、axis.text.y.right:坐标轴标签、X轴标签、上侧X轴标签、Y轴标签、右侧Y轴标签。

legend.text,图例标签。

■ 可修改的属性为:

family:选项为:"sans"(默认), "serif", "mono"。

face:粗体或斜体。1为普通,2为粗体,3为斜体,4为粗斜体。

color:文字颜色。

size:文字大小。

angle,旋转角度。Y轴标题默认旋转90度。

hjust、vjust:水平调整和垂直调整。取值越大文字越靠上(右),取值越小文字越靠下(左)。大于1或小于0的取值可能导致文字显示不完整。

lineheight:行高。默认值为0.9。

dat=read.csv("ip small.csv", row.names=1) # 前边的章节使用过的工业生产指数数据

dat$Date=as.Date(dat$Date)

p=ggplot(dat)+geom_line(aes(Date, Value, color=Area), size=1.2)+

labs(title="Industrial Production Index", subtitle="2011/7 ~ 2013/6", caption="Using package ggplot2")

p+theme(text=element_text(color="orange", size=20)) # 所有文字类项目

p+theme(title=element_text(color="orange", size=20)) # 所有标题类文字

p+theme(axis.title.y=element_text(angle=0, vjust=0.5)) # 将Y轴标题改为水平放置同时用vjust将其放到中部

p+labs(y="V\na\nl\nu\ne")+theme(axis.title.y=element_text (angle=0, vjust=0.5, lineheight=0.7)) # Y轴标题垂直排列

# 多项调整(www.xing528.com)

p+theme(

text=element_text(size=16),

axis.text.x=element_text(angle=30), # 旋转X轴标签

legend.text=element_text(face=4, color="red"), # 修改图例标签

plot.title=element_text(vjust=-12), # 使标题贴近甚至进入面板

plot.subtitle=element_text(vjust=-13),

plot.caption=element_text(hjust=0.5) # 调整注释的位置

)

2. element_line

用element_line修改的附属元素有:

line:所有线条类元素。注意:并非文字的所有属性均可作一次性调整,比如,次要网格线的粗细不能用line设置。

axis.ticks、axis.ticks.x、axis.ticks、axis.ticks.x.top、axis.ticks.y.right:坐标轴刻度线、X轴刻度线、Y轴刻度线、上侧X轴刻度线、右侧Y轴刻度线。

axis.line、axis.line.x、axis.line.y、axis.line.x.top、axis.line.y.right:坐标轴线、X轴线、Y轴线、上侧X轴线、下侧Y轴线。

panel.grid、panel.grid.major、panel.grid.minor、panel.grid.major.x、panel. grid.major.y、panel.grid.minor.x、panel.grid.minor.y:网格线、主要网格线、次要网格线,以及与X轴和Y轴相对应的主要、次要网格线。

可修改的属性为:color、size、linetype、lineend、arrow,请参阅前文对geom_line的说明。p+theme(

panel.grid=element_blank(),

axis.line=element_line(lineend="square", color="red", size=3, arrow=grid::arrow())

) # 默认状态下,ggplot并不显示坐标轴,仅当对坐标轴进行调整后,它才会显示出来p+theme(

panel.grid=element_line(linetype=2), # 所有网格线的线形

panel.grid.major.x=element_line(color="red"),

panel.grid.minor.y=element_line(color="green")

)

3. element_rect

用element_rect修改的附属元素为:

plot.background:全图背景。

panel.background:面板背景。注意:如果要给面板加边框,在此设置color="black"(或其他颜色)即可。

legend.box.background、legend.background、legend.key:图例区(容纳多个图例的区域)背景、单个图例背景、图例格子背景。

■ 可修改的属性为:

fill:填充色。如果不需要填充色,可设为NA。注意:此处没有alpha参数,如需使用半透明颜色,可用scales::alpha事先生成。

size、linetype、color:轮廓线的粗线、线形、颜色。

## 请观察本例中涉及图例的修改

ggplot()+geom_point(aes(x=c("a", "b", "c"), y=1: 3, shape=c("a", "b","c"), color=1: 3))+

theme(

legend.box.background=element_rect(fill="blue", color="green", size=5),

legend.background=element_rect(fill="orange", color="yellow", size=2),

legend.key=element_rect(fill="purple", color="red", size=2)

)

# 综合使用各项主题设置图3-3-1

p+scale_color_manual(values=c("Machinery"="black", "Computer"="goldenrod1"), guide=guide_legend(override.aes=list(size=2)))+

theme(panel.background=element_blank(),

plot.background=element_rect(fill="steelblue3", color="steelblue3"),

legend.box.background=element_blank(),

legend.background=element_blank(),

legend.key=element_blank(),

text=element_text(color="palegreen1", size=20, family="serif"), plot.title=element_text(size=22),

axis.text=element_text(color="palegreen1"),

axis.title.y=element_text(angle=0, vjust=0.5),

panel.grid=element_blank(),

panel.grid.major.y=element_line(color="palegreen1", linetype=2),

axis.ticks=element_line(color="palegreen1")

)

图3-3-1 综合使用各项主题设置

#==========

# 练习随机散点图

#==========

# 观察效果图图3-3-2可知各组散点在靠近角落的地方较密集而在靠近图表中间的位置较稀疏这种效果是通过生成呈截断正态分布的数值实现的

library(truncnorm)

seed=1 # 设置随机种子

n=270 # 每组散点的个数

SD=3 # 正态分布的标准差

maxsize=17 # 点的最大尺寸

co=c("blue3", "green", "yellow", "red")

# 生成数据

set.seed(seed); x1=rtruncnorm(n, a=0, b=5, mean=0, sd=SD); seed= seed+1

set.seed(seed); y1=rtruncnorm(n, a=0, b=5, mean=0, sd=SD); seed= seed+1

set.seed(seed); s1=runif(n, 1, maxsize); seed=seed+1

set.seed(seed); x2=rtruncnorm(n, a=5, b=10, mean=10, sd=SD); seed= seed+1

set.seed(seed); y2=rtruncnorm(n, a=0, b=5, mean=0, sd=SD); seed= seed+1

set.seed(seed); s2=runif(n, 1, maxsize); seed=seed+1

set.seed(seed); x3=rtruncnorm(n, a=5, b=10, mean=10, sd=SD); seed= seed+1

set.seed(seed); y3=rtruncnorm(n, a=5, b=10, mean=10, sd=SD); seed= seed+1

set.seed(seed); s3=runif(n, 1, maxsize); seed=seed+1

set.seed(seed); x4=rtruncnorm(n, a=0, b=5, mean=0, sd=SD); seed= seed+1

set.seed(seed); y4=rtruncnorm(n, a=5, b=10, mean=10, sd=SD); seed= seed+1

set.seed(seed); s4=runif(n, 1, maxsize)

p=ggplot()+theme_void()+ # 删除附属元素

theme(aspect.ratio=1, plot.background=element_rect(fill="black", color=NA))+

coord_cartesian(xlim=c(0, 10), ylim=c(0, 10), expand=FALSE)+

geom_point(aes(x1, y1), alpha=0.2, size=s1, color=co[1])+

geom_point(aes(x2, y2), alpha=0.2, size=s2, color=co[2])+

geom_point(aes(x3, y3), alpha=0.2, size=s3, color=co[3])+

geom_point(aes(x4, y4), alpha=0.2, size=s4, color=co[4])

p+geom_text(aes(x=5, y=5, label="Science makes life colorful"),color="white", fontface=3, size=7, family="serif") # 后面的章节会讲到用于添加文字的geom_text函数

图3-3-2 随机散点图

#==========

# 练习颠倒Y轴的图表

#==========

# 文件terror ym.csv记录了1968年至2009年期间按月统计的世界各地恐怖袭击伤亡情况我们用它来绘制一个颠倒Y轴的图表图3-3-3

library(reshape2)

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

dat=dat[384: 503, ] # 只使用2000年至2009年的数据

dat=melt(dat, id.vars="Date", measure.vars=c("Fatalities", "Injuries"))

# 转化成ggplot接受的形式

dat$Date=as.Date(dat$Date) # 转化成Date对象以便使用scale_x_date

# 第一个年份显示四位数字后边的只显示两位数字

pos=paste(2000: 2009, "-01-01", sep="")

true_lab=substr(2000: 2009, start=3, stop=4)

true_lab[1]="2000"

# 本例使用的geom_area用于绘制带阴影的曲线后边的章节将对其进行详细介绍

p=ggplot(dat)+

geom_area(aes(x=Date, y=value, alpha=variable), fill="red", position=position_identity())+

scale_alpha_manual(values=c("Fatalities"=1, "Injuries"= 0.4))+

scale_y_reverse(name=NULL)+ # 颠倒Y轴

scale_x_date(name=NULL, breaks=as.Date(pos), labels=true_lab, position="top") # 将X轴放到顶部

p+theme_void()+

labs(title="Monthly Fatalities and Injuries of\n Terrorist Attacks 2000 ~ 2009\n")+

theme(

text=element_text(family="mono"),

axis.text=element_text(size=15, color="grey70"),

plot.title=element_text(color="grey70", size=18, hjust=1),

legend.title=element_blank(),

legend.text=element_text(color="white", size=14),

plot.background=element_rect(fill="grey15", color=NA),

plot.margin=unit(rep(4, 4), "mm"),

axis.ticks.x.top=element_line(color="grey30"),

axis.ticks.length=unit(2, "mm"),

panel.grid.major.y=element_line(color="grey30", linetype= 3),

legend.position="bottom"

)

图3-3-3 颠倒Y轴的图表

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

我要反馈