Code
library(tidyverse)
library(ggplot2)
library(dplyr)
library(patchwork) # 拼接两幅图
library(hrbrthemes)
Rui
October 14, 2022
来源:http://r-graph-gallery.com/line-chart-dual-Y-axis-ggplot2.html
day | temperature | price |
---|---|---|
2019-01-01 | 0.9210156 | 100.56474 |
2019-01-02 | 0.3817453 | 99.47352 |
2019-01-03 | 0.7530957 | 97.75718 |
2019-01-04 | 0.7020752 | 95.69686 |
2019-01-05 | 0.0907566 | 94.44658 |
2019-01-06 | 0.1273013 | 93.49653 |
使用 sec.axis()
来添加第二个坐标轴。
coeff <- 10 # 设置比例系数
temperatureColor <- "seagreen"
priceColor <- "tomato"
ggplot(data, aes(x=day)) +
geom_line( aes(y=temperature), size=2, color=temperatureColor) +
geom_line( aes(y=price / coeff), size=2, color=priceColor) +
# 除以10以保证与temperature有相同的尺度
scale_y_continuous(
# 第一坐标轴
name = "Temperature (Celsius °)",
# 第二坐标轴
sec.axis = sec_axis(~.*coeff, name="Price ($)")
) +
theme(
axis.title.y = element_text(color = temperatureColor, size=13),
axis.title.y.right = element_text(color = priceColor, size=13)
) +
ggtitle("Temperature down, price up")
---
title: "双轴折线图"
author: "Rui"
date: "2022-10-14"
categories: [R, 可视化, ggplot2]
image: "double-flowers.jpg"
format:
html:
code-fold: true
code-tools: true
---
```{r setup, include = FALSE}
# 设置默认参数
knitr::opts_chunk$set(
echo = TRUE,
fig.align = "center",
message = FALSE,
warning = FALSE,
collapse = TRUE
)
```
> 来源:<http://r-graph-gallery.com/line-chart-dual-Y-axis-ggplot2.html>
## 导入程序包
```{r}
library(tidyverse)
library(ggplot2)
library(dplyr)
library(patchwork) # 拼接两幅图
library(hrbrthemes)
```
## 创建虚拟数据
```{r}
data <- data.frame(
day = as.Date("2019-01-01") + 0:99,
temperature = runif(100) + seq(1, 100)^2.5 / 10000,
price = runif(100) + seq(100, 1)^1.5 / 10
)
data %>% head() %>% knitr::kable()
```
## 基础绘图
```{r}
p1 <- ggplot(data, aes(x=day, y=temperature)) +
geom_line(color = "seagreen", size = 2) +
ggtitle("Temperature: range 1-10") +
theme_ipsum()
p2 <- ggplot(data, aes(x=day, y=price)) +
geom_line(color = "tomato", size = 2) +
ggtitle("Price: range 1-100") +
theme_ipsum()
# 使用patchwork程序包进行拼接
p1 + p2
```
## 双 Y 轴
使用 `sec.axis()` 来添加第二个坐标轴。
::: {.callout-note}
`sec.axis(trans=~.*10, name="Second Axis")` 中的 `trans=~.*10` 是指对第一个坐标轴刻度乘以 10 作为第二个坐标轴的刻度。这个系数 10 是怎么确定的呢?由上图可知:以变量 price 为第二坐标轴的刻度几乎是以 temperature 为第一坐标轴的刻度的 10 倍。
:::
```{r}
ggplot(data, aes(x=day, y=temperature)) +
# 自定义Y轴
scale_y_continuous(
# 第一个坐标轴
name = "First Axis",
# 添加第二个坐标轴
sec.axis = sec_axis(trans=~.*10, name="Second Axis")
) +
theme_ipsum()
```
## 使用双 Y 轴作图
```{r}
coeff <- 10 # 设置比例系数
temperatureColor <- "seagreen"
priceColor <- "tomato"
ggplot(data, aes(x=day)) +
geom_line( aes(y=temperature), size=2, color=temperatureColor) +
geom_line( aes(y=price / coeff), size=2, color=priceColor) +
# 除以10以保证与temperature有相同的尺度
scale_y_continuous(
# 第一坐标轴
name = "Temperature (Celsius °)",
# 第二坐标轴
sec.axis = sec_axis(~.*coeff, name="Price ($)")
) +
theme(
axis.title.y = element_text(color = temperatureColor, size=13),
axis.title.y.right = element_text(color = priceColor, size=13)
) +
ggtitle("Temperature down, price up")
```
::: {.callout-note}
在添加 `geom_line` 的时候为什么还要将 price 除以 coeff?虽然设置了第二坐标轴,但实际上第二坐标轴只是一个“注释”,图整体的网格线还是以第一坐标轴的尺度显示的。所以必须要将第二个变量除以比例系数来保证与第一个变量的尺度相同。
:::