github.com/tidyverse/ggplot2/issues/2978

тировать

Кажется, что неправильное поведениеsec_axis в ggplot2 3.1.0 есть ошибка. Это было признано разработчиками, и они работают над исправлением (см.нить на GitHub).

Цель

У меня есть график, где ось Y колеблется от 0 до 1. Я хотел бы добавить вторичную ось Y, которая колеблется от 0 до 0,5 (так что ровно половина значений первичной оси Y). Пока проблем нет.

Что усложняет дело, так это то, что у меня есть пользовательское преобразование для оси Y, где часть оси Y отображается линейно, а остальные - логарифмически (см. Пример ниже). Для справки см.эта почта или жеэтот.

проблема

Это прекрасно работает при использовании ggplot2 версии 3.0.0, но больше не работает при использовании новейшей версии (3.1.0). Смотрите пример ниже. Я не знаю, как это исправить в новейшей версии.

Изизменений:

sec_axis () и dup_axis () теперь возвращают соответствующие разрывы для вторичной оси при применении к лог-преобразованным масштабам

Эта новая функциональность, кажется, ломается в случае смешанно-преобразованных Y-осей.

Воспроизводимый пример

Вот пример использования новейшей версии (3.1.0) ggplot2:

library(ggplot2)
library(scales)

#-------------------------------------------------------------------------------------------------------
# Custom y-axis
#-------------------------------------------------------------------------------------------------------

magnify_trans_log <- function(interval_low = 0.05, interval_high = 1,  reducer = 0.05, reducer2 = 8) {

  trans <- Vectorize(function(x, i_low = interval_low, i_high = interval_high, r = reducer, r2 = reducer2) {
    if(is.na(x) || (x >= i_low & x <= i_high)) {
      x
    } else if(x < i_low & !is.na(x)) {
      (log10(x / r)/r2 + i_low)
    } else {
      log10((x - i_high) / r + i_high)/r2
    }
  })

  inv <- Vectorize(function(x, i_low = interval_low, i_high = interval_high, r = reducer, r2 = reducer2) {
    if(is.na(x) || (x >= i_low & x <= i_high)) {
      x
    } else if(x < i_low & !is.na(x)) {
      10^(-(i_low - x)*r2)*r
    } else {
      i_high + 10^(x*r2)*r - i_high*r
    }
  })

  trans_new(name = 'customlog', transform = trans, inverse = inv, domain = c(1e-16, Inf))
}

#-------------------------------------------------------------------------------------------------------
# Create data
#-------------------------------------------------------------------------------------------------------

x <- seq(-1, 1, length.out = 1000)
y <- c(x[x<0] + 1, -x[x>0] + 1)

dat <- data.frame(
  x = x
  , y = y
)

#-------------------------------------------------------------------------------------------------------
# Plot using ggplot2
#-------------------------------------------------------------------------------------------------------

theme_set(theme_bw())
ggplot(dat, aes(x = x, y = y)) +
  geom_line(size = 1) +
  scale_y_continuous(
    , trans = magnify_trans_log(interval_low = 0.5, interval_high = 1, reducer = 0.5, reducer2 = 8)
    , breaks = c(0.001, 0.01, 0.1, 0.5, 0.6, 0.7, 0.8, 0.9, 1)
    , sec.axis = sec_axis(
      trans = ~.*(1/2)
      , breaks = c(0.001, 0.01, 0.1, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)
    )
  ) + theme(
    axis.text.y=element_text(colour = "black", size=15)
  )

Это дает следующий сюжет:

Маркировка вторичной оси Y является правильной для логарифмической части оси (ниже 0,5), но неверной для линейной части оси.

Если я устанавливаю ggplot2 3.0.0 с помощью

require(devtools)
install_version("ggplot2", version = "3.0.0", repos = "http://cran.us.r-project.org")

и запустить тот же код, что и выше, я получаю следующий график, который я хочу:

Вопросов

Есть ли способ исправить эту проблему в новейшей версии ggplot2 (3.1.0)? В идеале я хотел бы воздержаться от использования более старой версии ggplot2 (т.е. 3.0.0).Есть ли альтернативыsec_axis что будет работать в этом случае?

Ответы на вопрос(1)

Ваш ответ на вопрос