This vignette contains example annotated use-cases of the
looplot package. We introduce several of the available
options and briefly explain their effect. For an in-depth introduction
into the goals of this package and the general workflow, see the
vignette “looplot: A package for creating nested
loop plots”.
For many options to further customize the plots, please refer to the documentation of the underlying ggplot2 package.
This example uses the same artifically created dataset as the other vignette.
set.seed(14)
params = list(
samplesize = c(100, 200, 500),
param1 = c(1, 2),
param2 = c(1, 2, 3),
param3 = c(1, 2, 3, 4)
)
design = expand.grid(params)
# add some "results"
design %<>%
mutate(method1 = rnorm(n = n(),
mean = param1 * (param2 * param3 + 1000 / samplesize),
sd = 2),
method2 = rnorm(n = n(),
mean = param1 * (param2 + param3 + 2000 / samplesize),
sd = 2),
method3 = rnorm(n = n(),
mean = param1 * (param2 + param3 + 3000 / samplesize),
sd = 2))
knitr::kable(head(design, n = 10))| samplesize | param1 | param2 | param3 | method1 | method2 | method3 |
|---|---|---|---|---|---|---|
| 100 | 1 | 1 | 1 | 9.676300 | 22.984443 | 33.793024 |
| 200 | 1 | 1 | 1 | 9.437908 | 12.710978 | 17.636887 |
| 500 | 1 | 1 | 1 | 7.243334 | 6.225153 | 6.659465 |
| 100 | 2 | 1 | 1 | 24.994307 | 46.274059 | 62.983457 |
| 200 | 2 | 1 | 1 | 11.927719 | 22.866110 | 36.833710 |
| 500 | 2 | 1 | 1 | 8.463890 | 13.105232 | 14.311812 |
| 100 | 1 | 2 | 1 | 11.870238 | 22.974996 | 35.277654 |
| 200 | 1 | 2 | 1 | 9.137987 | 11.857579 | 18.394986 |
| 500 | 1 | 2 | 1 | 3.246069 | 5.631446 | 9.701592 |
| 100 | 2 | 2 | 1 | 26.086366 | 48.338618 | 65.184775 |
x, grid_rows, grid_cols,
steps).steps_y_base,
steps_y_height).x_name, y_name).spu_x_shift).colors).steps_values_annotate,
steps_annotation_size).hline_intercept).y_expand_add).add_custom_theme).p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)grid_rows argument, move other parameters into
steps.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = c("param2", "param3"),
grid_rows = "param1",
steps_y_base = -10, steps_y_height = 3, steps_y_shift = 3,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)grid_cols argument, move other parameters into
steps.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = c("param2", "param3"),
grid_cols = "param1",
steps_y_base = -5, steps_y_height = 1, steps_y_shift = 3,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)steps.draw to c("add_points", "add_steps") to
display results via points and steps, then set connect_spus
to TRUE.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = c("param1", "param2", "param3"),
draw = "add_steps",
steps_y_base = -5, steps_y_height = 1, steps_y_shift = 3,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 200,
connect_spus = TRUE,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 5)
)
))
print(p)So far the x-axis has been treated as numeric scale with spacing of the breaks according to the values of the design parameter which defines the x-axis. If the design parameter is actually a factor, or converted to be one, then the spacing on the x-axis is equal.
nested_loop_plot now uses a factor
as x-axis (converted via dplyr::mutate).spu_x_shift. Note that the gap between any two datapoints
on the x-axis is now exactly one unit.x_factor_design = design %>%
mutate(samplesize = as.factor(samplesize))
p = nested_loop_plot(resdf = x_factor_design,
x = "samplesize", steps = c("param1", "param2", "param3"),
draw = "add_steps",
steps_y_base = -5, steps_y_height = 1, steps_y_shift = 3,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 1,
connect_spus = TRUE,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 5)
)
))
print(p)Data can be re-labelled to streamline the display of parameters on the x-axis or give meaningful names to panels.
replace_labels.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
replace_labels = list(
samplesize = c("100$" = "100",
"200$" = "",
"500$" = "500"),
param2 = c("1" = "low",
"2" = "mid",
"3" = "high"),
param3 = c("1" = "very low", # partial replacement
"4" = "very high")
),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)Elements of the plot can be customized. Note that these parameters
(sizes, line_linetypes,
point_shapes, colors) all at least take either
a single numeric value, a vector of numeric values or a named vector of
numeric values specifying which method should have which value.
line_linetypes).point_shapes).sizes and setting point_size
to NULL due to the underlying implementation in the
ggplot2 package.line_size).add_annotation).p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
line_linetypes = c(1, 2, 3),
point_shapes = c("method1" = 2, "method2" = 3, "method3" = 1),
sizes = c(1, 1.5, 2), point_size = NULL,
line_size = 1,
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
# add ribbon via an annotation
add_annotation = list(
geom = "rect",
xmin = -Inf, xmax = Inf, # stretch whole x-axis
ymin = 0, ymax = 10, alpha = 0.1, fill = "black"
),
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)In a partial design, not every possible combination of values for the design parameters is present in the results from the experiment. In our example, we simply remove parts corresponding to two design parameters from the data.frame containing the data.
design_type can be set to “partial” to remove the
parameter step functions for the missing design parts. If left at
default (“full”), then the missing parts are added.partial_design = design %>%
filter(!(param2 == 2 & param3 %in% c(3, 4)))
p = nested_loop_plot(resdf = partial_design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
design_type = "partial",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)An alternative parameter to use in case of missing data due to partial designs determines how “holes” in the data are handled.
na_rm argument can be set to TRUE (default) to
ignore missing data when connecting result values. (Note that in the
middle panel no data is available for samplesize 200.)partial_design = design %>%
filter(!(param2 == 2 & samplesize == 200))
p = nested_loop_plot(resdf = partial_design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
na_rm = TRUE,
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)na_rm argument can be set to FALSE make it clear
that data is missing by not connecting the result values accross missing
data.partial_design = design %>%
filter(!(param2 == 2 & samplesize == 200))
p = nested_loop_plot(resdf = partial_design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
na_rm = FALSE,
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)Axes of the facets can have different scales. However, currently it
is only possible to have different y- and x-scales for each row and
column, respectively. This is made possible thanks to the facet_grid_sc
extension of ggplot2. Because of this, it is also possible
to adjust the axes individually (i.e. per row / per column).
grid_scales argument to “free_y” to free the
y-scale. The x-axis remains the same, even if set to be free.y_expand_add (entries of this list are named by the values
of the design parameter which defines the grid_rows).p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
grid_scales = "free_y",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = list(
"2" = c(10, NULL)
),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)The package supports adding steps for meta-information. These do not influence the layout of the plot.
steps_add (note that
additional column added to the design data.frame).meta_design = design %>%
mutate(Difficulty = if_else(param3 == 4, "Hard", "Easy"))
p = nested_loop_plot(resdf = meta_design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_add = "Difficulty",
steps_y_base = -10, steps_y_height = 5, steps_y_shift = 10,
x_name = "Samplesize", y_name = "Error",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)Further geometries can be added to the plot via post-processing. For
several simple geometries convenience wrapper functions are implented in
this package (all starting with add_) so that only the
parameters of the geometry need to be passed to post-processing.
However, arbitrary geometries are supported via the
add_geom_at_position wrapper function, which allows the
user to directly pass any geometry object.
Here we add text to annotate the results, but also additional points or lines could be drawn in the same way. By passing a new data.frame, even new data can be added in this step. Examples for such advanced usage are shown below for adding panel specific geometries or using this package in a modularl fashion.
add_text).add_geom_at_position (note that
inherit.aes is set to FALSE so that the rest of the plot
does not impact the ribbons).p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
draw = "add_lines",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
add_text = list(
decimals = 1, size = 2, vjust = 0, hjust = 0
),
add_geom_at_position = list(
g = geom_rect(
data = NULL,
xmin = -Inf, xmax = Inf,
ymin = 0, ymax = 10,
alpha = 0.005, fill = "blue",
linetype = "blank",
inherit.aes = FALSE
),
position = "bottom" # place below other geometries
),
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)The normal axis transformations of ggplot2 can not be
used in general as the steps added for simulation parameters are also on
the same y-scale as the simulation results. E.g. if a logarithmic scale
is to be used for results, but the parameter steps have negative
y-coordinates, then the approach using ggplot2 will not
work.
Hence, the functionality is implemented by transformation of the
data. This can be done by the user outside the looplot
package or passed to the functions implemented in this package using the
trans argument.
Note that this is a transformation of the data. Hence, the y-axis
labels are also on the transformed scale. If that is not wanted, the
user can easily reverse this transformation for the labels by passing a
function to the y_labels argument. See documentation.
Another possibility is to simply rename the y-axis as e.g. ‘log2 of
results’ to indicate the scaling.
A further consequence is that all additions to the plot such as lines or parameter steps are now also on the transformed scale and may require re-adjustment.
trans.ylim, y_breaks and
y_labels arguments.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -0.5, steps_y_height = 0.5,
x_name = "Samplesize", y_name = "Error",
trans = log2,
ylim = c(0, 6),
y_breaks = 0:6,
y_labels = function(x) ifelse(x > 0, 2^x, 0),
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(3, 0.5),
post_processing = list(
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)We expand the design parameters by another layer of parameters. Overall the setup contains 600 unique parameter combinations.
set.seed(82356)
params = list(
samplesize = c(10, 50, 100, 200, 500),
param1 = c(1, 2),
param2 = c(1, 2, 3),
param3 = c(1, 2, 3, 4),
param4 = c(1, 2, 3, 4, 5)
)
design = expand.grid(params)
design %<>%
mutate(method1 = rnorm(n = n(),
mean = param1 * (param2 * param3 * param4 + 50 / samplesize),
sd = 2),
method2 = rnorm(n = n(),
mean = param1 * (param2 + param3 + param4 + 100 / samplesize),
sd = 2),
method3 = rnorm(n = n(),
mean = param1 * (param2 + param3 * param4 + 150 / samplesize),
sd = 2))
knitr::kable(head(design, n = 10))| samplesize | param1 | param2 | param3 | param4 | method1 | method2 | method3 |
|---|---|---|---|---|---|---|---|
| 10 | 1 | 1 | 1 | 1 | 4.4014514 | 16.411023 | 17.6199471 |
| 50 | 1 | 1 | 1 | 1 | 0.2362822 | 5.111114 | 6.6717133 |
| 100 | 1 | 1 | 1 | 1 | -2.5726311 | 2.753999 | 3.5378787 |
| 200 | 1 | 1 | 1 | 1 | 3.1213877 | 4.181095 | 0.1538609 |
| 500 | 1 | 1 | 1 | 1 | 2.6420683 | 5.497084 | 3.5507153 |
| 10 | 2 | 1 | 1 | 1 | 11.8447059 | 27.180114 | 35.4790589 |
| 50 | 2 | 1 | 1 | 1 | 3.6258356 | 10.845427 | 9.3207731 |
| 100 | 2 | 1 | 1 | 1 | 5.0769028 | 8.175888 | 9.4723016 |
| 200 | 2 | 1 | 1 | 1 | 3.8329818 | 7.640888 | 5.8487234 |
| 500 | 2 | 1 | 1 | 1 | 2.1029934 | 5.666710 | 5.9034683 |
x_labels). Add values on x-axis to name of axis.p = nested_loop_plot(resdf = design,
x = "samplesize", steps = c("param3", "param4"),
grid_rows = "param1", grid_cols = "param2",
steps_y_base = -10, steps_y_height = 2.5, steps_y_shift = 5,
x_name = "Samplesize (100, 200, 500)", y_name = "Error",
draw = "add_lines",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
x_labels = NULL,
post_processing = list(
add_custom_theme = list(legend.position = "top")
))
print(p)add_custom_theme).p = nested_loop_plot(resdf = design,
x = "samplesize", steps = c("param1", "param2", "param3", "param4"),
steps_y_base = -10, steps_y_height = 2.5, steps_y_shift = 7.5,
x_name = "Samplesize (100, 200, 500)", y_name = "Error",
draw = "add_lines",
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
x_labels = NULL,
post_processing = list(
add_custom_theme = list(
legend.position = "top",
panel.grid.major = element_line(
color = "grey95", size = 0.1
)
)
))
print(p)Annotations may depend on the design factors of the simulation study.
For example, variability or highlighted regions in the plot may be
indicated by ribbons, which in turn may depend on the column variable of
the facets. To add such panel parameter specific decorations we can use
the following
approach. We demonstrate them by recreating panel
specific ribbons. Data is created in the same way as in the first example.
dplyr::case_when.pass_through argument of the
nested_loop_plot function to pass the augmented columns
untouched to post-processing. They leave the rest of the plot completely
unaffected.add_geom_at_position function in
post-processing and make sure to set inherit.aes to FALSE
(otherwise the legend may be affected by the new geometries).# augment design data
augmented_design = design %>% mutate(
ymin = case_when(param2 == 1 ~ 0,
param2 == 2 ~ 10),
ymax = case_when(param2 == 1 ~ 10,
param2 == 2 ~ 20),
note = case_when(param2 == 3 & param1 == 1 ~ "This is a special case.")
)
p = nested_loop_plot(resdf = augmented_design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
# pass data to post-processing
pass_through = c("ymin", "ymax", "note"),
steps_y_base = -10, steps_y_height = 5,
x_name = "Samplesize", y_name = "Error",
draw = c("add_points", "add_lines"),
spu_x_shift = 75,
colors = scales::brewer_pal(palette = "Dark2"),
steps_values_annotate = TRUE, steps_annotation_size = 2.5,
hline_intercept = 0,
y_expand_add = c(10, NULL),
post_processing = list(
# add geometries that use the passed through data
# add panel specific text
add_geom_at_position = list(
geom = geom_text(
aes(x = 50, y = 60, label = note),
size = 4, color = "black",
hjust = 0,
inherit.aes = FALSE)
),
# add panel specific ribbons
add_geom_at_position = list(
geom = geom_rect(
aes(ymin = ymin, ymax = ymax),
xmin = -Inf, xmax = Inf,
alpha = 0.005, fill = "blue",
linetype = "blank",
inherit.aes = FALSE
),
position = "bottom" # place below other geometries
),
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
))
print(p)Similar results can also be obtained when working with the package in a modular fashion, as demonstrated below.
While the main interface to this package is a single function, the creation of nested loop plots is actually implemented via modular functions. This is useful if the user wants more control over the design of the plot and especially if additional meta-data should be added.
We recreate the basic facetted nested loop plot using the same data step by step. These are
nested_loop_base_data. This data.frame contains all
information to create the nested loop plots from this package, except
for the data for drawing design parameter step functions. It can be used
to add further information for plotting.ggplot2 object via
nested_loop_base_plot. It does not contain design parameter
step functions.nested_loop_paramsteps_data.ggplot2 object for drawing parameter step
functions.ggplot2 object to adjust
scales and axes.plot_data = nested_loop_base_data(
design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
spu_x_shift = 75
)
p = nested_loop_base_plot(
plot_data,
x_name = "Samplesize",
y_name = "Error",
colors = scales::brewer_pal(palette = "Dark2")
)
print(p)plot_data = nested_loop_paramsteps_data(
plot_data,
steps_y_base = -10,
steps_y_height = 5
)
p = nested_loop_paramsteps_plot(
p, plot_data,
steps_values_annotate = TRUE,
steps_annotation_size = 2.5
)
print(p)p = add_processing(
p,
list(
# set limits
adjust_ylim = list(
y_expand_add = c(10, NULL)
),
# adjust theme
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
),
# add horizontal lines
add_abline = list(
intercept = 0
)
)
)
print(p)Using the package functions modularly opens up
many more options for customization. These are all based on modification
of the data.frames which are returned by
nested_loop_base_data and
nested_loop_paramsteps_data that provide the basis data for
the plotting functions of this package.
We demonstrate an exemplary customization here. First, we obtain the
necessary data. The data.frame of interest is stored in the
plotdf entry of the resulting list, which can be modified
to add meta-information to the plots. We do this using the
dplyr::mutate and dplyr::case_when
functionality.
plot_data = nested_loop_base_data(
design,
x = "samplesize", steps = "param3",
grid_rows = "param1", grid_cols = "param2",
spu_x_shift = 75
) %>%
nested_loop_paramsteps_data(
steps_y_base = -10,
steps_y_height = 5
)
# create annotation data
plot_data$plotdf %<>%
mutate(
annotate_scenario = case_when(
samplesize %in% c(100, 200) &
param3 == 1 &
param2 %in% c(2, 3)
~ 0 # height at which a point should be drawn on y-axis
),
annotate_value = case_when(y_coord > 60 ~ y_coord) %>%
round(2)
)We add the additional plot elements to the post-processing list via
add_points and add_text. Note that we set
inherit.aes to FALSE so that the points do not show up in
the legend.
p = nested_loop_base_plot(
plot_data,
x_name = "Samplesize",
y_name = "Error",
colors = scales::brewer_pal(palette = "Dark2")
) %>%
nested_loop_paramsteps_plot(
plot_data,
steps_values_annotate = TRUE,
steps_annotation_size = 2.5
) %>%
add_processing(
list(
# annotate interesting scenarios
add_points = list(
mapping = aes(x = samplesize, y = annotate_scenario),
shape = 8, color = "red", inherit.aes = FALSE
),
# annotate high values
add_text = list(
mapping = aes(label = annotate_value),
color = "black", size = 3, hjust = 0, vjust = 0,
nudge_x = 20, nudge_y = 1
),
# set limits
adjust_ylim = list(
y_expand_add = c(10, NULL)
),
# adjust theme
add_custom_theme = list(
axis.text.x = element_text(angle = -90,
vjust = 0.5,
size = 8)
)
)
)
print(p)## R version 4.4.2 (2024-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 17763)
##
## Matrix products: default
##
##
## locale:
## [1] LC_COLLATE=C LC_CTYPE=German_Austria.1252
## [3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C
## [5] LC_TIME=German_Austria.1252
##
## time zone: Europe/Vienna
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] looplot_0.5.0.9003 ggplot2_4.0.1 purrr_1.0.2 magrittr_2.0.3
## [5] dplyr_1.1.4
##
## loaded via a namespace (and not attached):
## [1] gtable_0.3.6 jsonlite_1.8.8 highr_0.10 compiler_4.4.2
## [5] Rcpp_1.0.12 tidyselect_1.2.1 stringr_1.5.1 jquerylib_0.1.4
## [9] scales_1.4.0 yaml_2.3.9 fastmap_1.1.1 plyr_1.8.9
## [13] R6_2.6.1 labeling_0.4.3 generics_0.1.3 knitr_1.45
## [17] forcats_1.0.0 tibble_3.2.1 bslib_0.6.1 pillar_1.9.0
## [21] RColorBrewer_1.1-3 rlang_1.1.6 utf8_1.2.4 stringi_1.8.3
## [25] cachem_1.0.8 xfun_0.42 sass_0.4.9 S7_0.2.0
## [29] viridisLite_0.4.2 cli_3.6.5 withr_3.0.2 digest_0.6.35
## [33] grid_4.4.2 rstudioapi_0.15.0 lifecycle_1.0.4 vctrs_0.6.5
## [37] evaluate_1.0.5 glue_1.8.0 farver_2.1.1 fansi_1.0.6
## [41] reshape2_1.4.4 rmarkdown_2.30 tools_4.4.2 pkgconfig_2.0.3
## [45] htmltools_0.5.8.1