I have a scatter plot where the y-axis scaling changes at a certain point to plot data with some extreme values. I'm trying to add some sort of visual cue on the y-axis that indicates that the scaling changes at the point.
Here's an example of a plot
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))
I want to add some marker to "tick 30" on y axis for scale change.
I was thinking of adding a double tick on the axis, but there is no linetype
that looks like a double line. The product should look something like this. I'm aware of transforms like scale_y_log10
, but I'd rather work with custom scaling that dynamically changes with the data.
EDIT: per @Tjebo's suggestion, I used annotate
to add a "=" to the y axis breakpoint:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
mybreaks <- c(0, 10, 20, 30, 50, 70, 90, 110)
tick_linetype <- rep("solid", length(mybreaks))
tick_linetype[4] <- "blank"
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 3) +
scale_y_continuous(trans = transformation, breaks = mybreaks) +
theme(axis.ticks.y = element_line(linetype = tick_linetype)) +
coord_cartesian(clip = 'off')
I was thinking of adding a double tick on the axis, but there is no linetype that looks like a double line.
You can use any character as point shape. Also an equal sign, or back slash, etc.
For example:
library(scales)
library(ggplot2)
set.seed(104)
ggdata <- data.frame('x' = rep('a',100),
'y' = c(runif(90, 0, 20), runif(10, 90, 100)))
transformation <- trans_new(
"my_transformation",
transform = function(x) ifelse(x <= 30, x / 5, (x - 30) / 20 + 30 / 5),
inverse = function(x) ifelse(x <= 30 / 5, x * 5, (x - 30 / 5) * 20 + 30)
)
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "point", shape = "=", x = -Inf, y = 30, size = 8, color = 'red') +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110))+
coord_cartesian(clip = 'off')
I removed the clipping, but you can also leave it. The color was just chosen for highlighting.
Or, even better, use text annotation. You can then also change the angle - kind of nice.
ggplot(data = ggdata) +
geom_jitter(aes(x = x, y = y)) +
annotate(geom = "text", label = "=", x = -Inf, y = 30, size = 8, color = "red", angle = 45) +
scale_y_continuous(trans = transformation, breaks = c(0, 10, 20, 30, 50, 70, 90, 110)) +
coord_cartesian(clip = "off")
Created on 2020-04-21 by the reprex package (v0.3.0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With