Escala personalizada do eixo y e etiquetas secundárias do eixo y no ggplot2 3.1.0
Edita
Parece que o comportamento defeituoso desec_axis
no ggplot2 3.1.0 é um bug. Isso foi reconhecido pelos desenvolvedores e eles estão trabalhando em uma correção (consultefi no GitHub).
Objetiv
Tenho um gráfico em que o eixo y varia de 0 a 1. Gostaria de adicionar um eixo y secundário que varia de 0 a 0,5 (exatamente exatamente a metade dos valores do eixo y primário). Até agora não há problema.
O que complica a questão é que eu tenho uma transformação personalizada, para o eixo y em que parte do eixo y é exibida linearmente e o restante logaritmicamente (veja o código abaixo para obter um exemplo). Para referência, consulteesta postage ouest.
Problem
Isso funcionou perfeitamente com o ggplot2 versão 3.0.0, mas não funciona mais com a versão mais recente (3.1.0). Veja o exemplo abaixo. Não sei como corrigi-lo na versão mais recente.
De changelog:
sec_axis () e dup_axis () agora retornam quebras apropriadas para o eixo secundário quando aplicadas a registrar escalas transformadas
Esta nova funcionalidade parece quebrar no caso de eixos y transformados misto
Reproducible example
Aqui está um exemplo usando a versão mais recente (3.1.0) do 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)
)
This produz o seguinte gráfico:
A rotulagem do eixo y secundário é correta para a parte logarítmica do eixo (abaixo de 0,5), mas incorreta para a parte linear do eix
Se eu instalar o ggplot2 3.0.0 usando
require(devtools)
install_version("ggplot2", version = "3.0.0", repos = "http://cran.us.r-project.org")
e execute o mesmo código acima, recebo o seguinte gráfico, que é o que eu quero:
Questõe
Existe uma maneira de corrigir esse problema na versão mais recente do ggplot2 (3.1.0)? Idealmente, gostaria de não usar uma versão mais antiga do ggplot2 (isto é, 3.0.0).Existem alternativas parasec_axis
que funcionaria nesse caso?