ixxmu / mp_duty

抓取网络文章到github issues保存
https://archives.duty-machine.now.sh/
122 stars 30 forks source link

DAY6: 第十一章 分面 & 第十二章 配色 #2242

Closed ixxmu closed 2 years ago

ixxmu commented 2 years ago

https://mp.weixin.qq.com/s/4aMXotLMnacMZ2RWt06Swg

github-actions[bot] commented 2 years ago

DAY6: 第十一章 分面 & 第十二章 配色 by 生信技能树

🦝第十一章 分面

数据可视化重要的一点就是对分组数据的呈现。使用ggplot2对每组数据创建一个子图并且并排绘制这些子图很重要。这些图形被称为Trellis格子图形。在ggplot2中又被称为分面facet



11.1 使用分面将数据分割绘制到子图中

Q: 如何在独立的面板中绘制数据的若干子集?
A: 使用facet_grid()或者facet_wrap()函数,指定那个变量来分割数据

# 绘制底图,老演员之一的mpg汽车数据
mpg_plot <- ggplot(mpg, aes(x = displ, y = hwy)) +
  geom_point()

# 根据cyl纵向分面(横向排列)【点在左竖着分】
mpg_plot +
  facet_grid(. ~ cyl)

# 根据drv横向分面(纵向排列)【点在右横着分】
mpg_plot +
  facet_grid(drv ~ .)

# 同时根据drv以及cyl分
mpg_plot +
  facet_grid(drv ~ cyl)
cyl分类横向排列
drv分类纵向排列
同时分类
# 使用facet_wrap()时,各子图将像纸上的文字一样横向排布并换行,其默认使用相等数量的行和列
#可以通过设置nrow(), ncol()来对方阵进行修改
mpg_plot +
  facet_wrap( ~ class)

mpg_plot +
  facet_wrap( ~ class, nrow = 2)#这个和下面的分类是一样的
mpg_plot +
  facet_wrap( ~ class, ncol = 4)
默认方阵
更改行数或者列数后的方阵

*横向排布还是竖向排布呢?
这个取决于你想展示的数据的形式,比如条形图可能横向排布好一点,直方图可能纵向排布好一点。。。
或者用颜色,形状区分,可以自己diy。

11.2 在不同坐标轴下使用分面

Q: 如何绘制坐标轴范围或坐标轴元素不同的多个子图?
A: 将标度设置为free_x, free_y或者free即可 (这个知识点在3.10以及6.2也出现过哦~~)链接

#绘制底图
mpg_plot <- ggplot(mpg, aes(x = displ, y = hwy)) +
  geom_point()

#使用free_y
mpg_plot +
  facet_grid(drv ~ cyl, scales = "free_y")

#使用free
mpg_plot +
  facet_grid(drv ~ cyl, scales = "free")
使用free_y
使用free


*这里无法直接设置各行或者各列的值域,但是可以通过丢弃不想要的数据或者添加geom_blank()的方式控制值域的大小
这里引用链接的部分看如何改变y轴的值域。
方法是

  1. 1. 使用coord_cartesian函数,强制大家的值域一样

mpg_plot +
facet_grid(drv ~ cyl, scales = "free_y")+
coord_cartesian(ylim = c(0, 40))

image.png

2. 使用 expand_limits() 强制各分面从原点开始。使用scale_y_continuous(expand=c(0,0)) 删除 y 轴限制的缓冲区。其中expand的两个值是 c(乘数缓冲区,加法缓冲区)。通过包含 c(0,0),我们不包含轴刻度上的任何缓冲区。

image.png

3. 使用geom_blank()设置每一个图的最大最小值,分别绘制(这个太多了,放弃。。。)


11.3 修改分面标签的文本

Q: 如何修改分面标签的文本?
A: 修改各因子水平即可

library(dplyr)
# 更改原来的数据,为原来的drv分类重命名
mpg_mod <- mpg %>%
  mutate(drv = recode(drv, "4" = "4wd""f" = "Front""r" = "Rear"))#4叫做4wd,F叫做Front,r叫做Rear
# 分面画出来
ggplot(mpg_mod, aes(x = displ, y = hwy)) +
  geom_point() +
  facet_grid(drv ~ .)


*下面仅为facet_grid()进行贴标

#使用贴标函数label_both贴上变量名称和变量名(这个真的挺实用)
ggplot(mpg_mod, aes(x = displ, y = hwy)) +
  geom_point() +
  facet_grid(drv ~ ., labeller = label_both)

# 贴标函数label_parsed()可以读入字符串并且输出数学表达式
mpg_mod <- mpg %>%
  mutate(drv = recode(drv,
    "4" = "4^{wd}",
    "f" = "- Front %.% e^{pi * i}",
    "r" = "4^{wd} - Front"
  ))#先把公式打进去

ggplot(mpg_mod, aes(x = displ, y = hwy)) +
  geom_point() +
  facet_grid(drv ~ ., labeller = label_parsed)#啪的展示数学公式
每个写上变量名
展示数学公式


11.4 修改分面标签和标题的外观

Q: 如何修改分面标签和标题的外观?
A: 使用主题系统通过strip_text()控制文本的外观,strip_background()控制背景的外观。

