# How can I plot this complex ggplot with multiple layers together?

I am trying to figure out how to create this complex ggplot using the dataset below:

type a b d points end start
A -0.32 -0.02 0 1.08 1.14 1.03
A -0.32 -0.02 2 0.39 0.45 0.32
A -0.32 -0.02 4 0.25 0.32 0.17
A -0.32 -0.02 6 0.06 0.07 0.04
B -0.19 -0.02 0 1.07 1.12 1.01
B -0.19 -0.02 2 0.55 0.58 0.52
B -0.19 -0.02 4 0.43 0.48 0.39
B -0.19 -0.02 6 0.17 0.20 0.15

The plot will be like this:

For each "type", there will be a curve, a set of 4 points, and a set of 4 segments.

1. Each curve will be a curve of the the function [exp(ax + bx^2)], where a and b are in the dataset. I think it can be achieved by:
``````geom_function(fun = function(x) exp(a*x + b*x^2))
``````
1. The points can be plotted from the variable "points" like this:
``````geom_point(aes(x = d, y = points))
``````
1. The segments can be plotted from the start and end variables like this:
``````geom_segment(aes(x = d, y = start, xend = d, yend = end))
``````
1. The y axis is in a log10 scale, which can be achieved by adding:
``````scale_y_log10()
``````

I think I know the individual details, but unfortunately I am not being able to plot it after I put everything together. The curves of the functions are not coming up, and I am getting errors. Can anyone please help?

Thank you so much!!!!

It's kind of ugly, but it works by having separate geom_functions for each subset of data by type, and passing named parameters a and b as arguments to the function f.

``````library("ggplot2")
library("dplyr")

dat <- data.frame(type = rep(LETTERS[1:2], each = 4),
a = rep(c(-0.32, -0.19), each = 4),
b = -0.02,
d = rep(seq(0,6,2), length = 8),
points = c(1.08, 0.39, 0.25, 0.06, 1.07, 0.55, 0.43, 0.17),
end = c(1.14, 0.45, 0.32, 0.07, 1.12, 0.58, 0.48, 0.20),
start = c(1.03, 0.32, 0.17, 0.04, 1.01, 0.52, 0.39, 0.15))

# Define function
f <- function(x, a, b) exp(a * x + b * x^2)

# Subset data for each geom_function
ggplot(dat, aes(x = d, y = points, color = type, group = type)) +
geom_point() +
geom_function(data = dat %>% filter(type == "A"), fun = f,
args = list(a = -0.32, b = -0.02)) +
geom_function(data = dat %>% filter(type == "B"), fun = f,
args = list(a = -0.19, b = -0.02)) +
geom_segment(aes(y = start, xend = d, yend = end)) +
scale_y_log10() +
scale_color_brewer(palette = 6, type = "qual", direction = -1) +
theme_bw()
``````

Created on 2021-01-08 by the reprex package (v0.3.0)

I do not see how to pass values from the data to the function, so I cheated and made another data frame.
(I see another answer just popped up that does use geom_function)

``````library(ggplot2)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#>     filter, lag
#> The following objects are masked from 'package:base':
#>
#>     intersect, setdiff, setequal, union

DF2 <- data.frame(type = rep(c("A", "B"), each = 601),
d = rep(seq(0, 6, 0.01), 2),
a = rep(c(-0.32, -0.19), each = 601),
b = rep(-0.02, 1202))
DF2 <- DF2 %>% mutate(Y = exp(a*d + b*d^2))

ggplot(DF, aes(x = d, y = points, color = type)) + geom_point() +
geom_segment(aes(x = d, y = start, xend = d, yend = end)) +
geom_line(mapping = aes(x = d, y = Y), data = DF2) +
scale_y_log10()
``````

Created on 2021-01-07 by the reprex package (v0.3.0)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.