Reputation: 40231
I would like to transform a ggplot graph such that 0.9, 0.99, 0.999, 0.9999, etc. are at equal distances from each other on the x axis.
In the following example, these breaks are bunched up on the right side. I would like the higher values to be stretched on the x axis. This would be the opposite of a log scale which condenses larger values.
p <- seq(0.001, 1, 0.001)
d <- seq(1, 1000)
percentile <- data.frame(p, d)
g1 <- ggplot(percentile, aes(p, d))
g1 <- g1 + geom_point()
g1 <- g1 + scale_x_continuous(breaks=c(0,0.9,.9,.99,.999,.9999))
g1
I think I need to scale the x axis by an expression like log(1/(1-p)), but I'm not sure how to scale by an arbitrary expression.
Upvotes: 2
Views: 844
Reputation: 40231
Using Mike Wise's answer below as a template, I was able to get this working. Here is the code I came up with:
transform <- function(x){
log(1/(1-x))
}
p <- transform(seq(0.001, 1, 0.001))
d <- seq(1, 1000)
xin <- transform(c(0.5,0.9,0.99,0.999))
lxin <- as.character(c(0.5,0.9,0.99,0.999))
percentile <- data.frame(p, d)
g1 <- ggplot(percentile, aes(p, d))
g1 <- g1 + geom_point()
g1 <- g1 + scale_x_continuous(breaks=xin, labels=lxin)
g1
Upvotes: 2
Reputation: 22807
Been thinking about it. Think this is what you want:
This code:
#Generate our Data
p <- seq(0.001, 1-0.001, 0.001)
sin_p <- sin(p*pi)
xin <- c( 0.5,0.9,0.99,0.999 )
lxin <- as.character(xin)
pctdf <- data.frame(p,sinp)
# Plot it in raw form
g1 <- ggplot(pctdf, aes(p, sin_p)) +
geom_point() +
geom_vline(xintercept=xin,color="red") +
labs(title="Raw")+
scale_x_continuous(breaks=xin,labels=xin) +
theme(axis.text.x = element_text(size = rel(1.0),angle=-90,hjust=0))
g1
yields:
And then we transform it (using the inverse logistic function (in base 10)):
# Now transform it
transform <- function(x){
-log10(((1/x) - 1))
}
xin <- transform(xin)
pctdf$p <- transform(pctdf$p)
# Plot it
g2 <- ggplot(pctdf, aes(p, sin_p)) +
geom_point() +
geom_vline(xintercept=xin,color="red") +
labs(title="Transformed")+
scale_x_continuous(breaks=xin,labels=lxin) +
theme(axis.text.x = element_text(size = rel(1.0),angle=-90,hjust=0))
g2
yielding:
Upvotes: 2
Reputation: 4907
Remove scale_x_continuous
and use
g1 + scale_x_log10(breaks=c(0,0.9,.9,.99,.999,.9999))
But you're going to have problems with the breaks == 0
since log10(0) = -Inf
For example:
p <- seq(0.001, 1, 0.001)
d <- seq(1, 1000)
percentile <- data.frame(p, d)
g1 <- ggplot(percentile, aes(p, d))
g1 <- g1 + geom_point()
g1 <- g1 + scale_x_log10(breaks=c(0.9,.9,.99,.999,.9999)) + xlim(c(.9,1))
Upvotes: 1