library(gcookbook)  #经典cabbage_exp数据集
ggplot(cabbage_exp, aes(x = Cultivar, y = Weight)) +
  geom_col() +
  facet_grid(. ~ Date) +
  theme(
    strip.text = element_text(face = "bold", size = rel(1.5)),#控制字体
    strip.background = element_rect(fill = "lightblue", colour = "black", size = 1)
  )#控制背景


🐱第十二章 配色

颜色是一个图形属性(aesthetic),控制它不简单。



12.1 设置对象的颜色

Q: 如何设置图形中几何对象的颜色?
A: 设置colour或者fill参数的值

library(MASS)  # 加载MASS包中的birthwt数据集(老熟人了~)

#fill设置的填充色,colour设置的外框色
ggplot(birthwt, aes(x = bwt)) +
  geom_histogram(fill = "red", colour = "black")
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(colour = "red")
条形图
散点图

*之前我们提到过对于散点图中的点的颜色的设置,21-25号点是可以设置边界色和填充色的

12.2用变量控制颜色

Q: 如何使用一个变量来控制几何对象的颜色?
A: 调用geom时,将aes()中的colour或fill参数的值设置为数据中某一列的列名即可。

当变量是因子时:

library(gcookbook)  #继续大白菜cabbage_exp数据集
#以下两种方法效果相同

ggplot(cabbage_exp, aes(x = Date, y = Weight, fill = Cultivar)) +
  geom_col(colour = "black", position = "dodge")
========================================================================
ggplot(cabbage_exp, aes(x = Date, y = Weight)) +
  geom_col(aes(fill = Cultivar), colour = "black", position = "dodge")
========================================================================

# 以下效果也一样
ggplot(mtcars, aes(x = wt, y = mpg, colour = cyl)) +
  geom_point()
=========================================================================
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(aes(colour = cyl))
=========================================================================
映射到fill上
映射到colour上


当变量是数字时,ggplot可能无法分别所以要先转化为因子再画图
mtcars这个数据集的cyl变量只要4,6,8三个数字

# 把cyl因子化
ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) +
  geom_point()

# 直接创建一个新的数据框加上因子化的cyl
library(dplyr)
mtcars_mod <- mtcars %>%
  mutate(cyl = as.factor(cyl))  #cyl因子化
ggplot(mtcars_mod, aes(x = wt, y = mpg, colour = cyl)) +
  geom_point()
因子化向量


12.3 使用对色盲患者友好的调色板

Q: 如何使用色盲也能分辨的调色盘?
A: 使用viridis包中的轮廓色标度。通过明暗区别,色盲看也没毛病~
当数据是连续的:scale_fill_viridis_c()
当数据是离散的:scale_fill_viridis_d()

library(gcookbook)  # 加载uspopage数据集,记载美国人口1900-2002的分布
#绘制底图
uspopage_plot <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) +
  geom_area()

# 加上viridis色系
uspopage_plot +
  scale_fill_viridis_d()
viridis调色板


正常人看猫猫
绿色盲看猫猫
红色盲看猫猫
蓝色盲看猫猫


*微软的猫猫表情

12.4 对离散变量使用不同的调色板

Q: 如何对离散映射的变量使用不同的颜色?
A:

填充色标度轮廓色标度描述
scale_fill_discrete()scale_colour_discrete()色轮周围均匀等距色
scale_fill_hue()scale_colour_hue()同上
scale_fill_grey()scale_colour_grey()灰度调色板
scale_fill_viridis_d()scale_colour_viridis_d()Viridis调色板
scale_fill_brewer()scale_colour_brewer()ColorBrewer调色板
scale_fill_manual()scale_colour_manual()手动调色板
library(gcookbook)  #加载数据集和viridis调色板
library(viridis)  

# 绘制底图
uspopage_plot <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) +
  geom_area()

# 以下四种方法效果相同
uspopage_plot
# uspopage_plot + scale_fill_discrete()
# uspopage_plot + scale_fill_hue()
# uspopage_plot + scale_color_viridis()

# Viridis调色板
uspopage_plot +
  scale_fill_viridis(discrete = TRUE)

# ColorBrewer调色板
uspopage_plot +
  scale_fill_brewer()
正常版
viridis调色板
ColorBrewer调色板


默认调色板:
默认调色板来自HCL(hue-chroma-lightness)色系的色轮,默认亮度为65,有亿点点刺眼,所以可以调低亮度降低l值,让颜色深亿点点。

# 默认亮度l=65
hw_splot <- ggplot(heightweight, aes(x = ageYear, y = heightIn, colour = sex)) +
  geom_point()

# l=45
hw_splot +
  scale_colour_hue(l = 45)
l=65
l=45

ColorBrewer调色板:

