一、geom_text和geom_label
ggplot系统中用于添加文字的基本函数是geom_text和geom_label。两个函数有着相似的参数,前者用于添加纯文字,后者用于添加标签,即带背景色的文字。两个函数的参数有:
●label:待添加的文字。
●size、color、alpha:文字大小、颜色、透明度。
●family:字体。R自带的字体为"sans"、"serif"、"mono",以及我们通过在文档?Hershey中可查到的若干字体。
●fontface:粗体或斜体。1为普通,2为粗体,3为斜体,4为粗斜体。
●lineheight:行高,默认值为1.2。
●angle:倾斜角度。取值为0至360。
●vjust:垂直调整。默认值0.5代表不偏移。注意:偏移量跟文字大小有关:在同样的偏移量下,较大的文字偏移得较多。参数值亦可为"top"、"center"(相当于0.5)、"bottom"。例如,当vjust为"top"时,坐标值将不再是文字中心,而是其上沿。另外,vjust为"inward"时文字趋近图表中心,为"outward"时文字远离中心。
●hjust:水平调整。其用法与vjust相仿,亦可用"left"、"middle"(相当于0.5)、"right"、"inward"、"outward"。
●nudge_y、nudge_x:以坐标系中的单位计算的水平和垂直偏移量。这两个参数代表的偏移量不随文字大小而变化。
●parse:是否将文字显示成数学表达式(相关内容见下文)。例如,当parse= TRUE时,"x^2"将被显示为"x"加上上标的形式。
■ 以下是仅geom_label拥有的参数:
●fill:背景色。注意:alpha参数会同时改变文字和背景色的透明度。
●label.size:框线粗细。默认值为0.25,单位为毫米,如需删除框线可将其设为0。
●label.padding:方框中的文字距框线的距离。默认值为0.25行,用unit函数设置,例如:unit(2, "mm")。
●label.r:方框四个角的圆滑程度,默认值为0.15行,用unit函数设定。
library(ggplot2)
## 修改颜色、大小等属性
ggplot()+
geom_label(aes(0, 0, label="ABC\n DEF"), size=8, color="purple", fill="red", alpha=0.3, label.size=2, label.padding=unit(3, "mm"), label. r=unit(0.4, "cm"), lineheight=0.8)
## 比较v/h_just与nudge_x/y的不同
ggplot()+
geom_text(aes(x=-4: -1, y=0, label=LETTERS[1: 4]), vjust=c(0.5, 1, 0, -1))+
geom_text(aes(x=1: 4, y=0, label=LETTERS[1: 4]), nudge_y=c(0.5, 1, 0, -1), color="red")
## 数学表达式
?gr Devices::plotmath # 查询数学表达式的写法
# 注意:如果文字将由geom_text或geom_label使用,就不要事先用parse函数
处理;但ggplot中其他涉及文字的函数则要求预先处理文字
mytext="italic(frac(-b%+-%sqrt(b^2-4*a*c), 2*a))"
mytitle="integral(f(x)*d*x, a, +infinity)"
mytitle=parse(text=mytitle) # 此处务必加上参数名"text"
ggplot()+geom_text(aes(x=0, y=0, label=mytext), parse=TRUE)+ # 未被预先处理的文字
labs(title=mytitle, x=mytitle) # 被预先处理过的文字
geom_text和geom_label可用来为图表添加附属元素。下边的例子使用了数据集art record.csv,它记录了若干创下拍卖价格纪录的当代艺术品。我们希望在绘图区添加图表标题,并且生成带有不同填充色的Y轴标签。(图5-1-1)
图5-1-1 生成带有填充色的标签
dat=read.csv("art record.csv", row.names=1) # 课件中的文件
options(scipen=10) # 调整小数显示位数
dat$Date=as.numeric(as.Date(gsub("//", "-", paste(dat$Date, "-01", sep="")))) # 将Date列转为日期对象
# 为方便后续作图,我们将日期对象转化成连续时值,方便后续作图
xlab=seq(1998, 2018, 2)
xpos=as.numeric(as.Date(paste(xlab, "-01-01", sep="")))
left_end=as.numeric(as.Date("1998-01-01")) # 面板左边界
# 先画出折线图和散点图图层
p=ggplot()+
geom_line(data=dat, aes(x=Date, y=Price), color="grey20", size=1.5)+
geom_point(data=dat, aes(x=Date, y=Price), color="#A9996A", size=5)+
geom_text(aes(x=left_end, y=Inf, label="Highest Prices of\ n Contemporary Artworks"), size=6, family="mono", fontface=4, vjust=1.5, hjust=0)
# 手动生成Y轴标签和填充色
ypos=pretty(dat$Price)
ylab=format(ypos, digits=0, big.mark=", ")
ylab=paste("$", ylab, sep="")
myfill=hsv(seq(0.7, 0, length.out=length(ylab)), s=0.3)
# 添加彩色标签并调整附属元素
p+geom_label(aes(x=left_end, y=ypos, label=ylab), hjust="right", fill=myfill, size=4, label.size=0)+(www.xing528.com)
scale_y_continuous(breaks=ypos)+ # 尽管不需要使用Y轴标签,但仍需调整加注标签的位置以便绘制网格线
scale_x_continuous(breaks=xpos, labels=xlab, limits=c(left_end, NA), expand=expansion(0.1))+
coord_cartesian(clip="off")+ # 仅当允许图形超出面板时才可成功添加彩色标签
theme_minimal(base_size=15)+
theme(
plot.margin=unit(c(2, 2, 2, 15), "mm"), # 扩展边缘以便容纳彩色标签
panel.grid.minor=element_blank(),
axis.title=element_blank(),
axis.text.y=element_blank(), # 删除真正的Y轴标签
axis.ticks.x=element_line()
)
我们接下来尝试把艺术家和作品等信息添加到图表中。这里的问题是,文字与点,以及文字与文字会重叠在一起,因此我们需要使用ggrepel包来调整文字的位置。(图5-1-2)
# install.packages("ggrepel")
library(ggrepel)
p=ggplot(data=dat, aes(x=Date, y=Price))+
geom_line(color="lightblue", size=1.5)+
geom_point(color="#A9996A", size=5)+
scale_x_continuous(breaks=xpos, labels=xlab, limits=c(left_end, NA), expand=expansion(0.08))+
geom_text(aes(x=left_end, y=Inf, label="Highest Prices of\n Contemporary Artworks"), size=6, family="mono", fontface=4, vjust=1.5, hjust=0)
# 生成标签内容
price_lab=round(dat$Price/1000000, 2)
artist_lab=toupper(dat$Artist)
name_lab=scales::wrap_format(15)(dat$Name)
info=paste(artist_lab, "\n", name_lab, "\n", "$", price_lab, " million", sep="")
# 使用geom_label,标签要么与点或其他标签重叠,要么超出显示范围
p+geom_label(aes(label=info), size=3, lineheight=0.8)
# 改用geom_label_repel
p+geom_label_repel(aes(label=info), label.size=NA, box.padding= unit(6, "mm"), seed=1, max.iter=1500, fill="white", color="grey20", size=4, family="serif", fontface=2, lineheight=0.8)+
theme(axis.text=element_text(size=12), panel.grid.minor= element_blank(), axis.title=element_blank())
图5-1-2 自动调整文字位置
geom_label/text_repel的参数与geom_label/text的参数相似,不过以下参数是前者独有的:
●max.iter:调整位置时的迭代次数。默认次数为2000,实际使用时可设置小一些的数值。
●seed:随机种子。
●box.padding:文字框周围的留白。默认值为unit(0.25, "lines"),用unit函数设置。
●direction:在哪个方向调整位置。默认值为"both",意味着新位置在水平方向和在垂直方向上都不同于原位置;当为"x"时,新位置仅在水平方向上不同;当为"y"时,仅在垂直方向上不同。
●min.segment.length:当新位置与原位置之间的距离小于该值时,连接线不显示。默认值为unit(0.5, "lines"),用unit函数设置。
●segment.color、segment.alpha、segment.size、arrow:连接线的颜色、透明度、粗细和箭头。
以上提到的这些函数,都只能把文字放在面板中,接下来我们再看看如何把文字放在画布(也就是作图窗口)的任意位置。在下边的例子中,我们将用grid包中的text Grob和lines Grob函数,在图表下方放置一些文字和一条线以代替图表注释,并且在图表中间添加一个水印。(图5-1-3)
# install.packages("cowplot")
library(grid) # 使用lines Grob和text Grob
library(cowplot) # 使用ggdraw和draw_grob
# 第一步,画出主要图形
dat=read.csv("happy small.csv", row.names=1)
p1=ggplot(dat)+geom_point(aes(GDP_percap, Satisfaction))+
theme(plot.margin=unit(c(0.3, 0.3, 1.5, 0.3), "cm")) # 在下方留出较大边缘以便容纳文字
# 第二步,制作要添加的图形的grob对象(但并不直接画出图形)
gr1=lines Grob(x=c(0, 1), y=c(0.12, 0.12), gp=gpar(col="darkblue", lwd=1, lty=3))
图5-1-3 使用grid包添加文字
gr2=text Grob(label="source: UNdata\n(http://data.un.org/)", x=0.98, y=0.02, just=c("right", "bottom"), gp=gpar(col="darkblue", fontsize=15, fontfamily="serif", fontface=3, lineheight=0.7))
gr3=text Grob(label="OPEN DATA", x=0.5, y=0.5, hjust=0.5, vjust=0.5, rot=45, gp=gpar(col="red", alpha=0.4, fontsize=60))
# 这个例子展示了text Grob和lines Grob的使用方法,需要注意的是:(1)参数名称与ggplot系统不同,例如,颜色参数不是color而是col。(2)有的参数必须放在gpar函数里设置。(3)text Grob的hjust和vjust参数只能使用数值,而just参数应当使用长度为2的向量,取值为0至1的数值或字符"left"、"center"(水平方向)、"right"、"top"、"center"(垂直方向)、"bottom"
# 第三步,用cowplot包中的ggdraw和draw_grob函数完成合并(第七章将对cowplot包进行详细介绍)
ggdraw(p1)+draw_grob(gr1)+draw_grob(gr2)+draw_grob(gr3)
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。