问题
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().
回答1:
I'm sure this can still be optimised but here is a start:
Define a function
quantile_breaksto return the breaks based onquantile(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_newwith breaks defined byquantile_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_*_quantileposition 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))
来源:https://stackoverflow.com/questions/52067545/make-a-new-scale-in-ggplot2