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 3.6.3 (2020-02-29)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 8.1 x64 (build 9600)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=German_Austria.1252 LC_CTYPE=German_Austria.1252
## [3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C
## [5] LC_TIME=German_Austria.1252
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] looplot_0.5.0.9001 ggplot2_3.3.0.9000 purrr_0.3.3
## [4] magrittr_1.5 dplyr_0.8.4
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.1 RColorBrewer_1.1-2 pillar_1.4.3
## [4] compiler_3.6.3 highr_0.8 plyr_1.8.4
## [7] forcats_0.4.0 tools_3.6.3 digest_0.6.19
## [10] packrat_0.5.0 evaluate_0.14 tibble_2.1.3
## [13] gtable_0.3.0 viridisLite_0.3.0 pkgconfig_2.0.2
## [16] rlang_0.4.5 rstudioapi_0.11 yaml_2.2.0
## [19] xfun_0.8 withr_2.1.2 stringr_1.4.0
## [22] knitr_1.23 vctrs_0.2.4 grid_3.6.3
## [25] tidyselect_1.0.0 glue_1.3.1 R6_2.4.0
## [28] rmarkdown_1.13 reshape2_1.4.3 scales_1.0.0
## [31] htmltools_0.3.6 ellipsis_0.3.0 assertthat_0.2.1
## [34] colorspace_1.4-1 labeling_0.3 stringi_1.4.3
## [37] munsell_0.5.0 crayon_1.3.4
Rücker, Gerta, and Guido Schwarzer. 2014. “Presenting Simulation Results in a Nested Loop Plot.” Journal Article. BMC Medical Research Methodology 14.