hw_splot +
  scale_colour_brewer(palette = "Oranges"+
  theme_bw()


灰度调色板:
适合黑白打印,标度范围是0-1, 0是黑1是白。默认是0.2~0.8.范围可改

hw_splot +
  scale_colour_grey()

# Reverse the direction and use a different range of greys
hw_splot +
  scale_colour_grey(start = 0.7, end = 0)
灰度0-1
灰度0.7-1


12.5 对离散变量使用自定义调色板

Q: 对离散的变量,如何使用不同的颜色?
A: 这里将使用scale_colour_manual()函数自定义颜色。可以是已经命名的,也可以是RGB的

library(gcookbook)  #依旧是heightweight数据集
# 创建底图
hw_plot <- ggplot(heightweight, aes(x = ageYear, y = heightIn, colour = sex)) +
  geom_point()

#使用颜色名
hw_plot +
  scale_colour_manual(values = c("red""blue"))

# 使用RGB值
hw_plot +
  scale_colour_manual(values = c("#CC6666""#7777DD"))

# 使用基于viridis轮廓色标度的RGB值
hw_plot +
  scale_colour_manual(values = c("#440154FF""#FDE725FF")) +
  theme_bw()
颜色名
RGB
viridis based RGB

*如果是因子水平,会按照因子的水平给其上色
levels(heightweight$sex)
*如果是非因子水平,则按照字母表顺序上色
*如果要自定义颜色分配,可以使用带有名称的向量参数
hw_plot +
scale_colour_manual(values = c(m = "blue", f = "red"))

颜色名称,共有六百多个颜色


RGB颜色
颜色由6个数字组成(十六进制数),如#RRGGBB. 在16进制中,数字先从0到9, 然后紧接着从A到F。A是10,F是15. 每一种颜色都有两个数字来表示。范围从00到FF。颜色#FF0099中,FF代表225红色,0代表绿色,153代表蓝色,整体代表品红色。
RGB规则:一般数字越大越亮,灰色要把3个颜色设置为一样的值。RGB对应的是CMY印刷三原色,即cyan,品红,yellow。红色越大,颜色越红,红色越小,颜色越青。

library(viridis)
viridis(2#从viridis scale里面取俩颜色的RGB值
[1"#440154FF" "#FDE725FF"
inferno(5)   #从inferno scale里面取五个颜色的RGB值
[1"#000004FF" "#56106EFF" "#BB3754FF" "#F98C0AFF" "#FCFFA4FF"


12.6 对连续变量使用自定义调色板

Q: 如何对连续变量自定义调色板?
A:

library(gcookbook)  #加载heightweight数据集
# 绘制底图
hw_plot <- ggplot(heightweight, aes(x = ageYear, y = heightIn, colour = weightLb)) +
  geom_point(size = 3)

##muted()函数降低颜色的饱和度,使用的RGB格式
#渐变色中间用白色划分
library(scales)#设置颜色
hw_plot +
  scale_colour_gradient2(
    low = muted("red"),#低的红,中的白,高的蓝
    mid = "white",
    high = muted("blue"),
    midpoint = 110
  )

#使用两种颜色的渐变色(black and white)
hw_plot +
  scale_colour_gradient(low = "green", high = "yellow")#黑白渐变

#使用多种颜色的渐变色
hw_plot +
  scale_colour_gradientn(colours = c("darkred""orange""yellow""white"))#多色渐变
默认渐变
三色渐变
双色渐变
多色渐变
填充色轮廓色标度描述
scale_fill_gradient()scale_colour_gradient()双色渐变
scale_fill_gradient2()scale_colour_gradient2()三色渐变
scale_fill_gradientn()scale_colour_gradientn()多色渐变
scale_fill_viridis_c()scale_colour_viridis_c()Viridis调色盘


12.7 根据竖直设定阴影区域颜色

Q: 如何根据y值设置阴影区域的颜色?
A: 增加一列对y进行分类,然后映射到填充标度上。

library(gcookbook)  # 使用climate数据
library(dplyr)

climate_mod <- climate %>%
  filter(Source == "Berkeley"%>%
  mutate(valence = if_else(Anomaly10y >= 0"pos""neg"))#筛选出Berkeley的数据,如果大于等于0就是pos小于就是neg

climate_mod
     Source Year Anomaly1y Anomaly5y Anomaly10y Unc10y valence
1   Berkeley 1800        NA        NA     -0.435  0.505     neg
2   Berkeley 1801        NA        NA     -0.453  0.493     neg
3   Berkeley 1802        NA        NA     -0.460  0.486     neg
4   Berkeley 1803        NA        NA     -0.493  0.489     neg
5   Berkeley 1804        NA        NA     -0.536  0.483     neg
6   Berkeley 1805        NA        NA     -0.541  0.475     neg

ggplot(climate_mod, aes(x = Year, y = Anomaly10y)) +
  geom_area(aes(fill = valence)) +
  geom_line() +
  geom_hline(yintercept = 0)
0附近有很多阴影


为了解决这个问题,将使用approx()函数将数据插值到1000个点左右

# approx() 返回插值向量
interp <- approx(climate_mod$Year, climate_mod$Anomaly10y, n = 1000)

# 重新插入一列标记正负
cbi <- data.frame(Year = interp$x, Anomaly10y = interp$y) %>%
  mutate(valence = if_else(Anomaly10y >= 0"pos""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 = 'none'+#设置颜色
  scale_x_continuous(expand = c(00))#删除两侧空余