ggplot2辅助轴未映射到变换

时间:2019-02-09 21:18:34

标签: r ggplot2

使用ggplot2将辅助轴放置到绘图时遇到麻烦。具体来说,辅助轴向后映射到应该的位置。我不确定我是否在错误地使用sec.axis参数,这是转换到主轴数据的问题还是奇怪的错误。

library(ggplot2)
library(VGAM)
#dput(x) # create reproducible data set
structure(list(DATE = structure(c(15188, 15233, 15270, 15291, 
15320, 15380, 15426, 15481, 15510, 15547, 15553, 15156, 15188, 
15233, 15289, 15426, 15431, 15481, 15510, 15547, 15188, 15233, 
15270, 15291, 15340, 15380, 15426, 15431, 15510, 15553, 15156, 
15188, 15233, 15270, 15291, 15380, 15426, 15431, 15510, 15521, 
14908, 14943, 14994, 15028, 15052, 15082, 15104, 15147, 15174, 
15202, 15231, 15264, 15273, 14908, 14943, 14992, 15028, 15050, 
15082, 15103, 15147, 15174, 15202, 15237, 15272, 15273), class = "Date"), 
    JULIAN = c(578, 623, 660, 681, 710, 770, 816, 871, 900, 937, 
    943, 546, 578, 623, 679, 816, 821, 871, 900, 937, 578, 623, 
    660, 681, 730, 770, 816, 821, 900, 943, 546, 578, 623, 660, 
    681, 770, 816, 821, 900, 911, 298, 333, 384, 418, 442, 472, 
    494, 537, 564, 592, 621, 654, 663, 298, 333, 382, 418, 440, 
    472, 493, 537, 564, 592, 627, 662, 663), tempkt = c(38.2493118575297, 
    38.8918139130956, 38.9751719525914, 38.9255342604126, 39.3289327383671, 
    39.2502632853114, 38.4917383006476, 38.085196933948, 37.9534931405596, 
    38.0571510040783, 37.8609414814348, 41.0441867847656, 41.2983574639028, 
    41.9484899893221, 42.2016623398487, 42.2929040412033, 42.2093300154886, 
    41.5844615902843, 40.9536690489977, NaN, 39.7920269821338, 
    39.592156547337, 39.61233495346, 39.6624446808614, 39.8342150883199, 
    40.3918668247933, 40.2143769350208, 40.2393349250642, 39.8234837693704, 
    39.742700709588, 40.424224969676, 40.4451990799614, 40.8109263766474, 
    40.9865924998806, 41.0375724497903, 41.2189808187393, 41.3206162959404, 
    40.9766042214562, 40.4577779507897, 40.382158701417, 41.8201031347131, 
    41.8147160575188, 41.6767569469964, 41.658527312322, 41.6448016266584, 
    41.6420919537599, 41.5754495299616, 41.3110244532269, 41.3494251124613, 
    41.4485458187588, 41.546733896547, 41.4299365483899, 41.0628872985866, 
    41.9901884386202, 42.1042719644897, 42.0470007228451, 42.0555023596041, 
    41.9215569534753, 41.7497755339366, 41.401267252905, 40.9710848825845, 
    40.9252447192775, 41.1847858804725, 41.5180158973558, 41.6932841697949, 
    41.625926125789), SITE = c("hver", "hver", "hver", "hver", 
    "hver", "hver", "hver", "hver", "hver", "hver", "hver", "st14", 
    "st14", "st14", "st14", "st14", "st14", "st14", "st14", "st14", 
    "st6", "st6", "st6", "st6", "st6", "st6", "st6", "st6", "st6", 
    "st6", "st9", "st9", "st9", "st9", "st9", "st9", "st9", "st9", 
    "st9", "st9", "st7", "st7", "st7", "st7", "st7", "st7", "st7", 
    "st7", "st7", "st7", "st7", "st7", "st7", "oh2", "oh2", "oh2", 
    "oh2", "oh2", "oh2", "oh2", "oh2", "oh2", "oh2", "oh2", "oh2", 
    "oh2")), row.names = c(NA, -66L), class = "data.frame")
#function to transform tempkt
overkt_to_C <<- Vectorize(function(x) {
  VGAM::reciprocal(x*(8.61733*10^-5))-273.15})

#applying the function to an object to check ouput
x$tempC = overkt_to_C(x$tempkt)#new transformed variable
x$measure = rnorm(nrow(x))#random data row

现在,当我将原始变量tempkt与用tempC函数创建的新变量overkt_to_C相对时,它显示出转换已完成了预期的工作:

ggplot(x, aes(x = tempkt, y = tempC)) + geom_line(size = 2) +
labs(x = "Boltzmann Temperature (1/kt)", y = "Temperature C")

testing transformation effects

重要的是,存在一个负关系,x = 38对应于y =〜35,x = 42对应于y =〜0。但是,当我尝试使用overkt_to_C函数将tempkt变换到显示tempC的辅助轴上时,该变换不会显示这种负相关关系。相反,这是积极的。主轴(底部)上的x = 38对应于次级(顶部)上的〜0而不是〜35:

