How to Plot a Quadratic Function in R

For the following quadratic function:

$$f(x) = x^2 + 2x – 20$$

Here’s the plot that we want to produce:

Coding the function f(x) in R

A quadratic function is a function of the form: $$ax^2 + bx + c$$, where $$a \neq 0$$.

So for $$f(x) = x^2 + 2x – 20$$:

• a = 1
• b = 2
• c = -20

In R, we write:

a = 1
b = 2
c = -20

f = function(x) {
a*x^2 + b*x + c
}

Plotting the quadratic function f(x)

First, we have to choose a domain over which we want to plot f(x).

Let’s try -10 ≤ x ≤ 10:

# domain over which we want to plot f(x)
x = -10:10

# plot f(x)
plot(x, f(x), type = 'l') # type = 'l' plots a line instead of points

# plot the x and y axes
abline(h = 0)
abline(v = 0)

Output:

Finding the vertex

The vertex V of a quadratic equation, in this case the lowest point on the graph of f(x), is: $$V(\frac{-b}{2a}, f(\frac{-b}{2a}))$$

find.vertex = function(a, b, c) {
x_vertex = -b/(2 * a)
y_vertex = f(x_vertex)
c(x_vertex, y_vertex)
}

V = find.vertex(a, b, c)

# print(V) outputs: -1 -21
# so the vertex is the point V(-1, -21)

Adding the vertex to the plot:

# add the vertex to the plot
points(x = V[1], y = V[2],
pch = 18, cex = 2) # pch controls the form of the point and cex controls its size

# add a label next to the point
text(x = V[1], y = V[2],
labels = "Vertex", pos = 3) # pos = 3 places the text above the point

Output:

Finding the x-intercepts of f(x)

The x-intercepts are the solutions of the quadratic equation f(x) = 0; they can be found by using the quadratic formula:

$$x = \frac{-b \pm \sqrt{b^2 – 4ac}}{2a}$$

The quantity $$b^2 – 4ac$$ is called the discriminant:

• if the discriminant is positive, then f(x) has 2 solutions (i.e. 2 x-intercepts).
• if the discriminant is zero, then f(x) has 1 solution (i.e. 1 x-intercept).
• if the discriminant is negative, then f(x) has no real solutions (i.e. does not intersect the x-axis).
# find the x-intercepts of f(x)
find.roots = function(a, b, c) {
discriminant = b^2 - 4 * a * c
if (discriminant > 0) {
c((-b - sqrt(discriminant))/(2 * a), (-b + sqrt(discriminant))/(2 * a))
}
else if (discriminant == 0) {
-b / (2 * a)
}
else {
NaN
}
}

solutions = find.roots(a, b, c)

# print(solutions) outputs: -5.582576  3.582576
# so the x-intercepts are the points: (-5.582576, 0) and (3.582576, 0)

Adding the x-intercepts to the plot:

# add the x-intercepts to the plot
points(x = solutions, y = rep(0, length(solutions)), # x and y coordinates of the x-intercepts
pch = 18, cex = 2, col = 'red')

text(x = solutions, y = rep(0, length(solutions)),
labels = rep("x-intercept", length(solutions)),
pos = 3, col = 'red')

Output:

Here’s the full code used in this tutorial

a = 1
b = 2
c = -20

f = function(x) {
a*x^2 + b*x + c
}

# simple plot of f(x)
x = -10:10
plot(x, f(x), type = 'l')

# plot the x and y axes
abline(h = 0)
abline(v = 0)

# find the vertex
find.vertex = function(a, b, c) {
x_vertex = -b/(2 * a)
y_vertex = f(x_vertex)
c(x_vertex, y_vertex)
}

V = find.vertex(a, b, c)

# add the vertex to the plot
points(x = V[1], y = V[2],
pch = 18, cex = 2)

text(x = V[1], y = V[2],
labels = "Vertex", pos = 3)

# find the x-intercepts of f(x)
find.roots = function(a, b, c) {
discriminant = b^2 - 4 * a * c
if (discriminant > 0) {
c((-b - sqrt(discriminant))/(2 * a), (-b + sqrt(discriminant))/(2 * a))
}
else if (discriminant == 0) {
-b / (2 * a)
}
else {
NaN
}
}

solutions = find.roots(a, b, c)

# add the x-intercepts to the plot
points(x = solutions, y = rep(0, length(solutions)),
pch = 18, cex = 2, col = 'red')

text(x = solutions, y = rep(0, length(solutions)),
labels = rep("x-intercept", length(solutions)),
pos = 3, col = 'red')

I encourage you to play with this code, for example, you can change the function f(x) to get a negative discriminant, by using:

• a = 1
• b = 2
• c = 2

What does the plot look like in this case?