一、散点图使用scale_*_*函数
设想,我们需要为1000个点分配颜色,用偏蓝色的点代表较小值,用偏红色的点代表较大值。此时,我们固然可以使用包含1000个颜色值的向量,但有时,此类操作过于烦琐。在这种情况下,我们可以使用scale_*_*系列的函数为图形自动分配属性。
library(ggplot2)
dat=read.csv("happy small.csv", row.names=1) # 第一节使用过的满意度数据
p=ggplot(dat)+labs(title="Life Satisfaction VS. GDP per capita")
## 我们现在希望根据Y值(也就是变量Satisfaction)分配颜色,因此将color作为aes参数使用
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction), size=5)
# 此时,各点根据数据的大小获取颜色,这等同于不加任何修改地使用了scale_color_continuous(亦可写为scale_color_gradient)函数
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction), size=5)+
scale_color_continuous()
## 在上例中,被分配到各点的默认颜色为不同的蓝色。但是,也许我们需要的是其他颜色,因此我们需要对scale_color_continuous进行修改。我们用low和high参数设定较小值接近绿色,较大值接近红色(图2-3-1a)
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction), size=5)+
scale_color_continuous(low="green", high="red")
图2-3-1 左上=图a使用绿-红渐变色,右上=图b使用红-绿渐变色,左下=图c修改填充色,右下=图d指定两个以上颜色
# 当然,也可以反过来,设定较小值接近红色,较大值接近绿色;还可以用name参数指定图例的标题(图2-3-1b)
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction), size=5)+
scale_color_continuous(name="Life\n Satisfaction", low="red", high="green")
# 实际上,我们可以根据任何变量来自动分配颜色。例如,我们可以根据X值分配颜色,虽然这样做没什么实际意义
p+geom_point(aes(GDP_percap, Satisfaction, color=GDP_percap), size=5)+
scale_color_continuous(low="green", high="red")
## 如果要修改填充色,也就是点的核心的颜色,则使用scale_fill_continuous,并将fill作为aes参数使用(图2-3-1c)
p+geom_point(aes(GDP_percap, Satisfaction, fill=Satisfaction), shape=21, size=5, stroke=2)+
scale_fill_continuous(low="green", high="red")
## 当用于生成渐变效果的颜色多于两个时,需使用scale_color/fill_gradientn函数,其colors参数指向颜色向量(最小值对应的颜色在左边,最大值对应的颜色在右边)(图2-3-1d)
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction), size=5)+
scale_color_gradientn(colors=c("cyan", "blue", "green","orange", "red"))
我们来总结一下scale_color/fill_continuous/gradientn的参数:
●name:图例的标题。
●low、high、colors:颜色。
●na.value:当用于分配颜色的变量为缺失值时使用的颜色,默认为"grey50"。
●breaks:图例中标签所在的位置。在默认状态下,函数会自动计算。见以下示例。
●labels:图例中标签的内容。这个参数的长度必须与breaks的长度相等。见以下示例。
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction))+
scale_color_continuous(low="red", high="green", breaks=c(3, 6)) # 改变标签位置
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction))+
scale_color_continuous(low="red", high="green", breaks=c(3, 6),labels=c("标签1", "标签2")) # 改变标签位置和内容
要强调的是,当我们用scale_color/fill_continuous/gradientn分配颜色时,用来分配颜色的变量必须是连续变量(正如函数名中的"continuous"所示),而不应是离散变量。在本例中,我们可以用Satisfaction、GDP_percap这两个连续变量;而使用Level这个离散变量分配颜色的方法,我们会在后边讲到。
接下来,我们再尝试自动分配透明度值和点的大小。此时,只要把scale_color_continuous改为scale_alpha_continuous和scale_size_continuous,并改用相应的aes参数即可。另外,我们不再使用low和high参数,而是使用range参数确定最小和最大值。
## 用scale_alpha_continuous更改透明度
# alpha的默认范围是0.1至1
p+geom_point(aes(GDP_percap, Satisfaction, alpha=Satisfaction), size=5, color="red")
# 改变alpha的范围
p+geom_point(aes(GDP_percap, Satisfaction, alpha=Satisfaction), size=5, color="red")+
scale_alpha_continuous(range=c(0.3, 0.8))
## 用scale_size_continuous改变点的大小
p+geom_point(aes(GDP_percap, Satisfaction, size=Satisfaction))+
scale_size_continuous(range=c(1, 5))
## 还可同时修改多种图形属性(尽管多数情况下这样做并无必要)
p+geom_point(aes(GDP_percap, Satisfaction, color=Satisfaction, fill=Satisfaction), shape=21, size=3, stroke=2)+
scale_color_continuous(low="purple", high="yellow")+
scale_fill_continuous(low="green", high="red")
接下来,我们再来看如何用scale_color/fill/alpha/size_manual函数以半手动的方式分配属性。
## 数据中的Level变量标出了各国的满意度分数水平,我们现在依此分类手动分配颜色
p+geom_point(aes(GDP_percap, Satisfaction, color=Level), size=5)+scale_color_manual(values=c("red", "blue", "orange"))
这个函数分配颜色的方法是这样的:Level变量的取值,按字母顺序排列,是"high"、"low"、"medium",因此按字母顺序排在第一位的"high"得到的颜色是排在第一位的颜色"red",按字母顺序排在第二位的"low"得到的颜色是排在第二位的颜色"orange"。不过接下来,我们要以更为直接的方式确定每个类别所得到的颜色。
p+geom_point(aes(GDP_percap, Satisfaction, color=Level), size=5)
+scale_color_manual(values=c("Low"="blue", "Medium"="orange","High"="red")) # 此时在values参数中,我们不但要写颜色值,而且要在等号前边标明类别名称
## 下面尝试用scale_shape_manual修改点的形状
p+geom_point(aes(GDP_percap, Satisfaction, shape=Level), size=5)+
scale_shape_manual(values=c("Low"=15, "Medium"=16, "High"= 17))
当用于分配属性的变量是连续变量时,我们也可以用这种名称加引号的方式直接为每一个取值确定属性——不过,考虑到连续变量会有很多取值,我们通常并不会这样做。要强调的是,scale_*_manual仅用于离散变量,所以即使它所对应的变量原本是连续变量,我们也必须先把它转为因子变量再使用。下例数据包含了并无实际意义的一列数值,我们以此进行简单示范。
s=rep(1: 3, length.out=10)
dat_extra=cbind(dat, s)
ggplot(dat_extra)+
geom_point(aes(GDP_percap, Satisfaction, color=factor(s)), size=5)+ # 务必将连续变量s转为离散变量
scale_color_manual(values=c("1"="purple", "2"="orangered","3"="green"))
## 对于alpha、size,也必须先把用于分配属性的连续变量转为离散变量,故以下例子中亦使用factor(s),而不能直接使用s
ggplot(dat_extra)+
geom_point(aes(GDP_percap, Satisfaction, alpha=factor(s)), color="red", size=5)+
scale_alpha_manual(values=c("1"=0.3, "2"=0.6, "3"=1))
## ggplot自带为离散变量分配间隔均等颜色的scale_color/fill_hue函数,这个函数使用的是HCL颜色系统
ggplot(dat_extra)+
geom_point(aes(GDP_percap, Satisfaction, color=factor(s)), size=5)+
scale_color_hue()
这里要回答一个问题,是否能够不使用scale_*_*函数?答案:可以不使用,只是还需要单独设定属性。
以下两种写法的效果是完全相同的:
# 写法1,使用scale_*_*
ggplot(dat_extra)+(www.xing528.com)
geom_point(show.legend=FALSE, aes(GDP_percap, Satisfaction, color=factor(s), fill=Satisfaction, alpha=Satisfaction, size= Satisfaction), shape=21)+
scale_color_manual(values=c("1"="red", "2"="green", "3"="purple"))+
scale_fill_continuous(low="blue", high="yellow")+
scale_alpha_continuous(range=c(0.5, 0.9))+
scale_size_continuous(range=c(2, 5))
# 写法2,不使用scale_*_*,而是预先生成属性
library(scales)
mycolor=ifelse(s==1, "red", ifelse(s==2, "green", "purple"))
myfill=col_numeric(c("blue", "yellow"), domain=range(dat_extra$Satisfaction))(dat_extra$Satisfaction) # col_numeric的用法请参考第一章讲解颜色的部分
myalpha=rescale(dat_extra$Satisfaction, to=c(0.5, 0.9))
mysize=rescale(sqrt(rescale(dat$Satisfaction)), to=c(2, 5)) # 开方。相当于scales::area_pal(range=c(2, 5))(rescale(dat$Satisfaction)) #注意:手动设置size的方法不同于手动设置alpha的方法。设置size的过程多了一个开方的步骤
ggplot(dat_extra)+
geom_point(aes(GDP_percap, Satisfaction), shape=21, color=mycolor, fill=myfill, alpha=myalpha, size=mysize)
# 写法3,使用scale_*_identity将数据框中的值直接设为属性值
dat_extra=data.frame(dat_extra, mycolor, myfill, myalpha, size=mysize)
ggplot(dat_extra)+
geom_point(show.legend=FALSE, aes(GDP_percap, Satisfaction, color= mycolor, fill=myfill, alpha=myalpha, size=mysize), shape=21)+
scale_color_identity()+scale_fill_identity()+scale_alpha_identity ()+scale_size_identity()
另一个问题是,分配属性时使用连续变量与使用离散变量有何不同?请看以下例子:
# 写法1
ggplot(dat_extra)+geom_point(aes(GDP_percap, Satisfaction, color=s), size=5)
# 写法2
ggplot(dat_extra)+geom_point(aes(GDP_percap, Satisfaction, color=factor(s)), size=5)
# 在写法1中,color指向连续变量的s,因此程序会自动使用根据连续变量来分配颜色的scale_color_continuous,因此点的颜色是渐变的多个颜色;而在写法2中,color指向离散变量factor(s),因此程序会自动使用根据离散变量分配颜色的scale_color_hue
# 要强调的是,对scale_*_continuous和scale_*_discrete的使用取决于图形属性。请看以下例子:
# ggplot(dat_extra)+geom_point(aes(GDP_percap, Satisfaction, shape=s))+scale_shape_continuous()
# Error: A continuous variable can not be mapped to shape. # 点的形状等属性只能由离散变量决定,若使用scale_*_continuous则会报错
ggplot(dat_extra)+geom_point(aes(GDP_percap, Satisfaction, alpha=s))+scale_alpha_continuous()
ggplot(dat_extra)+geom_point(aes(GDP_percap, Satisfaction, alpha=factor(s)))+scale_alpha_discrete()
# Warning message: Using alpha for a discrete variable is not advised. # 透明度本身是连续值,因此用于分配属性的变量也应该是连续变量;但事实上,我们有时也确实会用离散变量进行分配,只是这样做会使警告弹出
由以上例子可知,scale_*_*系列的函数可以修改的图形属性有color/fill、alpha、size、shape、linetype等。具体来看,scale_*_manual可用于分配所有属性;size、alpha则可以用scale_*_continuous和scale_*_discrete来分配,只不过使用后者时会有警告弹出;shape和linetype则不能用scale_*_continuous分配;color/fill既可以用连续变量来分配,也可以用离散变量来分配。
#==========
# 练习:存在一个以上scale_fill/color_*的情况
#==========
# 代码中的scale_color_*会对所有包含aes(color=...)的图层的颜色进行分配。但是,如果我们要求不同图层有不同分配方式的话,就要用到ggnewscale包中的new_scale函数
# install.packages("ggnewscale")
library(ggnewscale)
ggplot()+
geom_point(aes(1: 10, 1: 10, color=1: 10))+
scale_color_continuous(low="red", high="blue")+
new_scale(new_aes="color")+
geom_point(aes(1: 10, 0, color=1: 10))+
scale_color_continuous(low="green", high="purple")
# 我们在两个图层之间加了new_scale函数。这样一来,在它之上和在它之下的两个图层,就可以拥有不同的渐变方式了。不过,目前new_scale函数只支持对scale_color_*和scale_fill_*的作用范围进行划分,因此,参数new_aes的值只能是"color"或"fill"
二、折线图使用scale_*_*函数
将scale_*_*函数用于折线图与用于散点图相仿,在此我们仅举若干例子。我们以ip_big.csv文件中五个工业领域的工业生产指数为例。
dat=read.csv("ip big.csv", row.names=1) # 课件中的文件
p=ggplot(dat)
p+geom_line(aes(ID, Value, color=Area), size=1)+
scale_color_manual(values=rainbow(5)) # 线条颜色
p+geom_line(aes(ID, Value, color=Area), size=1)+
scale_color_manual(values=c("Machinery"="red", "Computer"="yellow", "Furniture"="green", "Motor"="blue", "Metal"="purple")) #明确指定颜色
p+geom_line(aes(ID, Value, linetype=Area), size=1)+
scale_linetype_manual(values=c("Machinery"=1, "Computer"=2,"Furniture"=3, "Motor"=4, "Metal"=5)) # 指定线形。注意:可用的线形只有六种
p+geom_line(aes(ID, Value, size=Area))+
scale_size_manual(values=seq(0.5, 2, length.out=5)) # 线条粗细
p+geom_line(aes(ID, Value, color=Area, linetype=Area), size=1)+
scale_color_manual(values=rainbow(5))+
scale_linetype_manual(values=c("Machinery"=1, "Computer"=2,"Furniture"=3, "Motor"=4, "Metal"=5)) # 颜色+线形
#==========
# 练习:使用HCL配色方案
#==========
# 第一章曾提到,R包含多个HCL配色方案,那么怎样才能使用这些配色方案呢?虽然colorspace包提供了形如scale_color_continuous_diverging的若干函数,但这些函数的参数设置比较复杂,所以我们下面来看看如何手动使用配色方案
dat=read.csv("happy small.csv", row.names=1) # 课件中的文件
vi=hcl.colors(n=10, palette="Viridis") # 从名为"Viridis"的配色方案中提取颜色。如有需要,可用rev函数颠倒颜色的顺序
# 接下来,可使用两种方法分配颜色
# 方法1:用scale_color_gradientn自动分配颜色
ggplot(dat)+geom_point(aes(GDP_percap, Satisfaction, color= Satisfaction), size=5)+scale_color_gradientn(colors=vi)
# 方法2:先用gradient_n_pal分配颜色,再传给color参数
f=scales::gradient_n_pal(vi)
mycolor=f(scales::rescale(dat$Satisfaction))
ggplot(dat)+geom_point(aes(GDP_percap, Satisfaction), size=5, color=mycolor)
让我们来汇总一下scale_*_*函数,方便以后查询:
●调整颜色(常用):scale_colo(u)r/fill_continuous/gradient/gradientn/manual
●调整颜色(不常用):scale_colo(u)r/fill_hue/discrete/brewer/grey/gradient2
●调整大小或透明度:scale_size/alpha_continuous/discrete/manual
●调整点的形状或线形:scale_shape/linetype_discrete/manual
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。