Search code examples
rggplot2

Draw multiple function lines with parameters provided by a dataframe


I am trying to generate function lines programmatically by supplying a dataframe of coefficients. In the example below, the params dataframe represents a set of intercepts and slopes in each row. Each of these should represent a line in ggplot. Eventually I want to scale up the number of lines and draw more complicated curves.

Can ggplot geom_function() take this in as an aesthetic mapping? The best I've gotten so far is not standard and also does not draw separate lines.

library(tibble)
library(ggplot2)

params <- tribble(
  ~int, ~slope,
  0, 1, # a 45 deg line crossing (0, 0)
  1, 1, # a 45 deg line crossing (0, 1)
  2, -1 # a -45 degr line crossing (0, 2)
)

# Trying to get three separate lines, does not create separate lines
ggplot() +
  xlim(0, 1) +
  geom_function(fun = function(x) {params$int + params$slope*x})
#> Warning in params$slope * x: longer object length is not a multiple of shorter
#> object length
#> Warning in params$int + params$slope * x: longer object length is not a
#> multiple of shorter object length

This is what I want to create, but without typing out each layer

ggplot() +
  xlim(0, 1) +
  geom_function(fun = function(x) 0 + 1*x) +
  geom_function(fun = function(x) 1 + 1*x) +
  geom_function(fun = function(x) 2 - 1*x)

Created on 2024-10-17 with reprex v2.1.0


Solution

  • One option to achieve your desired result would be to use e.g. purrr::pmap to loop over the rows of params and create the geom_function layers:

    library(purrr)
    library(ggplot2)
    
    ggplot() +
      xlim(0, 1) +
      purrr::pmap(
        params,
        function(int, slope) geom_function(fun = function(x) int + slope * x)
      )