95

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.

1

7 Answers 7

119

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

Sign up to request clarification or add additional context in comments.

1 Comment

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?)
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)

Comments

37

plot has a plot.function method

plot(eq, 1, 1000)

Or

curve(eq, 1, 1000)

2 Comments

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 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
2

Here is a lattice version:

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

Lattice output

Comments

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

Comments

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)

Comments

1

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).

4 Comments

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.
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.
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.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.