简体   繁体   English

使用 ggplot2 同时为双 y 轴 plot 设置左右极限范围

[英]Set left and right limit ranges simultaneously for dual y-axis plot using ggplot2

Given a dataframe df :给定一个 dataframe df

df <- structure(list(date = c("2022-4-30", "2022-5-5", "2022-5-6", 
"2022-5-9", "2022-5-10", "2022-5-11", "2022-5-12", "2022-5-13", 
"2022-5-16", "2022-5-17", "2022-5-18", "2022-5-19", "2022-5-20"
), value1 = c(6, 6.1, 6.5, 6.9, 7.3, 7.7, 8.1, 8, 7.9, 7.8, 7.7, 
7.6, 7.5), value2 = c(-1L, -2L, 0L, 6L, 7L, 5L, 3L, 10L, 18L, 
16L, 12L, 19L, 20L), value3 = c(2.7, 2.4, 1.7, 0.5, -0.5, 0.2, 
-0.3, -0.2, 0.4, 0.9, 1.3, 1.1, 1)), class = "data.frame", row.names = c(NA, 
-13L))

Out:出去:

        date value1 value2 value3
1  2022-4-30    6.0     -1    2.7
2   2022-5-5    6.1     -2    2.4
3   2022-5-6    6.5      0    1.7
4   2022-5-9    6.9      6    0.5
5  2022-5-10    7.3      7   -0.5
6  2022-5-11    7.7      5    0.2
7  2022-5-12    8.1      3   -0.3
8  2022-5-13    8.0     10   -0.2
9  2022-5-16    7.9     18    0.4
10 2022-5-17    7.8     16    0.9
11 2022-5-18    7.7     12    1.3
12 2022-5-19    7.6     19    1.1
13 2022-5-20    7.5     20    1.0

I use code below to plot dual y-axis (left side for value1 and value3 , right side for value2 ):我将下面的代码用于 plot 双 y 轴(左侧为value1value3 ,右侧为value2 ):

df_m <- melt(df, id.vars = 'date')
df_m <- df_m %>% 
  mutate(date=as.Date(date))

df_m1 <- df_m %>% 
  filter(variable %in% c("value1", 'value3')) 

df_m2 <- df_m %>% 
  filter(variable %in% c("value2")) %>%
  mutate(value = value * 0.6)


df_m2
coeff = 1/0.6

ggplot() +
  geom_line(data = df_m1[!is.na(df_m1$value), ], aes(x = date, y = value, col = variable), alpha = 1, size = 1) +
  geom_line(data = df_m2[!is.na(df_m2$value), ], aes(x = date, y = value, col = variable), alpha = 1, size = 1) +
  scale_y_continuous(
    name = '',
    # limits=c(-1, 9),
    sec.axis = sec_axis(~.*coeff, name = "")) 

Out:出去:

在此处输入图像描述

Now I wondering if it's possible to set limits=c(-1, 9) for left y-axis and limits=c(-2, 20) for right y-axis simultaneously using ggplot2?现在我想知道是否可以同时使用 ggplot2 为左 y 轴设置limits=c(-1, 9)y 轴设置limits=c(-2, 20)

I try with code below, but right y-axis's changed to around limits=c(-2, 15) , not as figure above.我尝试使用下面的代码,但右 y 轴更改为大约limits=c(-2, 15) ,而不是如上图。 Alternative solutions to plot a similar dual y-axis plot will be welcomed as well. plot 和类似的双 y 轴 plot 的替代解决方案也将受到欢迎。

ggplot() +
  geom_line(data = df_m1[!is.na(df_m1$value), ], aes(x = date, y = value, col = variable), alpha = 1, size = 1) +
  geom_line(data = df_m2[!is.na(df_m2$value), ], aes(x = date, y = value, col = variable), alpha = 1, size = 1) +
  scale_y_continuous(
    name = '',
    limits=c(-1, 9),
    sec.axis = sec_axis(~.*coeff, name = ""))

在此处输入图像描述

Reference:参考:

https://r-graph-gallery.com/line-chart-dual-Y-axis-ggplot2.html https://r-graph-gallery.com/line-chart-dual-Y-axis-ggplot2.html

This is one of the reasons ggh4x::help_secondary() was written.这是编写ggh4x::help_secondary()的原因之一。 Essentially it figures out the transformation needed to get the secondary range to match the primary range and the inverse.本质上,它计算出使次要范围与主要范围相匹配所需的转换和反向。 We apply the transformation to secondary data and it's inverse is used as the trans argument of the secondary axis.我们将转换应用于辅助数据,它的逆被用作辅助轴的trans参数。

In your example, we can drop the mutate() bit, because that is handled in sec$proj() .在您的示例中,我们可以删除mutate()位,因为这是在sec$proj()中处理的。

(Disclaimer: I wrote ggh4x) (免责声明:我写了 ggh4x)

# df <- structure(...) # omitted for brevity

library(ggplot2)
library(dplyr)
library(reshape2)

df_m <- melt(df, id.vars = 'date')
df_m <- df_m %>% 
  mutate(date=as.Date(date))

df_m1 <- df_m %>% 
  filter(variable %in% c("value1", 'value3')) 

df_m2 <- df_m %>% 
  filter(variable %in% c("value2"))

sec <- ggh4x::help_secondary(
  name = "",
  primary = c(-1, 9), secondary = c(-2, 20),
)

ggplot() +
  geom_line(data = df_m1[!is.na(df_m1$value), ], 
            aes(x = date, y = value, col = variable), alpha = 1, size = 1) +
  geom_line(data = df_m2[!is.na(df_m2$value), ], 
            aes(x = date, y = sec$proj(value), col = variable), alpha = 1, size = 1) +
  scale_y_continuous(
    limits = c(-1, 9),
    name = '',
    sec.axis = sec) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM