ggplot2における 軸関連のコントロール～逆引き的ミニまとめ～

:::note info
こちらの記事は、Tokyo.R第99回R勉強会でのLT発表資料をWeb用に再編したものです。
:::

# ggplot2で軸関連のコントロールをしようとすると結構こんがらがる
ggplot2でプロットを行っていると、見やすさやレイアウトなどの観点から軸関連の設定を変えたいときがあります。

しかし
- **軸に関連する設定は`scale_`関数や`theme`関数などをまたいで行われる**
- **人によっては普段使わないような引数を用いて設定を行う必要がある**

といった背景から、ggplot2で軸のコントロールをしようとすると実は結構こんがらがります。

そのため、いざ軸のコントロールをしようとすると、「改めて考えてみると、この操作ってどんなコードでできるのかよくわからないな……？」となることも多いと思います。



:::note info
例えば
「軸ラベルの内容」は`scale_*`関数等で設定する必要がありますが、「軸ラベルのフォント」については`theme`関数で設定する必要があります
:::

**そこでここでは、こんがらがりがちな軸関連のコントロールを逆引き的にご紹介しようと思います！**

:::note warn
- 発表者が把握している書き方をご紹介しますが、他にもっとよい書き方があるかもしれません
- どちらかというと初心者向けの内容になります
- データは`palmerpenguins::penguins`を利用します（参考：https://allisonhorst.github.io/palmerpenguins/） 
:::

# 基本のプロット
以下のgraph1、graph2を基本のプロットとして、設定でどのようにプロットが変わるかを確認します。

|graph1|graph2|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|

