94

What are the alternatives for drawing a simple curve for a function like

eq = function(x){x*x}

in R?

It sounds such an obvious question, but I could only find these related questions on stackoverflow, but they are all more specific

I hope I didn't write a duplicate question.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
sjdh
  • 3,907
  • 8
  • 25
  • 32
  • related https://stackoverflow.com/questions/70626264/one-function-per-facet/70636329#70636329 – tjebo May 28 '22 at 09:20

7 Answers7

116

I did some searching on the web, and this are some ways that I found:

The easiest way is using curve without predefined function

curve(x^2, from=1, to=50, , xlab="x", ylab="y")

enter image description here

You can also use curve when you have a predfined function

eq = function(x){x*x}
curve(eq, from=1, to=50, xlab="x", ylab="y")

enter image description here

If you want to use ggplot,

library("ggplot2")
eq = function(x){x*x}
ggplot(data.frame(x=c(1, 50)), aes(x=x)) + 
  stat_function(fun=eq)

enter image description here

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
sjdh
  • 3,907
  • 8
  • 25
  • 32
  • 4
    FYI the qplot example no longer works: To encourage users to use `ggplot()`, the `qplot()` function was crippled - so, for example, it no longer accepts the `fun` argument (as of v3?) – tim Jun 20 '19 at 08:18
52

You mean like this?

> eq = function(x){x*x}
> plot(eq(1:1000), type='l')

Plot of eq over range 1:1000

(Or whatever range of values is relevant to your function)

Eric
  • 1,691
  • 16
  • 24
37

plot has a plot.function method

plot(eq, 1, 1000)

Or

curve(eq, 1, 1000)
GSee
  • 48,880
  • 13
  • 125
  • 145
  • 1
    Interesting, I did not see your example `plot(eq, 1, 1000)` anywhere else. I also saw the `curve(eq, 1, 100)` example. Is there a difference? – sjdh Sep 29 '14 at 01:33
  • 4
    @sjdh Not much. `plot.function` actually calls `curve` after doing some argument checking. Also, `curve` can take an expression as input, but `plot` needs a function as input to dispatch to `plot.function` – GSee Sep 29 '14 at 01:41
2

Here is a lattice version:

library(lattice)
eq<-function(x) {x*x}
X<-1:1000
xyplot(eq(X)~X,type="l")

Lattice output

John Paul
  • 12,196
  • 6
  • 55
  • 75
2

Lattice solution with additional settings which I needed:

library(lattice)
distribution<-function(x) {2^(-x*2)}
X<-seq(0,10,0.00001)
xyplot(distribution(X)~X,type="l", col = rgb(red = 255, green = 90, blue = 0, maxColorValue = 255), cex.lab = 3.5, cex.axis = 3.5, lwd=2 )
  1. If you need your range of values for x plotted in increments different from 1, e.g. 0.00001 you can use:

X<-seq(0,10,0.00001)

  1. You can change the colour of your line by defining a rgb value:

col = rgb(red = 255, green = 90, blue = 0, maxColorValue = 255)

  1. You can change the width of the plotted line by setting:

lwd = 2

  1. You can change the size of the labels by scaling them:

cex.lab = 3.5, cex.axis = 3.5

Example plot

mrk
  • 8,059
  • 3
  • 56
  • 78
2

As sjdh also mentioned, ggplot2 comes to the rescue. A more intuitive way without making a dummy data set is to use xlim:

library(ggplot2)
eq <- function(x){sin(x)}
base <- ggplot() + xlim(0, 30)
base + geom_function(fun=eq)

Additionally, for a smoother graph we can set the number of points over which the graph is interpolated using n:

base + geom_function(fun=eq, n=10000)
0

Function containing parameters

I had a function (emax()) involving 3 parameters (a, b & h) whose line I wanted to plot:

emax = function(x, a, b, h){
  (a * x^h)/(b + x^h)
}
curve(emax, from = 1, to = 40, n=40 a = 1, b = 2, h = 3)

which errored with Error in emax(x) : argument "a" is missing, with no default error.

This is fixed by putting the named arguments within the function using this syntax:

curve(emax(x, a = 1, b = 2, h = 3), from = 1, to = 40, n = 40)

which is contrary to the documentation which writes curve(expr, from, to, n, ...) rather than curve(expr(x,...), from, to, n).

  • It's not contrary to the documentation. expr is just the name of this argument and not a function by itself. It is defined as _The name of a function, or a call or an expression written as a function of x which will evaluate to an object of the same length as x._ this means if you have more than just the name of the function it will evaluate the entire argument as an expression. – tjebo May 25 '22 at 13:13
  • Hi @tjebo I agree that the expr argument is correct, but how they've written the "..." in the syntax suggests curve(expr=fun,...) works too which is not true. curve(expr=fun(x,...)) seems to be the only way. – Timothy M Pollington May 28 '22 at 05:26
  • no. the ... are for the "function method of plot" (this is just the R way to allow more flexibility in programming) - see `?curve`. Here, the documentation even specifies `For the "function" method of plot, ... can include any of the other arguments of curve, except expr.` - this makes it fairly clear that it does not relate to the expression. I think this documentation is pretty clear in this case. – tjebo May 28 '22 at 09:06
  • P.S. I assume your confusion arises from other functions where you can add additional arguments to a function using `...` (e.g., lapply). However, this is just the way those are designed, and `...` takes different roles in each case, depending on the underlying function design. Also, methods are generally a special case of functions and sometimes can even contain `...` that have no meaning at all. I would therefore generally avoid blindly using `...` if you don't exactly know what it does for that function. – tjebo May 28 '22 at 09:15