Descriptive use cases are provided here to provide ‘from the ground
up’ demonstrations of how to use fxl to generate visual
figures. A range of use cases will be provided to demonstrate the
research and clinical applications of the package.
Use Case Number 1: Basic Treatment Evaluation with Reversal
Design
The most fundamental and applicable design is the reversal design,
which has strong representation in both clinical and applied contexts.
In clinical contexts, this is often the quickest means of evaluating
whether a particular treatment has the desired effect on specific
behavior.
To be consistent with behavior analytic conventions this type of
figure would involve featuring:
A short tutorial regarding the design and execution of each
convention is provided in the section below.
Data Import
The data relevant to the figure must be imported in R in the form of
a data frame prior to generating a plotting object. By default,
fxl works with wide data because this is generally how
most folks trained to work within spreadsheets arrange and organize
their data (i.e., individual data series have their own columns).
An example of this data formatting is provided below:
use_case_1 <- data.frame(
Session = seq_len(16),
Target = c(
runif(3, 10, 20),
runif(3, 0, 10),
runif(3, 10, 20),
runif(7, 2, 8)
),
Phase = c(
rep("Baseline", 3),
rep("Intervention", 3),
rep("Baseline2", 3),
rep("Intervention2", 7)
),
Participant = rep("1", 16)
)
head(use_case_1, 3)
## Session Target Phase Participant
## 1 1 10.08000 Baseline 1
## 2 2 18.14250 Baseline 1
## 3 3 16.88793 Baseline 1
In this example, there is a column specific to the x-axis (Session)
and the y-axis (Target) as well as a variable to speaks to data embedded
within a specific condition (Phase). The Phase factor must have
unique tags for each phase (i.e., “baseline” vs “baseline2”),
otherwise it would try to connect points between two phases that were
not temporally connected (i.e., connecting the last point of the first
baseline to the first point of the second baseline).
Mapping Aesthetics to Data
The current data can be mapped using the var_map function to
assign the x-axis variable (Session), the y-axis variable (at least a
primary one; Target), and the phase identifier (Phase). The result of
this, without any specific data layers, is presented below.
scr_plot(
use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
)
)
Adding Primary Data Layers
By default, assigning the core plot alone will only create the
plotting space with default labels. A simple, single series of lines and
markers can be added to the core plotting object by adding the
scr_points and scr_lines layers.
scr_plot(use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
)
) |>
scr_lines() |>
scr_points()
Customizing Margins and Axes
The plotting engine will be intelligent ‘guesses’ as to margin sizes,
but these will often have to be overridden to make the overall display
more pleasing. That is, the ticks on the y-axis may need to be adjusted
to become less cluttered as well (i.e., larger interval between ticks)
and padding may be helpful to provide separation from the origin (i.e.,
0-point). An example of this provided in the space below.
scr_plot(use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
),
mai = c(
0.375,
0.5,
0.175,
0.1
),
omi = c(
0.25,
0.25,
0.25,
0.25
)
) |>
scr_xoverride(
c(0.5, 16.5),
xticks = 1:16
) |>
scr_yoverride(
c(-0.5, 20),
yticks = c(0, 5, 10, 15, 20),
ydelta = 5
) |>
scr_lines() |>
scr_points()
Adding Phase Change Lines
Adding phase changes lines to the current can be done in one of two
ways: adding to individual facets (e.g., just in one subplot;
scr_plines) or as an element that cuts across multiple facets
(e.g., across three plots in a figure; scr_plines_mbd). Since
the current example has only one facet, the scr_plines layer is
the most appropriate.
The current figure involves three elements, separating the four
phases, and each element is described using a specific key-ed value in
the call. Note: since we extended out the bottom of the y-axis, we must
add an argument (y2 = -0.5) to make sure this matches the
current floor for the figure in each of the phase change elements.
scr_plot(use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
),
mai = c(
0.375,
0.5,
0.175,
0.1
),
omi = c(
0.25,
0.25,
0.25,
0.25
)
) |>
scr_xoverride(
c(0.5, 16.5),
xticks = 1:16
) |>
scr_yoverride(
c(-0.5, 20),
yticks = c(0, 5, 10, 15, 20),
ydelta = 5
) |>
scr_lines() |>
scr_points() |>
scr_plines(
lty = 1,
lines = list(
"A" = list(
x1 = 3.5,
y1 = 20,
y2 = -0.5
),
"B" = list(
x1 = 6.5,
y1 = 20,
y2 = -0.5
),
"C" = list(
x1 = 9.5,
y1 = 20,
y2 = -0.5
)
)
)
Adding Phase Labels
The figure can be made more descriptive by drawing text in certain
areas to designate which phases correspond with certain changes in the
environment. Adding labels to the figure can be done by drawing them
within a single plot (i.e., scr_label_phase) or individually
across multiple facets (i.e., scr_label_facet). Since there is
only one subplot in this figure, the scr_label_phase call is
more appropriate.
The current figure involves four phases, two instances of baseline
and intervention, respectively. Labels are drawn using a series of
key-ed list elements, with each element corresponding to a unique label.
Note: since we have repeated instances of similar conditions, we must
override the label argument in the key-ed entry within each of
the items.
scr_plot(use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
),
mai = c(
0.375,
0.5,
0.175,
0.1
),
omi = c(
0.25,
0.25,
0.25,
0.25
)
) |>
scr_xoverride(
c(0.5, 16.5),
xticks = 1:16
) |>
scr_yoverride(
c(-0.5, 20),
yticks = c(0, 5, 10, 15, 20),
ydelta = 5
) |>
scr_lines() |>
scr_points() |>
scr_plines(
lty = 1,
lines = list(
"A" = list(
x1 = 3.5,
y1 = 20,
y2 = -0.5
),
"B" = list(
x1 = 6.5,
y1 = 20,
y2 = -0.5
),
"C" = list(
x1 = 9.5,
y1 = 20,
y2 = -0.5
)
)
) |>
scr_label_phase(
cex = 1,
face = 2,
adj = 0.5,
y = 20,
labels = list(
"A" = list(
x = 2,
label = "Baseline"
),
"B" = list(
x = 5,
label = "Intervention"
),
"C" = list(
x = 8,
label = "Baseline"
),
"D" = list(
x = 13,
label = "Intervention"
)
)
)
Customizing Title, Axes Labels
As a final point of styling this figure, the specific labels for each
axis can be customized to better suit the desired theme. Generally,
there are three primary features that might need adjustment:
scr_xlabel, scr_ylabel, and scr_title. Each
of these corresponds to the respective label.
An example customizing these features is provided in the section
below.
scr_plot(use_case_1,
aesthetics = var_map(
x = Session,
y = Target,
p = Phase
),
mai = c(
0.375,
0.5,
0.175,
0.1
),
omi = c(
0.25,
0.25,
0.25,
0.25
)
) |>
scr_xoverride(
c(0.5, 16.5),
xticks = 1:16
) |>
scr_yoverride(
c(-0.5, 20),
yticks = c(0, 5, 10, 15, 20),
ydelta = 5
) |>
scr_lines() |>
scr_points() |>
scr_plines(
lty = 1,
lines = list(
"A" = list(
x1 = 3.5,
y1 = 20,
y2 = -0.5
),
"B" = list(
x1 = 6.5,
y1 = 20,
y2 = -0.5
),
"C" = list(
x1 = 9.5,
y1 = 20,
y2 = -0.5
)
)
) |>
scr_label_phase(
adj = 0.5,
y = 20,
labels = list(
"A" = list(
x = 2,
label = "Baseline"
),
"B" = list(
x = 5,
label = "Intervention"
),
"C" = list(
x = 8,
label = "Baseline"
),
"D" = list(
x = 13,
label = "Intervention"
)
)
) |>
scr_xlabel("Daily Sessions") |>
scr_ylabel("Rates of Target Behavior (per Minute)") |>
scr_title("Use Case #1",
face = 2
)
Closing and Summary
This use case serves as a good introduction to the fxl
package in that the reversal design is very common across both research
and applied settings. Using this example as a base, one could easily
adapt this snippet and expand its elements to fits various clinical,
educational, and/or research needs.
Use Case Number 2: Multiple Baseline Design across Students
The multiple baseline design is among the most common research
designs used in educational settings. This particular design has good
utility in both research and clinical applications. However, the use of
multiple concurrent (or nonconcurrent) data series presents an issue
wherein most graphical charting packages do not support cross-plot
conventions natively. Historically, most analysts have had to rely on
over-engineered spreadsheets and highly specialized customizations to
produce the desired figure.
To be consistent with behavior analytic conventions this type of
figure would involve featuring:
One or more data layers with markers and lines
Phase change lines
Phase labels
Informative axis labels
Series annotations and/or a figure legend
Phase change lines that distinguish conditions within as well as
between individual subplots.
A short tutorial regarding the design and execution of each
convention is provided in the section below.
Data Import
The data relevant to the figure must be imported in R in the form of
a data frame prior to generating a plotting object. By default,
fxl works with wide data because this is generally how
most folks trained to work within spreadsheets arrange and organize
their data (i.e., individual data series have their own columns).
An example of this data formatting is provided below:
use_case_2 <- Gilroyetal2015
head(use_case_2, 3)
## Participant Session Condition Responding PhaseNum LineOff
## 1 Andrew 1 Baseline 10.81081 1 0
## 2 Andrew 2 Baseline 13.51351 1 0
## 3 Andrew 3 Baseline 10.81081 1 0
In this example, there is a column specific to the x-axis (Session)
and the y-axis (Responding) as well as a variable to speaks to data
embedded within a specific condition (Condition). The Phase factor must
have unique tags for each phase (i.e., “1” vs “2”), otherwise
it would try to connect points between two phases that were not
temporally connected (i.e., connecting the last point of the first
baseline to the first point of the second baseline).
Mapping Aesthetics to Data
The current data can be mapped using the var_map function to
assign the x-axis variable (Session), the y-axis variable (at least a
primary one; Responding), and the phase identifier (Condition). The
result of this, without any specific data layers, is presented
below.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
)
Adding Primary Data Layers
By default, assigning the core plot alone will only create the
plotting space with default labels. A simple, single series of lines and
markers can be added to the core plotting object by adding the
scr_points and scr_lines layers.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
) |>
scr_lines() |>
scr_points(cex = 2)
Adding Phase Change Lines
Adding phase changes lines to the current can be done in one of two
ways: adding to individual facets (e.g., just in one subplot;
scr_plines) or as an element that cuts across multiple facets
(e.g., across three plots in a figure; scr_plines_mbd). Since
the current example has three facets, illustrating a staggered
introduction of some independent variable, the scr_plines_mbd
layer is the most appropriate.
The current figure involves three elements, separating the phases
across the three panels, and each cross-figure phase change
point is described using a key-ed value in the call. Specifically there
are three phase change elements representing the (“A”) boundary
between baseline and intervention, (“B”) intervention and maintenance,
and (“C”) maintenance and generalization. The specific keys for the
lines are arbitrary; however, the lists must contain named
lists that use the facet as the name (e.g., “Andrew”,
“Brian”, “Charles”) and include relevant x and y
information. Note: since we extended out the bottom of the y-axis, we
must add an argument (y2 = -5) to the list for Charles to make
sure this matches the current floor for the figure in each of the phase
change elements–this generally only matters for the final plot as the
connection to phases below this point generally accomplishes this
without intervention.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
) |>
scr_lines() |>
scr_points(cex = 2) |>
scr_plines_mbd(
lines = list( # plot linked phase lines (note: drawn from top through bottom)
"A" = list(
"Andrew" = list(
x1 = 4.5,
y1 = 100
),
"Brian" = list(
x1 = 11.5,
y1 = 100
),
"Charles" = list(
x1 = 18.5,
y1 = 100,
y2 = -5
)
),
"B" = list(
"Andrew" = list(
x1 = 13.5,
y1 = 100
),
"Brian" = list(
x1 = 20.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
),
"C" = list(
"Andrew" = list(
x1 = 23.5,
y1 = 100
),
"Brian" = list(
x1 = 23.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
)
)
)
Adding Facet and Phase Labels
The figure can be made more descriptive by drawing text in certain
areas to designate which phases correspond with certain changes in the
environment and which facets (i.e., sub-plots) correspond with specific
participants/targets. Adding labels to the figure can be done by drawing
them within a single plot (i.e., scr_label_phase) or
individually across multiple facets (i.e., scr_label_facet).
Since there are three subplots in this figure, the
scr_label_phase and scr_label_facet calls are more
necessary.
The current figure features three participants (i.e., “Andrew”,
“Brian”, “Charles”) and the plots are illustrated in that order. The
scr_label_facet is called with a labels argument and
the named lists must correspond with the values for the subplot (e.g.,
“Andrew”). Each of these arguments must feature information regarding
where to draw that label. Note: it is possible to set a general
x or y argument in the overall layer as well as to
override the label argument in the named list (i.e., if
differing from the name for the list/facet).
The figure features four phases across each of the facets–baseline,
intervention, maintenance, and generalization. Phase labels are drawn
using a series of key-ed list elements, with each element corresponding
to a unique label drawn somewhere on the figure. However, since this
plot involves multiple subplots in the overall figure, the analyst must
specify which facet to draw these labels upon. That is, the
facet argument in scr_labels_phase must be set to
“Andrew” to specify that phase labels will be drawn on the topmost facet
only.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
) |>
scr_lines() |>
scr_points(cex = 2) |>
scr_plines_mbd(
lines = list( # plot linked phase lines (note: drawn from top through bottom)
"A" = list(
"Andrew" = list(
x1 = 4.5,
y1 = 100
),
"Brian" = list(
x1 = 11.5,
y1 = 100
),
"Charles" = list(
x1 = 18.5,
y1 = 100,
y2 = -5
)
),
"B" = list(
"Andrew" = list(
x1 = 13.5,
y1 = 100
),
"Brian" = list(
x1 = 20.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
),
"C" = list(
"Andrew" = list(
x1 = 23.5,
y1 = 100
),
"Brian" = list(
x1 = 23.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
)
)
) |>
scr_label_facet(
cex = 1.5, # plot labels across facets (not within a single facet)
adj = 1,
y = 10,
labels = list( # list of labels to draw (will use assigned key for label)
"Andrew" = list(
x = 27
),
"Brian" = list(
x = 27
),
"Charles" = list(
x = 27
)
)
) |>
scr_label_phase(
facet = "Andrew", # plot labels on specific facet
cex = 1.25,
adj = 0.5,
y = 107,
labels = list( # list of labels to draw (will use assigned key for label)
"Baseline" = list(
x = 2.5
),
"Treatment" = list(
x = 9
),
"Maintenance" = list(
x = 19
),
"Generalization" = list(
x = 26
)
)
)
Customizing Title, Axes Labels
As a final point of styling this figure, the specific labels for each
axis can be customized to better suit the desired theme. Generally,
there are three primary features that might need adjustment:
scr_xlabel, scr_ylabel, and scr_title. Each
of these corresponds to the respective label.
An example customizing these features is provided in the section
below.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
) |>
scr_lines() |>
scr_points(cex = 2) |>
scr_plines_mbd(
lines = list( # plot linked phase lines (note: drawn from top through bottom)
"A" = list(
"Andrew" = list(
x1 = 4.5,
y1 = 100
),
"Brian" = list(
x1 = 11.5,
y1 = 100
),
"Charles" = list(
x1 = 18.5,
y1 = 100,
y2 = -5
)
),
"B" = list(
"Andrew" = list(
x1 = 13.5,
y1 = 100
),
"Brian" = list(
x1 = 20.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
),
"C" = list(
"Andrew" = list(
x1 = 23.5,
y1 = 100
),
"Brian" = list(
x1 = 23.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
)
)
) |> # plot lines, using x/y from aesthetics
scr_label_phase(
facet = "Andrew", # plot labels on specific facet
cex = 1.25,
adj = 0.5,
y = 107,
labels = list( # list of labels to draw (will use assigned key for label)
"Baseline" = list(
x = 2.5
),
"Treatment" = list(
x = 9
),
"Maintenance" = list(
x = 19
),
"Generalization" = list(
x = 26
)
)
) |>
scr_xlabel("Session") |> # Override x-axis label (bottom only shown by default)
scr_ylabel(" Percent Accuracy") |> # Override y-axis label (centered, leftmost label)
scr_title("Rates of Acquisition across Participants",
face = 2
)
Saving Figure Output
After the desired design is complete, the figure drawn within R can
be saved in any number of formats (e.g., rasters, vectors) depending on
the need (e.g., insert into an educational report, saved to include in
manuscript). It is important to think carefully about the dimensions
supplied for the output. That is, smaller figures will present as
“cramped” and may not provide sufficient space in the plane to include
suitable text sizes.
An example that outputs the current figure to a PNG-type file is
provided in the section below.
scr_plot(
use_case_2,
aesthetics = var_map(
x = Session,
y = Responding,
p = Condition,
facet = Participant
),
mai = c(
0.375,
0.375,
0.2,
0.0
),
omi = c(
0.25,
0.25,
0.25,
0.1
)
) |>
scr_xoverride(
c(0.25, 27.5),
xticks = 1:27,
xtickslabs = as.character(1:27)
) |> # manually override x-axis (make extra room for labels)
scr_yoverride(
c(-5, 105), # manually override y-axis and tick interval (tick every 10 units)
yticks = seq(0, 100, by = 10),
ytickslabs = as.character(seq(0, 100, by = 10)),
) |>
scr_lines() |>
scr_points(cex = 2) |>
scr_plines_mbd(
lines = list( # plot linked phase lines (note: drawn from top through bottom)
"A" = list(
"Andrew" = list(
x1 = 4.5,
y1 = 100
),
"Brian" = list(
x1 = 11.5,
y1 = 100
),
"Charles" = list(
x1 = 18.5,
y1 = 100,
y2 = -5
)
),
"B" = list(
"Andrew" = list(
x1 = 13.5,
y1 = 100
),
"Brian" = list(
x1 = 20.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
),
"C" = list(
"Andrew" = list(
x1 = 23.5,
y1 = 100
),
"Brian" = list(
x1 = 23.5,
y1 = 100
),
"Charles" = list(
x1 = 23.5,
y1 = 100,
y2 = -5
)
)
)
) |> # plot lines, using x/y from aesthetics
scr_label_phase(
facet = "Andrew", # plot labels on specific facet
cex = 1.25,
adj = 0.5,
y = 107,
labels = list( # list of labels to draw (will use assigned key for label)
"Baseline" = list(
x = 2.5
),
"Treatment" = list(
x = 9
),
"Maintenance" = list(
x = 19
),
"Generalization" = list(
x = 26
)
)
) |>
scr_xlabel("Session") |> # Override x-axis label (bottom only shown by default)
scr_ylabel(" Percent Accuracy") |> # Override y-axis label (centered, leftmost label)
scr_title("Rates of Acquisition across Participants",
face = 2
) # |>
# scr_save(
# name = "use_case_2.png",
# units = "in",
# width = 9,
# height = 6,
# format = "png"
# )
Closing and Summary
This use case serves as a good expansion to using the fxl
package because the multiple baseline design is very common in research
and practice. Both researchers and clinicians can use this example and
use case to fit various clinical, educational, and/or research
needs.