I have some constraints for my plot:
x
axis should be reversed and logarithmicy
axis should be binned, but:- bins should be displayed in reverse order
- bins size should have logarithmic scale or something similar (
0-10
bin should be bigger than10-20
, and so on)
- For both
x
andy
,0
tick should appear on the axis (which we usually achieve withlimits=c(0, 0)
)
Here is some sample data:
set.seed(123)
dat <- data.frame(
a=sample(seq(0, 100), 1e4, replace=TRUE),
b=sample(1e6, 1e4),
t=sample(letters[seq(2)], 1e4, replace=TRUE)
)
I can achieve most constraints on x
axis, and some on y
:
dat |> ggplot(aes(y=a, x=b, colour=t))
geom_jitter()
scale_x_continuous(
trans=c("log10", "reverse"),
breaks=seq(0, 6) |> purrr::map(~c(2.5, 5, 10)*10^.x) |> unlist(),
expand=c(0, 0)
)
scale_y_binned(expand=c(0, 0), limits=c(0, 100))
ggthemes::theme_clean()
What's missing here is:
- 0 tick on
x
: usinglimits=c(0, 100)
withlog
scale produces an error. Usingscales::pseudo_log_trans
instead ofscales::log10
doesn't work. I tried to useggallin::pseudolog10_trans
that also keeps 0 and negatives, but couldn't figure how to mix it with another transformer. - log scale on
y
axis. The issue here is thatscale_y_binned
discretizes the data, and log transformation can only be applied to continuous data. - reversed
y
axis. The issue here is similar, because reversing an axis is not just a cosmetic operation forggplot2
likecoord_flip
would be; it is actually also a transformation that requires continuous data.
Cheers!
CodePudding user response:
Perhaps the easiest way to do this is to bin the scale manually and use a continuous rather than binned y scale with custom labels:
dat |>
within(abin <- cut(a, c(0, 10^seq(0, 2, 0.25)), include.lowest = TRUE,
right = FALSE,
labels = seq(-0.1072541, by = 0.25, len = 9)))|>
within(abin <- as.numeric(as.character(abin))) |>
ggplot(aes(y = abin, x = log10(b 1), colour = t))
geom_jitter()
scale_x_reverse(breaks = c(log10(c(5e5, 25e4, 1e5, 5e4, 25e3, 1e4, 5e3,
25e2, 1e3, 5e2, 250, 100, 50, 10) 1), 0.3),
limits = c(6, 0.3), expand = c(0, 0), name = "b",
labels = ~c(head(comma(10^(.x) - 1), -1), 0))
scale_y_reverse('a', breaks = seq(-0.25, 2, 0.25),
labels = ~ c(0, round(10^(tail(.x, -1)))))
ggthemes::theme_clean()