Escala personalizada del eje y y etiquetas secundarias del eje y en ggplot2 3.1.0
Edita
arece que el comportamiento defectuoso desec_axis
en ggplot2 3.1.0 es un error. Esto ha sido reconocido por los desarrolladores y están trabajando en una solución (verhil en GitHub).
Go
Tengo un gráfico en el que el eje y varía de 0 a 1. Me gustaría agregar un eje y secundario que varía de 0 a 0.5 (es decir, exactamente la mitad de los valores del eje y primario). Hasta ahora no hay problema.
Lo que complica el asunto es que tengo una transformación personalizada, para el eje y donde parte del eje y se muestra linealmente y el resto logarítmicamente (vea el código a continuación para ver un ejemplo). Para referencia, veaesta publicació oést.
Problem
Esto funcionó a la perfección con ggplot2 versión 3.0.0, pero ya no funciona con la versión más reciente (3.1.0). Ver ejemplo a continuación. No sé cómo solucionarlo en la versión más reciente.
Desde el changelog:
sec_axis () y dup_axis () ahora devuelven saltos apropiados para el eje secundario cuando se aplican a escalas transformadas de registro
Esta nueva funcionalidad parece romperse en el caso de los ejes y de transformación mixta.
Ejemplo reproducible
Aquí hay un ejemplo con la versión más reciente (3.1.0) de 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)
)
Esto produce la siguiente trama:
El etiquetado del eje y secundario es correcto para la parte logarítmica del eje (por debajo de 0.5) pero incorrecto para la parte lineal del eje.
Si instalo ggplot2 3.0.0 usando
require(devtools)
install_version("ggplot2", version = "3.0.0", repos = "http://cran.us.r-project.org")
y ejecuto el mismo código que el anterior, obtengo el siguiente gráfico, que es lo que quiero:
Preguntas
¿Hay alguna forma de solucionar este problema en la versión más reciente de ggplot2 (3.1.0)? Idealmente, me gustaría abstenerme de usar una versión anterior de ggplot2 (es decir, 3.0.0). ¿Hay alternativas asec_axis
que funcionaría en este caso?