本节主要介绍,如何批量画出由少数参数确定的多边形的方法。例如,长方形就属于此类多边形,我们只要知道宽和高就可以确定这个长方形的形状了。
一、geom_tile/rect
我们用geom_tile或geom_rect来批量绘制矩形。
geom_tile使用中心点坐标来确定矩形的位置,用宽和高来确定矩形的形状。由于条形图本质上就是并列的多个矩形,所以接下来我们尝试用geom_tile代替geom_bar来绘制条形图。
# install.packages("ggforce")
library(ggfittext) # 用于添加文字
library(plothelper) # 使用spathxy等
library(ggforce) # 使用geom_regon
library(tibble) # 使用tibble
v=c(1, 2, 3, 5, 4)
# 首先,我们用geom_bar绘制条形图并观察
ggplot()+geom_bar(aes(x=1: 5, y=v, fill=v), stat="identity", width=0.8, color="orange")
# 观察可知,条形图中矩形的中心点X坐标就是底边中点X坐标,Y坐标就是高度的1/2
ggplot()+geom_tile(aes(x=1: 5, y=v/2, fill=v), width=0.8, height=v, color="orange") # 可见,用两种方法绘制的条形图几乎是一样的
# geom_tile用参数x和y来确定一个或多个矩形的中心点,用width和height来确定宽和高,用fill和color等参数来确定填充色和轮廓色等属性
geom_rect的功能与geom_tile相似,但前者使用矩形左边、右边、底边、顶边的位置来确定位置和形状。
# 仍以绘制条形图为例:观察可知,条形图中矩形的底边位置(ymin)都是0,顶边位置(ymax)等于用来作图的数值大小,左边位置(xmin)是底边中心点的位置减去宽度的1/2,右边位置(xmax)是底边中心点的位置加上宽度的1/2
ggplot()+geom_rect(aes(xmin=(1: 5)-0.8/2, xmax=(1: 5)+0.8/2, ymin=0, ymax=v, fill=v), color="orange")
啤酒颜色标准参考方法(Standard Reference Method)常用于评估啤酒颜色的视觉属性。下面我们尝试把这一评估方法涉及的颜色绘制到图上(图6-2-1)。
图6-2-1 使用geom_tile绘制多个矩形
mycolor=read.csv("beer.csv", row.names=1) # 课件中的文件
mycolor=mycolor[, 1]
# 先生成矩形位置。为确保从浅色到深色的矩形按照从左到右、从上到下的位置排列,我们使用spathxy函数生成坐标
dat=spathxy(1: 8, 1: 5, first="right", second="bottom", change_
line=TRUE) # 总共需要40个点位
# 绘制矩形
p=ggplot()+coord_fixed()+theme_void()+
geom_tile(data=dat, aes(x, y), fill=mycolor, width=0.9, height= 0.9)+
labs(title="Beer Color SRM")+
theme(plot.title=element_text(size=25, hjust=0.5, family="Hershey Gothic English"))
# 用geom_fit_text添加文字
lab=paste(1: 40, "\n", mycolor, sep="")
text_color=rep(c("black", "white"), times=c(16, 24))
q=geom_fit_text(data=dat, aes(x, y, label=lab), family="serif", fontface=2, width=0.9, height=0.6, grow=TRUE, color=text_color)
p+q
#==========
# 练习:绘制矩阵条形图
#==========
# 本例使用的数据是若干国家在世界银行营商便利程度评估的各具体维度的得分(分值在1至100之间,较高的分值代表一个国家或地区能够以较好的措施支持或监管商业行为)。在表格中,每行存放一个国家的分数,每列存放一个维度的分数,而在我们将要绘制的矩阵条形图中,条形也是按此方式排列的(图6-2-2)
dat=read.csv("db 5dim.csv", row.names=1) # 课件中的文件
maxlen=0.9 # 当分数为满分时,条形的长度
width=0.3 # 宽度
nd=ncol(dat) # 维度数
n=nrow(dat) # 国家数
nation=rownames(dat) # 国家名
lab=colnames(dat) # 维度名
lab=gsub("\\.", " ", lab) # 将句点变成空格
lab=scales::wrap_format(9)(lab) # 设置每行宽度为9
score=as.numeric(as.matrix(dat))
bar_pos=spathxy(1: nd, 1: n, first="bottom", second="right", change_line=TRUE) # 生成条形的起始点
bar_len=scales::rescale(c(0, 100, score), to=c(0, maxlen))[-c(1, 2)] # 根据条形的最大长度调整单个条形的长度
bar_pos=cbind(bar_pos, bar_len, score)
p=ggplot(bar_pos)+
geom_rect(show.legend=FALSE, aes(xmin=x, xmax=x+maxlen, ymin=ywidth/2, ymax=y+width/2, color=factor(x)), fill=NA)+
geom_rect(show.legend=FALSE, aes(xmin=x, xmax=x+bar_len, ymin=ywidth/2, ymax=y+width/2, fill=factor(x)))+
geom_text(aes(x=x, y=y, label=round_text(score, 2)), nudge_y=0.15+width/2, size=4.5, hjust="left", family="Hershey Sans", fontface=2, color="white")+
scale_color_manual(values=c("#CE5B78", "#577284", "#E08119","#797B3A", "#9B1B30"))+
scale_fill_manual(values=c("#CE5B78", "#577284", "#E08119","#797B3A", "#9B1B30"))
p+scale_x_continuous(breaks=(1: nd), labels=lab, position="top")+
scale_y_continuous(breaks=n: 1, labels=nation, expand= expansion(0.05))+
geom_hline(aes(yintercept=n+0.5), color="white")+
labs(title="Business Environment Evaluation\n")+(www.xing528.com)
theme_void()+
theme(
axis.text.x=element_text(hjust=0, face=3, family="serif", size=15, color="white"),
axis.text.y=element_text(face=3, family="serif", size=15, color="white"),
plot.title=element_text(face=2, family="serif", size=20, hjust=0.8, color="white"),
aspect.ratio=0.6,
plot.margin=unit(rep(3, 4), "mm"),
plot.background=element_rect(fill="deepskyblue1", color="deepskyblue1")
)
图6-2-2 矩阵条形图
二、geom_regon
ggforce包中的geom_regon函数可用来绘制正多边形。
ggplot()+coord_fixed()+
geom_regon(aes(x0=c(-4, 0, 4), y0=0, angle=c(0, pi/4, 0), r=c(1, 1, 2), sides=c(4, 4, 50)), radius=unit(2, "mm"))
# geom_regon函数必需的参数有:x0和y0用于指定中心点坐标;angle用于指定旋转角度(以弧度计算),即使不作旋转,也要将值设定为0;r用于正多边形的大小,其实际意义为中心点到顶点的长度;sides为边数(如需绘制圆形,设置足够多的边即可)。函数的fill、color等参数与geom_bar的同名参数相仿。此外,geom_regon还可用unit设置radius参数来让顶点部位变得平滑
我们还可用geom_regon绘制形状不随坐标系变化的图形——当我们在不添加coord_fixed()的情况下随意拉伸坐标系时,或改用极坐标系时,这些图形都不会发生变化。注意:绘制此类图形时,我们需手动设置坐标轴值域,因为此类图形无法自动对值域进行调整。
# 参数设置方法为:将r设为一个足够小的值(不能是0),然后用unit设置expand参数使得图形向外扩展
ggplot()+xlim(-3, 3)+ylim(-3, 3)+
geom_regon(aes(x0=0, y0=0, angle=0, sides=4, r=0.001), expand= unit(2, "cm"))
三、geom_circle/ellipse/circle_cm
plothelper包里的函数,可用来绘制尺寸以厘米为单位且不随坐标系变化的图形。
p=ggplot()+xlim(-3, 3)+ylim(-2, 2)
## geom_circle_cm用rcm来指定以厘米为单位的半径。注意:该函数不包含linetype参数
p+geom_circle_cm(aes(x=0, y=0), rcm=2, color="red", fill="blue")
## geom_ellipse_cm使用rcm和ab两个参数来控制椭圆的形状,但不能直接控制长半径和短半径的长度,只能用ab来设定图形被"压扁"的程度(当ab=1时图形为圆形)。angle用来控制旋转角度,n用于设定点数
p+geom_ellipse_cm(aes(x=c(-1, 0, 1, 2), y=0, n=50), rcm=1, ab=c(2, 2, 1, 0.5), angle=c(0, pi/6, 0, 0), linetype=2)
## geom_rect_cm用width和height控制矩形的宽和高,用vjust和hjust调整位置(0.5代表不调整)
p+geom_rect_cm(aes(x=c(-2, 0, 2), y=0), width=1, height=1, vjust= c(0.5, 1, 0), linetype=2)
在以下例子中,一方面,我们为了让图表自行调整尺寸,没有使用coord_fixed;另一方面,我们希望用一个圆形来强调汇率开始大幅变化的时间点,如果不使用coord_fixed,就无法保证圆形在绘图,设备中显示为圆形。此时,我们就应使用不随坐标系变化的图形。
dat=read.csv("usdcny2019.csv", row.names=1) # 课件中的文件
dat=dat[122: 165, ]
D=as.Date(dat$date)
ggplot()+geom_line(na.rm=TRUE, aes(D, dat$close), color="blue")+
geom_circle_cm(aes(x=as.Date("2019-08-01"), y=6.8834), rcm= 1.5, color=NA, fill="red", alpha=0.2)+
geom_point(aes(x=as.Date("2019-08-01"), y=6.8834), color="red", size=2)
四、渐变条形图
在使用geom_bar绘制的条形图中,每个条形只能有一种颜色,而plothelper包中的geom_shading_bar绘制的条形图,可以让单个条形拥有渐变色,甚至让不同条形带有不同的渐变色。
geom_shading_bar的参数有:
●x、y:条形的位置和高度。
●raster:渐变色。当有n个条形时,raster必须是一个包含n个颜色向量的列表,以便函数为每个条形分配一套渐变色。若所有条形使用同样的渐变色,则raster应是包含一个向量的列表。
●width:条形宽度。
●flip:当使用coord_flip函数时,务必设置flip=TRUE(默认为FALSE)。
●modify_raster、smooth、space:当modify_raster取值为TRUE(默认)时,函数将自动增加颜色的数量,以便使渐变更加平滑。此时,smooth用于设定每个条形使用的颜色数量(默认值为15),space用于设定颜色空间,选项为"rgb"(默认)或"Lab"。如果你认为传递给raster的渐变色已经被调整好了,可将modify_raster设为FALSE。
●equal_scale:当其为FALSE(默认)时,每个条形将使用分配给它们的所有渐变色。若将其改为TRUE,则每个条形只会根据自身长度使用部分渐变色。见以下示例。
●orientation:见第三章第一节关于coord_flip的内容。
接下来,我们以2016年森林覆盖率数据为例,绘制渐变条形图(图6-2-3)。
dat=read.csv("forest area.csv", row.names=1) # 课件中的文件
dat$Country=scales::wrap_format(9)(dat$Country) # 让长国名自动换行
dat$Country=reorder(dat$Country, dat$Percent)
# 我们既可把x、y和raster所需的数值分开放置,也可把它们放在tibble对象里,本例将示范后一种方式。为简便起见,我们让所有条形都使用一套渐变色
mycolor=hcl.colors(n=15, palette="viridis") # 选择颜色
mycolor=rev(mycolor)
mycolor=list(mycolor)
tib=tibble(x=dat[, 1], y=dat[, 2], mycolor=mycolor)
ggplot(tib)+coord_flip()+
geom_shading_bar(aes(x, y, raster=mycolor), smooth=40, flip=TRUE)+ # 请尝试添加equal_scale=TRUE并观察效果
geom_text(aes(x, y, label=round(y, 1)), family="mono",fontface=3, size=5, hjust=-0.1)+
scale_y_continuous(limits=c(0, 80), breaks=seq(0, 80, 20))+
labs(x=NULL, y=NULL, title="Forest/Land Ratio (%)")+
theme_minimal(base_size=16)+theme(text=element_text(family="mono"))
图6-2-3 渐变条形图
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。