ggplot(x, aes(x = tempkt, y = measure)) +
  scale_x_continuous(name = "Boltzmann Temperature", sec.axis = sec_axis(~overkt_to_C(.), name = expression("Temperature"~degree*"C")))

plot showing incorrect sec.axis mapping

我尝试过以多种方式使它们中的任一个方向反转,如果它们做任何事情,它们都会使两个轴都反转:

ggplot(x, aes(y = tempkt, x = measure)) + coord_flip() +
  scale_y_continuous(name = "Boltzmann Temperature", trans = 'reverse',
                     sec.axis = sec_axis(~overkt_to_C(.), name = expression("Temperature"~degree*"C")))

我尝试了从这个问题的答案中得到的建议:ggplot2: Reversing secondary continuous x axis

ggplot(x, aes(y = tempkt, x = measure)) + coord_flip() +
  scale_y_continuous(name = "Boltzmann Temperature", trans = 'reverse',
                     sec.axis = sec_axis(~(33.3538 - overkt_to_C(.)), name = expression("Temperature"~degree*"C")))##33.353 is max x$tempC

这很奇怪,只稍微移动了上轴。我能得到的最接近的是它,它映射接近期望值的负值(这可能只是巧合):

ggplot(x, aes(x = tempkt, y = measure)) +
  scale_x_continuous(name = "Boltzmann Temperature", trans = 'reverse',
                     sec.axis = sec_axis(~(-33.3538 + overkt_to_C(.)), name = "Temperature C"))

编辑:下面是一个近似值(由上面的代码直接创建),带有一个重要的警告,类似于预期的输出:值是负数,而不是正数,如第一个所示。 。我不知道这是否符合事实。但是可以预期的是,上轴应该按照第一个图所示的关系进行映射,但目前尚不知道这是出于未知原因。 correct-ish plot of secondary axis

然后不顾一切地尝试,从DJ Casper那里得到一些建议,尝试使用cha cha slide方法:“ reverse-reverse”:

ggplot(x, aes(y = tempkt, x = measure)) + coord_flip() +
  scale_y_reverse(name = "Boltzmann Temperature", trans = 'reverse',
                     sec.axis = sec_axis(~overkt_to_C(.), name = expression("Temperature"~degree*"C")))

关于为什么发生这种情况,为什么减去最大tempC值的解决方法无法产生预期结果的任何想法,和/或潜在的解决方法,将不胜感激。

1 个答案:

答案 0 :(得分:1)

我在Github上提交了此问题,但这是一个手动解决方法。我简化了转换函数,但是无论您提供逆函数如何,转换函数都应相同。

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 3.5.2
library(scales)

kt_to_C <- function(x) (
  1/(x*(8.61733*10^-5)) - 273.15
)

C_to_kt <- function(y) {
  1/(8.61733*10^-5) * 1/(y + 273.15)
}

生成一些虚假数据

temp_df <- data.frame(kt = runif(20,37.5,42.5))
temp_df$C <- kt_to_C(temp_df$kt)

temp_df
#>          kt         C
#> 1  41.51999  6.342394
#> 2  41.08151  9.325581
#> 3  39.43804 21.096904
#> 4  39.63741 19.616928
#> 5  38.59228 27.545405
#> 6  40.45097 13.728731
#> 7  39.99526 16.997412
#> 8  39.58650 19.993455
#> 9  38.65305 27.072686
#> 10 39.94612 17.354342
#> 11 41.59221  5.857097
#> 12 39.11671 23.514092
#> 13 37.59091 35.555587
#> 14 38.52162 28.097024
#> 15 38.41469 28.935554
#> 16 39.98483 17.073158
#> 17 40.28613 14.902581
#> 18 39.78529 18.528738
#> 19 38.52061 28.104892
#> 20 41.87998  3.939950

手动计算休息时间并反向转换

在这里,我们获取kt数据,然后使用函数将其转换为C,然后使用scales::extendedbreaks()找出如果原始数据位于C中,则中断将在哪里。

然后,我们将这些漂亮的数字反向转换为丑陋的非整数kt数字。这样ggplot知道了在坐标空间中放置中断的位置,并且我们准备好了漂亮的圆形标签。

breaks_in_C <- scales::extended_breaks()(kt_to_C(temp_df$kt))
breaks_in_C
#> [1]  0 10 20 30 40

breaks_in_kt <- C_to_kt(breaks_in_C)
breaks_in_kt
#> [1] 42.48407 40.98366 39.58561 38.27980 37.05739

造势

由于我们是手动处理转换的,所以我们只想使用dup_axis并谎称如何标记数字。

ggplot(temp_df, aes(kt, C)) +
  geom_point() +
  scale_x_continuous(
    sec.axis = dup_axis(
      breaks = breaks_in_kt,
      labels = breaks_in_C,
      name = "kt converted to C"
      )
    )