# 11.分面
 # 11.1 使用分面将数据分割绘制到子图中
 # 使用facet_grid()或facet_wrap()函数,并指定根据哪个变量来分割数据。
 # 使用facet_grid()函数时,可以指定一个变量作为纵向子面板分割的依据,并指定另外一个变量作为横向子面板分割的依据
 library(ggplot2)
 # 基本图形
 p <- ggplot(mpg,aes(x=displ,y=hwy))+geom_point()
 p
 # 纵向排列的子面板根据drv分面
 p+facet_grid(drv~.)
 # 横向排列的子面板根据cyl分面
 p+facet_grid(.~cyl)
 # 同时根据drv(纵向)和cyl(横向)分割
 p+facet_grid(drv~cyl)


 # 使用facet_wrap()是,各子图将像纸上的文字一样被一次横向排布并换行
 # 依class分面
 # 注意波浪线前没有任何字符
 p+facet_wrap(~class)
 # 使用facet_wrap()时,默认使用相等数量的行和列,要对方阵进行修改,可以通过向nrow或ncol赋值实现
 # 两种方式的结果是相同的:2行4列的分面
 p+facet_wrap(~class,nrow = 2)
 p+facet_wrap(~class,ncol = 4)


 # 11.2在不同坐标轴下使用分面
 # 将标度设置为“free_x"、"free_y"或"free"
 # 基本图形
 p <- ggplot(mpg,aes(x=displ,y=hwy))+geom_point()
 # 使用自由的y标度
 p+facet_grid(drv~cyl,scales = "free_y")
 # 使用自由的x标度和y标度
 p+facet_grid(drv~cyl,scales = "free")
 # 当使用自由的y标度时,各行子图都将拥有自己的y值域;当使用自由的x标度时,相同的原理也适用于各列子图
 # 无法直接设置各行或各列的值域,但是可以通过丢弃不想要的数据(以缩减值域)或通过添加几何对象geom_blank()(以扩展值域)的方式控制值域的大小。


 # 11.3 修改分面的文本标签
 # 修改因子各水平的名称即可
 mpg2 <- mpg
 # 重命名4为4wd,f为Front,r为Rear
 levels(mpg2$drv)[levels(mpg2$drv)=="4"] <- "4wd"
 levels(mpg2$drv)[levels(mpg2$drv)=="f"] <- "Front"
 levels(mpg2$drv)[levels(mpg2$drv)=="r"] <- "Rear"
 # 绘制新数据
 ggplot(mpg2,aes(x=displ,y=hwy))+geom_point()+facet_grid(drv~.)
 # 要设置分面标签,必须修改数据本身的值,这在用法上与能够设置标签的标度有所不同
 # 使用facet_grid()时,可以使用一个贴标函数(labeller function)来设置标签。
 # 贴标函数label_both()将在每个分面上同时打印出变量的名称和变量的值
 ggplot(mpg2,aes(x=displ,y=hwy))+geom_point()+facet_grid(drv~.,labeller = label_both)
 # 另一个使用贴标函数label_parsed(),它可以读入字符串,并将其作为R数学表达式来解析
 mpg3 <- mpg
 levels(mpg3$drv)[levels(mpg3$drv)=="4"] <- "4^{wd}"
 levels(mpg3$drv)[levels(mpg3$drv)=="f"] <- "-Front%.%e^{pi*i}"
 levels(mpg3$drv)[levels(mpg3$drv)=="r"] <- "4^{wd}-Front"
 ggplot(mpg3,aes(x=displ,y=hwy))+geom_point()+facet_grid(drv~.,labeller = label_parsed)


 # 11.4 修改分面标签和标签的外观
 # 使用主题系统,通过设置strip.text来控制文本的外观,设置strip.background以控制背景的外观
 library(gcookbook)
 ggplot(cabbage_exp,aes(x=Cultivar,y=Weight))+geom_bar(stat = "identity")+facet_grid(.~Date)+theme(strip.text = element_text(face = "bold",size = rel(1.5)),strip.background = element_rect(fill = "lightblue",colour = "black",size = 1))
 # rel(1.5)使得标签文本的大小为此主题下基准文本大小的1.5倍。# 在背景设置中使用size=1使得分面标题背景轮廓线的粗细为1毫米.
