# How to plot mathematical functions with ggplot2 - Tutorial #1

geom_function() and as_function() offer an elegant and powerful solution to plot mathematical functions with ggplot2

Dear R enthusiasts,

Welcome to the first Tutorial! Tutorials are a new format where I will share tips to get the most out of R, and to improve coding skills.

In this first Tutorial, I would like to share an elegant solution to plot mathematical functions with `ggplot2`

.

## A simple function

Let's begin with a simple function: a logarithm.

$$ f \left( x \right) = \ln x $$

We want to produce the following plot.

Often, when I read tutorials to plot functions with `ggplot2`

, they do the following:

- Generate a data frame from the function
- Plot the data frame

I find this method cumbersome, especially if we want to edit the function as we need to regenerate the data frame. More steps mean a higher chance to introduce bugs and errors. It is also not particularly elegant. What I want is to plot the function by specifying it symbolically, i.e., without generating an intermediary data frame. This is possible thanks to `geom_function()`

.

`geom_function()`

takes at least one argument: `fun`

. To plot a logarithm, we can use the built-in `log()`

function.

```
geom_function(
fun = log
)
```

The following code produces Figure 1:

```
ggplot() +
geom_function(
fun = log
) +
scale_x_continuous(
limits = c(0, 1000)
) +
scale_y_continuous(
limits = c(0, 10)
) +
labs(
x = "x",
y = "y"
)
```

I use `scale_continuous()`

and `limits`

to specify the limits of the axes.

So far, so good. But what if we want to plot a more complicated function? What if we want to have a lot more control over the function we plot?

## A more complicated function

Let's say we want to plot a logistic function.

The general equation of a logistic function is the following:

$$ f \left( x \right) = \frac{L}{1 + e^{- k \left( x + x_0\right)}} $$

- \( L \) is the supremum, i.e., the maximum value the curve reaches on the plot
- \( k \) is the growth rate, i.e., the steepness of the curve
- \( x_0 \) is the midpoint

Like `log()`

, R has a built-in function to work with logistic functions. But let's say we want to specify all parameters ourselves. Or we want to use a modified form of a sigmoid function. Used in conjunction with `geom_function()`

, `as_function()`

makes all this possible.

With `as_function()`

, we can manually specify the mathematical function we want to plot. With `as_function()`

, we have complete control.

The following code produces Figure 2, with \( L = 1 \), \( k = 1.5 \) and \( x_0 = 6 \).

```
library(rlang)
supremum <- 1
growth_rate <- 1.5
midpoint <- 6
ggplot() +
geom_function(
fun = as_function(
~ (supremum)
/
(1 + exp(-1 * growth_rate * (.x - midpoint)))
)
) +
scale_x_continuous(
limits = c(0, midpoint * 2)
) +
scale_y_continuous(
limits = c(0, 1)
) +
labs(
x = "x",
y = "y"
)
```

Let's break down the code.

First, we need to load `rlang`

to use `as_function()`

. If you use the Tidyverse, `rlang`

should already be installed. If you do not use the Tidyverse, you probably need to install it.

Second, I defined three variables that store the values of the parameters. I could have hard coded the values directly in `as_function()`

. But defining variables makes the code easier to read. It also makes it easier to change the value of the parameters. A clearer and simpler code is a code that is less prone to bugs and errors.

Third, the rest. It looks a lot like the code we wrote to plot the logarithm, but with some differences.

`fun`

now calls `as_function()`

. The syntax of `as_function()`

is the following:

`as_function(~ .x)`

`~`

tells `as_function()`

what is on the right-hand side of the equation. `.x`

is basically a computational representation of the mathematical \( x \).

Fun fact: if you use `as_function(~ .x)`

, it plots a linear function (try it!).

One important thing to note: inside `as_function()`

, you need to explicitly write `*`

everywhere there is a multiplication. R, or at least `as_function()`

, is not able to infer multiplication. Without writing `*`

, R interprets `var()`

as a call to a function named `var`

. With `var * ()`

, R knows that we want to multiply the numerical value stored in the variable named `var`

with what is inside the parentheses.

## Wrapping up

So here it is! You know how to plot any arbitrary function with `ggplot2`

.

If you enjoyed this Tutorial, please share it on social media and in your network. To not miss my future Tutorials on R and coding, you can also subscribe to the newsletter below.

Olivier