---
# System prepended metadata

title: 快速進行ggplot2繪圖布置-patchwork
tags: [ggplot2, 可視化, R]

---

---
disqus: ahb0222
GA : G-CQ4L16KHK4
---
# 快速進行ggplot2繪圖布置-patchwork
> [color=#40f1ef][name=LHB阿好伯, 2024/01/13][:earth_africa:](https://www.facebook.com/LHB0222/)
###### tags: `R` `ggplot2` `可視化`

[TOC]

**patchwork** 利用簡單的數學運算符組合多個ggplot2圖片
允許任意複雜的圖組成

# 基本應用
## `＋` 加號與 `|` 豎線用於水平排版
![](https://i.imgur.com/e0IF3gv.png)


```r=
library(ggplot2)
library(patchwork)
# 將ggplot2物件保存至變量中

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
p4 <- ggplot(mtcars) + geom_bar(aes(carb))

# 搭配數學運算符號排版
p1 + p2
```

![](https://i.imgur.com/hCr6Exa.png)

## `/`除號用於垂直排版
```r=+
p1/p2
```
![](https://i.imgur.com/caz10al.png)

## `()`括弧用於合併圖區
```r=+
(p1 | p2 | p3) /
      p4
```
![](https://i.imgur.com/qJbEiCe.png)

```r=+
(p1 / p2 /p3) | p4
```
![](https://i.imgur.com/OVJXQwr.png)

# 控制布局

:::success
`plot_layout(
  ncol = NULL,
  nrow = NULL,
  byrow = NULL,
  widths = NULL,
  heights = NULL,
  guides = NULL,
  tag_level = NULL,
  design = NULL`
)
:::

## 欄列數
:::success
`plot_layout(ncol = NULL,
  nrow = NULL )`
:::

```r=
p1 + p2 + p3 
```
![](https://i.imgur.com/sUtmiMu.png)

```r=+
p1 + p2 + p3 + plot_layout(ncol=1)
```
![](https://i.imgur.com/yQ71u55.png)

## 繪圖區大小

`plot_layout(widths = NULL, heights = NULL)`

```r=
p1 / p2 / p3 
```

![](https://i.imgur.com/gpfmaUD.png)
```r=+
p1 / p2 / p3 + plot_layout(heights=c(2,2,1))
```
![](https://i.imgur.com/xOcESVx.png)

## 空白繪圖區
`plot_spacer()`
```r=
(p1 + plot_spacer() + p2)/
(plot_spacer() + p3 + plot_spacer())
```
![](https://i.imgur.com/gkWoVIp.png)

# 指定排版
:::success
`plot_layout(design = NULL)`
:::

```r=
design <- "
  122
  133
  444
"
p1 + p2 + p3 + p4  + plot_layout(design = design)

```
![](https://i.imgur.com/YvzLnHi.png)


## 鑲嵌圖片
:::success
inset_element()
:::

```r=
p1 + inset_element(p2, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99)
```
![](https://i.imgur.com/4iKOJPx.png)

## 圖例控制
### 刪除重複圖例
:::success
`plot_layout(guides='collect')`
:::


```r=
p5 <- ggplot(mtcars) + geom_point(aes(mpg, disp, color=cyl))
p6 <- ggplot(mtcars) + geom_point(aes(mpg, hp, color=cyl))
p5 + inset_element(p6, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99)
```
![](https://i.imgur.com/Wu4SI70.png)

```r=+
p5 + inset_element(p6, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99) +plot_layout(guides='collect')
```
![](https://i.imgur.com/4Ntki7Q.png)

### 更改位置
:::success
`theme(legend.position='bottom')`
:::

```r=+
p5 + inset_element(p6, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99) +plot_layout(guides='collect')&
  theme(legend.position='bottom')
```
![](https://i.imgur.com/g4sdjPa.png)

## 標題與註腳

```r=
p1 + inset_element(p2, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99)+  plot_annotation('標題',caption =  '註腳' )
```

![](https://i.imgur.com/foL4HIM.png)

### 變更標題字體大小
```r=+
p1 + inset_element(p2, left = 0.5, bottom = 0.4, right = 0.99, top = 0.99)+ 
        plot_annotation('標題',caption =  '註腳', 
        theme = theme(plot.title = element_text(size = 20)))
```
![](https://i.imgur.com/deLQ514.png)

## 添加標籤
:::success
`plot_annotation(tag_levels = 'A')`
類型有'a', 'A', '1', 'i, 'I'
:::

```r=
((p1 / p2 /p3) | p4 )+
  plot_annotation(tag_levels = 'A')
```

### 多層次標籤

```r=+
(((p1 / p2 /p3)+ plot_layout(tag_level = 'new')) | p4)  +
  plot_annotation(tag_levels = c('A', '1'))
```

![](https://i.imgur.com/LPAoZsn.png)

```r=+
(((p1 / p2 /p3)+ plot_layout(tag_level = 'new')) | p4)  +
  plot_annotation(tag_levels = list(c('smaple',"type"),'1'))
```

![](https://i.imgur.com/xgzFLK2.png)


## 添加對點陣圖形式（如raster類和nativeRaster類）

patchwork最初是為ggplot2設計的
但它一直支持其他圖形類型
比如grobs和基礎圖形（通過使用公式表示法）
在這次更新中，它增加了對另一種類型的支持
點陣圖。點陣圖類（raster class）和原生點陣圖類（nativeRaster class）現在它們可以被直接識別，並且可以通過`wrap_elements()`函數使用
```r=
library(png)
# 假設您的檔案名稱是 'LOGO2.png' 並且它位於您的工作目錄中
file_path <- 'LOGO2.png'
# 使用 readPNG 函數讀取圖像
logo2 <- readPNG(file_path, native = TRUE)
p1 +logo2 
```
在被patchwork匯入的圖形也會成為事是ggplot2的物件
可以使用ggplot2的一些與法修改圖形呈現
例如背景、標題等
```r=
library(magick)

# 使用 magick 包讀取圖像
logo2 <- image_read('LOGO2.png')

# 將白色背景變為透明
logo2_transparent <- image_transparent(logo2, 'white')

# 保存修改後的圖像
image_write(logo2_transparent, 'LOGO2_transparent.png')

file_path <- 'LOGO2_transparent.png'

# 使用 readPNG 函數讀取圖像
logo2_transparent <- readPNG(file_path, native = TRUE)
p1 +logo2_transparent + ggtitle('AHB Loge') +
  theme(plot.background = element_rect('grey'))
```
![image](https://hackmd.io/_uploads/HJmO61xY6.png)

利用inset_element()就可以將圖片作為浮水印放到繪圖中
```r=
inset_element(p, left, bottom, right, top, align_to = "panel", on_top = TRUE, 
              clip = TRUE, ignore_tag = FALSE) 
```

:::danger

inset_element 函數在 patchwork 包中被用於將一個圖形元素（p）插入到另一個圖形中。
它的主要參數包括：
left, bottom, right, top：這些參數定義了插入圖形的位置和大小，
通常使用“npc”單位（0至1之間的數字），表示在父圖形中的相對位置。
align_to：決定對齊方式，可以是"panel"（默認）、"plot"或"full"。
on_top：布林值，決定圖形是否疊加在頂部。
clip：布林值，用於決定是否剪裁超出範圍的圖形部分。
ignore_tag：布林值，用於決定是否忽略標籤。
:::

```r=
p1 + inset_element(logo2_transparent, 0.8, 0.8, 1, 1, align_to = 'full') + theme_void()
```

![image](https://hackmd.io/_uploads/ryrp5xxF6.png)


## 刪除重複的座標軸

當多個圖表共享相同的y軸時，為了避免視覺上的混亂
可以移除最右側圖表的軸
當然，通過設定主題來移除它，將相關的主題元素設置為element_blank()
但這樣做可能有些麻煩！
使用`element_blank()`非常簡單
這種方法能輕鬆地管理和自定義圖表的軸線顯示
從而使得圖形的整體呈現更加清晰和專業。

```r=
p1+p2
```
![image](https://hackmd.io/_uploads/H1BJJbxFT.png)


```r=+
p1 + p2 + plot_layout(axes = "collect")
```
![image](https://hackmd.io/_uploads/H1bXy-eFp.png)

也可以選擇只刪除Y座標標題

p1 + p2 + plot_layout(axis_titles = "collect")

![image](https://hackmd.io/_uploads/HJJ9g-xYT.png)

若是有使用到 `|` 豎線用於水平鑲嵌的排版
你會發現`plot_layout(axes = "collect")`不起作用

```
p1 + (p1 | p2) + plot_layout(axes = "collect")
```

![image](https://hackmd.io/_uploads/ByHlf-lFp.png)

官方推薦可以使用`widths`進行排版


```r=
plot_layout
function (ncol = NULL, nrow = NULL, byrow = NULL, widths = NULL, 
    heights = NULL, guides = NULL, tag_level = NULL, design = NULL, 
    axes = NULL, axis_titles = axes) 
```


但我更推薦使用design矩陣的方式
更加直覺且能進行更多變化

:::danger
ncol 和 nrow：分別定義列數和行數。
byrow：決定布局是按行還是按列填充。
widths 和 heights：用於設定每列或每行的寬度和高度。
guides：控制圖例的顯示方式。
tag_level：設定標籤層次。
axes 和 axis_titles：控制軸線的收集與顯示方式。
design：提供一個更靈活的方式來定義佈局。
:::

```r=
# 創建一個描述佈局的矩陣
design <- "
  1122
  3333
  4444
"
p1 + p2 + p3 + p4 + plot_layout(design = design, axes = "collect")
```
![image](https://hackmd.io/_uploads/HJBk3bgt6.png)



最後官方展示了一個不受文字拘束的的排版方式
避免受到過長的軸標籤所影響`p1 / p3`
![image](https://hackmd.io/_uploads/Hkocibetp.png)



```
p1 / free(p3) + plot_layout(guides = "collect") & theme_dark()
```

![image](https://hackmd.io/_uploads/Hy9JjZxFa.png)

# 參考資料

>[Multiple plots in ggplot2 with patchwork](https://gotellilab.github.io/GotelliLabMeetingHacks/NickGotelli/ggplotPatchwork.html)
>[Insetting a new patchwork version](https://www.r-bloggers.com/2020/11/insetting-a-new-patchwork-version/)
>[Insetting a new patchwork version](https://www.data-imaginist.com/posts/2020-11-09-insetting-a-new-patchwork-version/index.html)

>
全文分享至

https://www.facebook.com/LHB0222/

有疑問想討論的都歡迎於下方留言

喜歡的幫我分享給所有的朋友 \o/

有所錯誤歡迎指教

# [:page_with_curl: 全部文章列表](https://hackmd.io/@LHB-0222/AllWritings)


![](https://i.imgur.com/47HlvGH.png)

