Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a power curve using ggplot2

Tags:

r

ggplot2

I want to use ggplot2 to visualize some data that follows a power curve. This has been asked before (Add exp/power trend line to a ggplot) but the answer didn't really help.

One trick is to use stat_function() to create a curve. However, I am unable to get stat_function() and my power curve to work with logarithmic scales.

I illustrate my problems.

Create some sample data and a base plot:

library(ggplot2)

x <- 1:100
pwr <- function(x)x^-2.5
dat <- data.frame(x, y = pwr(x))

p <- ggplot(dat, aes(x = x, y = y)) + 
  geom_point()

p + stat_function(fun = pwr)

enter image description here

Great, let's add some logaritmic scales using a coord_trans(). This works perfectly, except that my straight lines are no longer straight (exactly as the documentation tells me to expect).

p + stat_function(fun = pwr) + coord_trans(x = "log10", y = "log10")

enter image description here

So, try again with coord_x_log10() and coord_y_log10(), but this throws an error:

p + stat_function(fun = pwr) + scale_x_log10() + scale_y_log10()

Error in seq.default(min, max, by = by) : 
  'from' cannot be NA, NaN or infinite

This has most likely to do with the fact that I have to adjust my function to invert the effect of the scales, but I can't quite figure it out.

I can do it with only the logarithmix x-scale:

p + scale_x_log10() + stat_function(fun = function(x)pwr(10^x))

enter image description here

I have no idea how to convert the y-values if I add scale_y_log10().

I'm probably missing something fundamental. Is there an easy way to plot this curve?

like image 294
Andrie Avatar asked Jul 23 '15 17:07

Andrie


People also ask

How do I add a curve in ggplot2?

In order to create a normal curve, we create a ggplot base layer that has an x-axis range from -4 to 4 (or whatever range you want!), and assign the x-value aesthetic to this range ( aes(x = x) ). We then add the stat_function option and add dnorm to the function argument to make it a normal curve.

What is the power curve?

A power law graph in statistics. Curves used for crossfading between multiple audio signals, used in audio mixing and digital signal processing. The relationship between statistical power and effect size (or sometimes, between statistical power and sample size).

What is power curve in statistics?

Power curves are line plots that show how the change in variables, such as effect size and sample size, impact the power of the statistical test.


1 Answers

Putting my comments into an answer:

The main problem is a bug in stat_function. When used in conjunction with axis transformations it calculates y-values from the transformed and not from the original values. This has been fixed on github very recently.

However, this is not easy to see since the first error occurs when calculating the axis breaks since the bug produces Inf, zero and/or negative y-values. You need to set explicit axis limits to see that the actual problem is stat_function:

p + stat_function(fun = pwr) + 
  scale_x_log10() + scale_y_log10(limits = c(1e-5, 1))
#Warning message:
#Removed 100 rows containing missing values (geom_path).

resulting plot

It's even more obvious if you only transform the x-axis:

p + stat_function(fun = pwr) + 
  scale_x_log10() 

resulting plot

If you can't use the ggplot2 version from github you could use this:

p + geom_line(data = data.frame(x = seq(min(dat$x), max(dat$x), length.out = 100)),
              aes(y = pwr(x))) + 
  scale_x_log10() + scale_y_log10()

resulting plot

like image 52
Roland Avatar answered Oct 02 '22 18:10

Roland