Reputation: 2780
I have the following plot which plots quantile labels and breaks. This is currently done manually.
library(tidyverse)
mtcars %>%
as_tibble() %>%
ggplot(aes(y = mpg, x = hp, color = factor(cyl))) +
geom_point() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank()) +
scale_y_continuous(labels = as.numeric(quantile(mtcars$mpg)),
breaks = as.numeric(quantile(mtcars$mpg))) +
scale_x_continuous(labels = as.numeric(quantile(mtcars$hp)),
breaks = as.numeric(quantile(mtcars$hp)))
Created on 2018-08-28 by the reprex package (v0.2.0).
I would like to make a function which does this with any dataset. This was one attempt
scale_y_quantile <- function(y){
ggplot2::scale_y_continuous(labels = as.numeric(quantile(y)))
}
I then tried to use it as follows.
mtcars %>%
as_tibble() %>%
ggplot(aes(y = mpg, x = hp, color = factor(cyl))) +
geom_point() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank()) +
scale_y_quantile()
but I get the following error
Error in quantile(y) : object 'y' not found
The problem is I don't know how to access the data that is passed to aes()
.
Upvotes: 2
Views: 763
Reputation: 50668
I'm sure this can still be optimised but here is a start:
Define a function quantile_breaks
to return the breaks based on quantile(val)
# Define function for quantile breaks based on val
quantile_breaks <- function(val, prob) {
function(x) as.numeric(quantile(val, prob))
}
Define the transformation function with scales::trans_new
with breaks defined by quantile_breaks
.
quantile_trans <- function(val, prob) {
scales::trans_new(
name = "quantile",
transform = function(x) x,
inverse = function(x) x,
breaks = quantile_breaks(val, prob))
}
Define 2 new scale_*_quantile
position scales.
scale_x_quantile <- function(val, prob = seq(0, 1, 0.25), ...) {
scale_x_continuous(..., trans = quantile_trans(val, prob))
}
scale_y_quantile <- function(val, prob = seq(0, 1, 0.25), ...) {
scale_y_continuous(..., trans = quantile_trans(val, prob))
}
Let's test on mtcars
:
mtcars %>%
ggplot(aes(hp, mpg, colour = factor(cyl))) +
geom_point() +
scale_x_quantile(mtcars$hp) +
scale_y_quantile(mtcars$mpg)
You can also change the quantiles that you want to show, e.g. to show all 20% (rather than the default 25% quartiles) you can do
mtcars %>%
ggplot(aes(hp, mpg, colour = factor(cyl))) +
geom_point() +
scale_x_quantile(mtcars$hp, prob = seq(0, 1, 0.2)) +
scale_y_quantile(mtcars$mpg, prob = seq(0, 1, 0.2))
Upvotes: 2