首页 理论教育 ggplot可视化:scale_*_*函数

ggplot可视化:scale_*_*函数

时间:2023-11-19 理论教育 版权反馈
【摘要】:在这种情况下,我们可以使用scale_*_*系列的函数为图形自动分配属性。但是,也许我们需要的是其他颜色,因此我们需要对scale_color_continuous进行修改。

ggplot可视化:scale_*_*函数

一、散点图使用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"))

## 对于alphasize也必须先把用于分配属性的连续变量转为离散变量故以下例子中亦使用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

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

我要反馈