# 12.配色
 # 在ggplot2的图形语法中,颜色是一个图形属性(aesthetic)
 # 12.1设置对象的颜色
 # 对于几何对象(geom),设置colour或者fill参数的值
 ggplot(mtcars,aes(x=wt,y=mpg))+geom_point(colour="red")
 library(MASS)
 ggplot(birthwt,aes(x=bwt))+geom_histogram(fill="red",colour="black")


 # 在ggplot2中,设置和映射图形属性有非常重大的区别。
 # 一般而言,colour参数控制的是线条、多边形轮廓的颜色,而fill参数控制的是多边形的填充色。
 # 对于点形来说,情况略微不同,大多数的点形,整个点的颜色是由color控制的,而不是fill。


 # 12.2将变量映射到颜色上
 # 对于几何对象,将colour或fill参数的值设置为数据中某一列的列名即可
 library(gcookbook)
 # 这两种方法效果相同
 ggplot(cabbage_exp,aes(x=Date,y=Weight,fill=Cultivar))+geom_bar(colour="black",position = "dodge",stat = "identity")
 ggplot(cabbage_exp,aes(x=Date,y=Weight))+geom_bar(aes(fill=Cultivar),colour="black",position = "dodge",stat = "identity")


 # 这两种方法效果相同
 ggplot(mtcars,aes(x=wt,y=mpg,colour=cyl))+geom_point()
 ggplot(mtcars,aes(x=wt,y=mpg))+geom_point(aes(colour=cyl))


 # ggplot()函数中的映射使用的是默认映射(所有几何对象都由此继承).
 # 通过在geom系列函数中的具体设置,可以覆盖默认映射。
 str(cabbage_exp)
 # 在ggplot()中因子化
 ggplot(mtcars,aes(x=wt,y=mpg,colour=factor(cyl)))+geom_point()
 # 另一个方法:在原数据中因子化
 m <- mtcars
 m$cyl <- factor(m$cyl)
 ggplot(m,aes(x=wt,y=mpg,colour=cyl))+geom_point()


 # 12.3 对离散型变量使用不同的调色板
 # 使用默认调色板和ColorBrewer调色板
 library(gcookbook)
 # 基础图形
 p <- ggplot(uspopage,aes(x=Year,y=Thousands,fill=AgeGroup))+geom_area()
 # 这三种方法效果相同
 p
 p+scale_fill_discrete()
 p+scale_fill_hue()
 # ColorBrewer调色板
 p+scale_fill_brewer()
 # 修改调色板就是修改填充色标度(fill)或轮廓色标度(colour):它会设计从连续型或离散型变量到图形属性上映射的改变。在颜色上有两个类型的标度,填充色标度和轮廓色标度。
 # 函数scale_fill_hue()中颜色来自HCL色系(hue-chroma-lightness:色相-色度-亮度)的色轮,默认的亮度是65(取值为0~100)。
 # 调整参数l(luminance/lightness)的值设置亮度
 # 基本的散点图
 h <- ggplot(heightweight,aes(x=ageYear,y=heightIn,colour=sex))+geom_point()
 # 默认亮度lightness=65
 h
 # 略微加深
 h+scale_color_hue(l=45)


 # ColorBrewer包提供了很多调色板
 library(RColorBrewer)
 display.brewer.all()
 # ColorBrewer调色板可以通过名称来选择
 p+scale_fill_brewer(palette = "Oranges")
 # 使用灰度调色板,适合黑白打印。标度范围是0~1(其中0对应黑色,1对应白色),灰度调色板的默认范围是0.2~0.8,但可以修改
 p+scale_fill_grey()
 # 倒转方向并且更改灰度范围
 p+scale_fill_grey(start = 0.7,end = 0)


 # 12.4 对离散型变量使用自定义调色板
 # 使用scale_colour_manual()函数来自定义颜色。其中的颜色可以使已命名的,也可以是RGB形式的
 library(gcookbook)
 # 基础图形
 h <- ggplot(heightweight,aes(x=ageYear,y=heightIn,colour=sex))+geom_point()
 # 使用颜色名
 h+scale_color_manual(values = c("red","blue"))
 # 使用RGB值
 h+scale_colour_manual(values = c("#CC6666","#7777DD"))
 # 对于填充色标度,使用scale_fill_manual()代替即可
 # 参数values向量中的元素顺序自动匹配离散标度对应因子水平的顺序。
 levels(heightweight$sex)
 # 如果变量是字符型向量而非因子形式,那么它会被自动转换为因子;顺序也默认地按照字母表排序。
 # 如果想自定义颜色分配的顺序,可以使用带有名称的向量参数
 h+scale_colour_manual(values = c(m="blue",f="red"))
 # R中有很多已经命名的颜色
 colors()
 # RGB颜色:由6个数字构成(十六进制),每个颜色都由两个数字表示,范围从00到FF
 # 调整RGB颜色的经验法则:
 # 1.在一般情况下,较大的数字更明亮,较小的数字更暗淡。
 # 2.如果要得到灰色,将三个颜色通道设置为相同的值。
 # 3.和RGB对立的是CMY(印刷三原色):青(cyan)、品红(magenta)、黄(yellow)。红色通道值越高,颜色越红,越低则越青。
 # 同样的法则适用于另外两组颜色对:绿色-品红、蓝色-黄色。


 # 12.5使用色盲友好式的调色板
 # 使用函数scale_fill_manual(),调色板(cb_palette)用自定义的
 library(gcookbook)
 # 基础图形
 p <- ggplot(uspopage,aes(x=Year,y=Thousands,fill=AgeGroup))+geom_area()
 # 加入灰色到调色板
 cb_palette <- c("#999999","#E69F00","#56B4E9","#009E73","#F0E442","#0072B2","#D55E00","#CC79A7")
 # 将其使用到图形中
 p+scale_fill_manual(values = cb_palette)


 # 12.6对连续型变量使用自定义调色板
 library(gcookbook)
 # 基础图形
 p <- ggplot(heightweight,aes(x=ageYear,y=heightIn,colour=weightLb))+geom_point(size=3)
 p
 # 使用两种颜色的渐变色
 p+scale_color_gradient(low = "black",high = "white")
 # 渐变色中间用白色划分
 library(scales)
 p+scale_colour_gradient2(low = muted("red"),mid = "white",high = muted("blue"),midpoint = 110)
 # n个颜色的渐变色
 p+scale_color_gradientn(colours = c("darkred","orange","yellow","white"))
 # 对于填充色标度,使用scale_fill_xxx()替换即可,这里xxx是gradient、gradient2或gradientn中的一个
 # 将连续型变量映射到颜色标度上需要一组连续变化的颜色。
 # muted()函数来自scales包,它会针对输入的颜色输出一个饱和度较低的颜色(RGB格式)
 # 如果不想用连续标度,要使用离散(分类)标度,可以将数据重新编码呈分类值


 # 12.7根据数值设定阴影颜色
 # 增加一列来对y进行划分,然后将该列映射到填充色标度上。
 library(gcookbook)
 cb <- subset(climate,Source=="Berkeley")
 cb$valence[cb$Anomaly10y>=0] <- "pos"
 cb$valence[cb$Anomaly10y<0] <- "neg"
 cb
 ggplot(cb,aes(x=Year,y=Anomaly10y))+geom_area(aes(fill=valence))+geom_line()+geom_hline(yintercept = 0)
 # approx()返回一个列表,包含x和y向量
 interp <- approx(cb$Year,cb$Anomaly10y,n=1000)
 # 放在一个数据框中并重新计算valence
 cbi <- data.frame(Year=interp$x,Anomaly10y=interp$y)
 cbi$valence[cbi$Anomaly10y>=0] <- "pos"
 cbi$valence[cbi$Anomaly10y<0] <- "neg"
 # 让阴影区域半透明、改变颜色、移除图例并删除填充区域左右两侧的空余
 ggplot(cbi,aes(x=Year,y=Anomaly10y))+geom_area(aes(fill=valence),alpha=.4)+geom_line()+geom_hline(yintercept = 0)+scale_fill_manual(values = c("#CCEEFF","#FFDDDD"),guide=FALSE)+scale_x_continuous(expand = c(0,0))