```描画コード.R
theme_tmp <- theme(
  axis.title = element_text(family = "sans", size = 10), 
  axis.text = element_text(family = "sans", size = 10), 
  legend.title = element_text(family = "sans", size = 10), 
  legend.text = element_text(family = "sans", size = 10), 
  panel.background = element_blank(), 
  panel.border = element_rect(fill = NA, color = "black"), 
  panel.grid.major = element_line(color = "black", size = 0.2), 
  panel.grid.minor = element_line(color = "black", linetype = 2, size = 0.2)
)

graph1 <- ggplot(data = penguins) + 
  geom_point(aes(x = bill_length_mm, y = bill_depth_mm, color = species, shape = species), size = 1.2, alpha = 0.9) + 
  scale_color_manual(values = MetBrewer::met.brewer(name = "Hiroshige", n = 3)) + 
  theme_tmp
  
ggsave(graph1, file = "graph1.png", width = 10.5, height = 7, units = "cm", dpi = 200)
  

graph2 <- ggplot(data = penguins) + 
  geom_violin(aes(x = species, y = bill_length_mm, fill = species)) + 
  scale_fill_manual(values = MetBrewer::met.brewer(name = "Hiroshige", n = 3)) + 
  theme_tmp + 
  theme(
    panel.grid.major = element_blank()
  )

ggsave(graph2, file = "graph2.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```
※カラーパレットとして`MetBrewer`を使用しています（参考：[期待の新カラーパレット {MetBrewer}：メトロポリタン美術館所蔵の作品の色合いをRで！](https://qiita.com/ocean_f/items/ab86eac9550607ec5e0e)）。


# 軸のコントロールとそれを実現する設定
#### 軸の範囲と軸目盛の間隔を調整
**→　`scale_*`内で`limit`, `breaks`, `minor_breaks`を設定！**

```.R
graph1_axisrange <- graph1 + 
  scale_x_continuous(limits = c(30, 60), breaks = seq(30, 60, 10), minor_breaks = seq(30, 60, 5)) + 
  scale_y_continuous(limits = c(10, 25), breaks = seq(10, 30, 10), minor_breaks = seq(10, 30, 5))

ggsave(graph1_axisrange, file = "graph1_axisrange.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph1_axisrange.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/1e62f40f-e7d5-bb8f-00d2-02b78f35a333.png)|

#### 軸タイトル、ラベルの文字の大きさやフォントを変える
**→　`theme`内の`axis.title`, `axis.text`に対し、`element_text`を用いて設定！**


```.R
graph1_textfont <- graph1 + 
  theme(
    axis.title = element_text(family = "serif", size = 15), 
    axis.text = element_text(family = "mono", size = 15)
  )

ggsave(graph1_textfont, file = "graph1_textfont.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph1_textfont.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/3be090a5-a9f4-91f1-603c-2fdc1d511449.png)|


#### 軸ラベルの文字の角度を変える
**→　`element_text`内で`angle`を設定！**

```.R
graph2_textangle <- graph2 + 
  theme(
    axis.title.x = element_blank(), 
    axis.text.x = element_text(angle = 90)
  )

ggsave(graph2_textangle, file = "graph2_textangle.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_textangle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/831ca9e0-2452-6ac0-1ca4-6649b34ffa6e.png)|


#### 軸タイトル、軸ラベルのテキストを編集する
**→　`scale_*`関数内で`name`, `labels`を設定！**


```.R
graph1_titletext <- graph1 + 
  scale_x_continuous(name = "Bill length(mm)", limits = c(30, 60), breaks = seq(30, 60, 10), minor_breaks = seq(30, 60, 5), labels = paste0(seq(30, 60, 10), ".0"))

ggsave(graph1_titletext, file = "graph1_titletext.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph1_titletext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/8d0b7587-dd0b-20c3-99a1-b1fc3b6ce104.png)|


#### 対数軸を使用したい！
**→　`scale_ _log10`あるいは`scale_`関数内で`trans = "log10"`を指定！**


```.R
graph1_log10 <- graph1 + 
  scale_x_log10() + 
  scale_y_continuous(trans = "log10")

ggsave(graph1_log10, file = "graph1_log10.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph1_log10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/d6179e5f-23d9-91d2-34fc-a6510da26173.png)|



#### 軸タイトル、軸ラベル、軸目盛を消したい
**→　`theme`関数内で`element_blank`関数を用いる！**
※`name = "none"`や`breaks = ""`とは挙動が違うので注意！（これらを設定した場合、「タイトルやラベルがあるスペースは残っているが文字は見えない状態」になります）


```.R
graph2_axistitletext <- graph2 + 
  theme(
    axis.title.x = element_blank(), 
    axis.text.x = element_blank(), 
    axis.ticks.x = element_blank()
  )

ggsave(graph2_axistitletext, file = "graph2_axistitletext.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_axistitletext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/9b020963-5b26-bfcf-ac11-3d45709e56ef.png)|


#### 片方の軸を消す
**→　`element_blank`で軸や枠線を非表示に！**


```.R
graph2_oneaxis <- graph2 + 
  theme(
    axis.line.x = element_blank(), 
    panel.background = element_blank(), 
    panel.border = element_blank()
  )

ggsave(graph2_oneaxis, file = "graph2_oneaxis.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_oneaxis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/61ebb53e-3474-acbc-427a-0be98ecb41f5.png)|


#### 軸の位置を変えたい！
**→　`scale_`内で`position`を設定！**


```.R
graph2_position <- graph2 + 
  scale_x_discrete(position = "top")

ggsave(graph2_position, file = "graph2_position.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_position.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/4b1e678d-6d4c-36d0-faad-4c31d6920d95.png)|

#### x軸とy軸を入れ替えたい！
**→　`coord_flip`を使う！**


```.R
graph2_flip <- graph2 + 
  coord_flip()

ggsave(graph2_flip, file = "graph2_flip.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_flip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/2e757a09-85bc-baf6-7f7c-ed9dc9edc045.png)|


#### 軸を矢印にしたい！
**→　`theme`内の`axis.line`に対し、`element_line`を用いて設定！**


```.R
graph1_arrow <- graph1 + 
  theme(
    axis.line = element_line(arrow = arrow(length = unit(0.2, "cm")))
  )

ggsave(graph1_arrow, file = "graph1_arrow.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
| ![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/50f90360-6f48-1142-f323-e7277c4408ac.png)|![graph1_arrow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/2adad606-6293-cacd-0433-4af9515e5c41.png)|

#### 軸ラベルに斜字や太字交じりのラベルを使いたい！
**→　`theme`内の`axis.text`に対し、`ggtext::element_markdown`を用いて設定！**
上記の設定に加えて、labelsで設定できるラベル内容にMarkdown記法を用いることで、軸ラベル内に複数の字体を混在させることができるようになります。
参考：https://wilkelab.org/ggtext/

```.R
graph2_scientificname <- graph2 + 
  scale_x_discrete(labels = c("<b><i>P. adeliae</i></b><br><span style = 'font-size:4pt'>(Hombron & Jacquinot, 1841)</span>", "<b><i>P. antarcticus</i></b><br><span style = 'font-size:4pt'>(Forster, 1781)</span>", "<b><i>P. papua</i></b><br><span style = 'font-size:4pt'>(Forster, 1781)</span>")) + 
  theme(
    axis.text.x = ggtext::element_markdown(family = "sans", size = 8)
  )

ggsave(graph2_scientificname, file = "graph2_scientificname.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_scientificname.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/23ba2b15-92f0-282c-fc6e-2213f8ece856.png)|

※学名参考：https://en.wikipedia.org/wiki/Ad%C3%A9lie_penguin; https://en.wikipedia.org/wiki/Chinstrap_penguin; https://en.wikipedia.org/wiki/Gentoo_penguin


#### 2つめの軸を追加したい！
**→　`scale_`関数内で`sec.axisを`設定！**

```.R
graph2_secaxis <- graph2 + 
  scale_y_continuous(sec.axis = sec_axis(name = "Bill length(cm)", trans = ~ . * 0.1))

ggsave(graph2_secaxis, file = "graph2_secaxis.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_secaxis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/c803b6de-f70d-0249-e4a3-f9490c95f4b1.png)|


#### 応用：軸ラベルを軸の位置に被らせたい！
**→　`coord_cartesian`内で`clip = "off"`を指定し、`annotate`で文字列をプロット！**

```.R
graph2_clipoff <- graph2 + 
  annotate("text", x = 1:3, y = 30, label = c("Adelie", "Chinstrap", "Gentoo"), angle = 45) + 
  coord_cartesian(clip = "off") + 
  theme(
    axis.title.x = element_blank(), 
    axis.text.x = element_blank(), 
    axis.ticks.x = element_blank(), 
    panel.background = element_blank(), 
    panel.border = element_blank()
  )

ggsave(graph2_clipoff, file = "graph2_clipoff.png", width = 10.5, height = 7, units = "cm", dpi = 200)
```

|Before|After|
|:-----------:|:------------:|
|![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/15ec528e-80cd-0bc9-ddb7-4a10a3fe70ad.png)|![graph2_clipoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/c548cb02-f0c0-424a-0b1d-d0268fe2086d.png)|


# さいごに
これらのコントロールは、

- **必要になったときに、検索して出てきたコードを実際に使ってみる**

- **関数のレファレンスを見て、グラフのどのような部分をコントロールできるかを確認しておく**

と覚えやすいと思います！

※theme設定に関しては以前投稿した以下の記事もご参照ください。
[【ggplot2】themeの使い方まとめ2021：作ったグラフの見た目をきれいにコントロールするために
](https://qiita.com/ocean_f/items/03a31a8a7ce222bb3838)