scplot(exampleAB)
Plotting the data is a first important approach to single-case analysis. The scplot package has a set of functions to visualizes single-case data. It takes your sccdf an draws a time series plot and, if the scdf contains more than one case, a multiple baseline plot is created.
scplot is an add-on package to scan for visualizing single-case data.1
scplotsplot is available from the CRAN repository. Execute install.packages("scplot") to install it.
If you are more adventures, you can install the developmental version of scplot from github.The project is hosted at https://github.com/jazznbass/scplot. You can install it with pak::pak("jazznbass/scplot") from your R console. Make sure you have the package pak installed before2. The scplot package has to be compiled. When you are running R on a Windows machine you also have to install Rtools. Rtools is not an R package and can be downloaded from CRAN at https://cran.r-project.org/bin/windows/Rtools/.
The following chapter has been written with scplot version 0.7.0. If you have problems replicating the examples, please update to this version.
scplot(object, …)
You start by providing an scdf object (see Section 3.2) to the scplot() function (e.g. scplot(exampleAB)). This already creates a default plot.
scplot(exampleAB)
Now you use a series of pipe-operators (|>) to apply functions that add elements and change characteristics of the resulting plot. For example:
scplot(exampleABC) |>
add_title("My plot") |>
set_xlabel("Days", color = "red", size = 1.3)Here is an overview of possible functions:
| Function | What it does ... |
|---|---|
| set_dataline | Change the default dataline/ add an additional dataline |
| add_statline | Add a line or curve representing statistical parameters |
| add_arrow | Add an arrow to a specific case at a specific position |
| add_line | Add a line to a specific case |
| add_grid | Add a grid to the plot pannel |
| add_labels | Add value labels to each data-point |
| add_legend | Add a plot legend |
| add_marks | Mark specific data points of specific cases |
| add_ridge | Colour the area below the dataline |
| add_text | Add text to a specific case at a specific position |
| add_title | Add a title above the plot |
| add_caption | Add a caption below the plot |
| set_xlabel/ set_ylabel | Change and style axis labels |
| set_xaxis/ set_yaxis | Set the value range, increments etc. of the x- and y-axis |
| set_background | Set colour and texture of the plot background |
| set_panel | Set colour and texture of the plot panel |
| set_phasenames | Rename and style the phases |
| set_casenames | Rename and style the phases |
| set_separator | Style the vertical separator line between phases |
| set_theme | Apply a predefined visual theme |
| set_theme_element | Style specific elements of the plot |
| as_ggplot | Return a ggplot2 object for further processing |
| new_theme | Create/define a new visual theme |
All text, line, dot, and area elements have a set of arguments to change visual characteristics.
Text arguments can be applied to the following functions: add_caption(), add_labels(), add_legend(), add_text(), add_title(), set_xlabel(), set_ylabel(), set_phasenames(), set_casenames().
Possible arguments are:
| Argument | What it does ... |
|---|---|
| color | Change color. Either a color name or a color code (e.g. 'red' or '#110044'). |
| size | Relativ size to the base text size. |
| family | The font ('serif', 'sans', 'mono') |
| face | The font face ('plain', 'bold', 'italic', 'bold.italic') |
| hjust | Horizontal alignment (0 = left, 0.5 = centered, 1 = right) |
| vjust | Vertical alignment (0 = upper, 0.5 = centered, 1 = lower) |
Line arguments can be applied to the following functions: set_dataline(), add_statline(), add_line(), add_arrow(), add_ridge(), set_xaxis(), set_yaxis(), set_separator().
| Argument | What it does ... |
|---|---|
| color | Either a color name or a color code (e.g. 'red' or '#110044'). |
| linewidth | Relativ width of the line. |
| linetype | Linetype ('solid', 'dashed', 'dotted') |
Point arguments can be applied to the following functions: set_dataline(), add_statline(), add_marks(), add_arrow().
| Argument | What it does.... |
|---|---|
| color | Either a color name or a color code (e.g. 'red' or '#110044'). |
| linewidth | Relativ width of the line. |
| linetype | Linetype ('solid', 'dashed', 'dotted') |
set_dataline(
object,
variable = NULL,
line,
point,
type = “continuous”,
label = NULL,
show_gaps = FALSE,
…
)
By default, the single-case plot will depict the main dependent variable as defined in the scdf object. For changing this default behaviour or adding a second data line, use the set_dataline() function. The function takes the argument variable (with the main dependent variable as a default) which must correspond to a variable name within the applied scdf.
scplot(exampleAB_add) |>
set_dataline("depression")
Styling parameters like line and point colour will be set automatically based on the applied graphic theme. We will learn later about how to change and modify these themes. If you want to directly change the styling parameters, you can use the line and point arguments which take lists with styling parameters. For line, the parameters are colour, linewidth, linetype, lineend, and arrow. For point the parameters are colour, size, and shape.
scplot(exampleAB_add) |>
set_dataline(
line = list(colour = "darkred", linewidth = 2),
point = list(colour = "black", size = 3, shape = 15)
)
add_statline(
object,
stat = c(“mean”, “median”, “min”, “max”, “quantile”, “sd”, “mad”, “trend”, “moving mean”, “moving median”, “loreg”, “lowess”, “loess”, “trendA”, “trendA theil-sen”, “trendA bisplit”, “trendA trisplit”),
phase = NULL,
color = NULL,
linewidth = NULL,
linetype = NULL,
variable = NULL,
label = NULL,
segmented = NULL,
case = NULL,
…
)
Adding statlines is an important way to visualize statistical parameters of the data. The add_statline() function takes the argument stat which specifies the statistic to be visualized. The following sections show some examples for different statistics.
A first approach is to draw a line for each phase. This can be achieved with the following statistics mean, min, max, median, sd, quantile, and trend.
scplot(exampleABC) |>
add_statline("mean") |>
add_statline("max") |>
add_statline("min") |>
add_statline("median")
If you specify a specific phase, the statistic will be calculated for this phase only and the line will be drawn across the whole plot. This is usually used to draw a baseline as a reference for all other phases but can also be used with any phase (e.g., to draw a line with the mean of the intervention phase across the whole plot or the median of multiple combined intervention phases).
If you want to draw a line based on all phases (i.e., all values), set phase = "all".
The following example sets a line with the mean of phase A, the maximum of phases B and C, the minimum of phases 2 and 3, and the median of all phases:
scplot(exampleABC) |>
add_statline("mean", phase = "A") |>
add_statline("max", phase = c("B", "C")) |>
add_statline("min", phase = c(2, 3)) |>
add_statline("median", phase = "all") |>
add_legend()
By default, the trend statistic will give you a linear regression line (ordinary least squared method) for each phase. You can specify other methods for calculating the trend line with the method argument. Possible values are theil-sen, bisplit, and trisplit. The theil-sen method calculates a median based regression line. The bisplit and trisplit methods split the data into two or three parts and calculates a regression line for the median values of the first and last part. These methods are more robust against outliers but can also be less precise than the ordinary least squared method.
scplot(exampleABC) |>
add_statline("trend") |>
add_statline("trend", method = "theil-sen") |>
add_statline("trend", method = "bisplit") |>
add_statline("trend", method = "trisplit") 
If you want to draw a trend line for a specific phase, set the phase argument to the respective phase. The following example draws a linear regression line for each phase and an additional linear regression line for the baseline trend phase A with the OLS and Theil-Sen methods:
scplot(exampleABC) |>
add_statline("trend") |>
add_statline("trend", phase = "A", method = "theil-sen") |>
add_statline("trend", phase = "A")
Smoothed curves try to capture the general pattern of the data by fitting a curve to the data points. scplot provides several methods for calculating smoothed curves. Possible values for the stat argument are moving mean, moving median, loess, lowess.
Moving averages (based on the mean or median) compute a value for each data point using the surrounding observations. The lag argument specifies how many neighboring points are included on each side of the focal point. For example, lag = 2 means that the average is calculated from the focal data point, the two preceding values, and the two following values.
loess and lowess fit a local regression to the data. The arguments span (for loess) and f (for lowess) specify the proportion of neighbouring observations used to fit each local regression.
scplot(exampleABC) |>
add_statline("loess") |>
add_statline("moving mean")
Some of the statistics allow additional arguments to specify parameters:
| Statistic | Argument | What it does … |
|---|---|---|
| mean | trim | Trims the mean. trim = 0.10 calculates a 10% trimmed mean. |
| quantile | probs | Probability. probs = 0.25 calculates the 25% quantile. |
| moving mean, moving median | lag | Lag surrounding the estimated value. lag = 2 will calculate mean or median based on the two values before and after the to be replaced value. |
| loess | span | Proportion of the surrounding point to estimate a value. |
| lowess | f | Proportion of the surrounding point to estimate a value. |
scplot(exampleABC) |>
add_statline("moving mean", lag = 1) |>
add_statline("quantile", probs = 0.75)
If you do not specify the variable argument, the statline refers to the default first data-line.
scplot(exampleAB_add) |>
set_dataline("cigarrets") |>
add_statline("mean", variable = "cigarrets") |>
add_statline("trend")
By default, the statline is drawn for all cases. You can specify a specific case with the case argument. This is particularly useful for multiple baseline plots.
scplot(exampleAB) |>
add_statline("mean", case = 1) |>
add_statline("trend", case = 2) |>
add_statline("max", phase = "A", case = 3) |>
add_legend()
The lines can be drawn with gaps between the phases by setting segmented = TRUE. This can be applied to all statlines but is particularly useful for statistics that visualize the changes between phases. The defaults for trend depend on the stat and phase settings.
scplot(exampleABC) |>
add_statline("loess", segmented = TRUE, case = 1) |>
add_statline("trend", segmented = FALSE, case = 2) |>
add_statline("trend", phase = "B", segmented = TRUE, case = 3)
The positions argument can take a numeric vector:
scplot(exampleABC) |>
add_marks(case = 1, positions = c(7, 12)) |>
add_marks(case = 3, positions = c(3, 17), color = "blue", size = 7)
The positions argument can also be a string containing a logical expression. This will be evaluated and the respective positions will be marked.
scplot(exampleABC) |>
add_marks(case = 1, positions = "mt > 15") |>
add_marks(case = 2, positions = 'phase == "B"', color = "green", size = 5) |>
add_marks(case = 3, positions = "values > quantile(values, probs = 0.80)", color = "blue", size = 7) |>
add_marks(case = "all", positions = "values < quantile(values, probs = 0.20)", color = "yellow", size = 7) |>
add_caption("red: mt > 15 in case 1;
green: phase 'B' in case 2;
blue: values > 80% quantile of case 3;
yellow: values < 20% quantile of all cases")
And the positions argument can take the results from a scan outlier analyses and mark the positions of the outliers of each case:
scplot(exampleABC_outlier) |>
add_marks(positions = outlier(exampleABC_outlier), size = 3)
scplot(exampleABC) |>
add_text("Here!", case = 2, x = 10, y = 80, color = "red")
Draw lines either by providing starting (x0 and y0) an end coordinates (x1 and y1) or a horizontal (hline) or vertical (vline) position:
scplot(exampleABC) |>
add_line(case = 1, x0 = 6, y0 = 90, x1 = 3, y1 = 63, color = "red") |>
add_line(case = 2, hline = 80, color = "blue") |>
add_line(case = 3, vline = 15, color = "darkgreen")
Draw an arrow:
scplot(exampleABC) |>
add_arrow(case = 1, x0 = 6, y0 = 90, x1 = 3, y1 = 63) |>
add_text("Problem", case = 1, x = 6, y = 94, color = "red", size = 1, hjust = 0 ) 
scplot(exampleABC) |>
set_dataline(color = "blue", linewidth = 1, linetype = "dotted",
point = list(colour = "red", size = 1, shape = 2) )
# Equivalent_
# scplot(exampleABC) |>
# set_dataline(line = list(colour = "blue", linewidth = 1, linetype = "dotted"),
# point = list(colour = "red", size = 1, shape = 2)) The background ist the complete area of the plot including a frame.
scplot(exampleABC) |>
set_background(fill = "grey90", color = "black", linewidth = 2)
The panel refers to the coordinate system.
scplot(exampleABC) |>
set_panel(fill = "tan1", colour = "palevioletred", linewidth = 2)
You can specify a different panel color for each phase by providing a vector to the fill argument:
scplot(exampleABC) |>
set_panel(fill = c("grey80", "white", "blue4"))
Note: The colours are 50% transparent. So they might appear different.
Themes are complete styles that define various elements of a plot.
Function set_theme("theme_name")
Possible themes:
basic, colours_muted, colours_bw, colors_publication, colors_blind, colors_presentation, grid, grid2, grid3, small, tiny, big, phase_color, phase_shade, staircase, strip, minimal, dark, illustration, clarity, midnight, journal, playful, atelier, bauhaus, poster, handout, sparse, sienna














When providing multiple themes the order is important as the latter overwrites styles of the former.
scplot(exampleABC) |>
set_theme("sienna", "minimal", "small", "phase_color")
For creating a custom theme, start with the new_theme() function and add all styling parameters like described above. The resulting new object can now be applied to the set_theme() function:
my_theme <- new_theme() |>
set_panel(color = "red") |>
set_base_text(size = 12, color = "blue") |>
set_dataline(color = "darkred", linewidth = 2)
scplot(exampleABC) |> set_theme(my_theme)
The base text size is the absolute size. All other text sizes are relative to this base text size.
scplot(exampleAB_decreasing$Peter) |>
set_base_text(colour = "blue", family = "serif", face = "italic", size = 14)
scplot(exampleAB_decreasing) |>
add_title("A new plot", color = "darkblue", size = 1.3) |>
add_caption("Note. What a nice plot!", face = "italic", color = "darkred")
The add_legend() function adds a predefined legend that includes all datalines and statlines you have added. The labels for these lines are set automatically if you did not set the label argument in the corresponding set_dataline() and add_statline() functions.
Here is a simple example:
scplot(exampleABC) |>
add_statline("mean", color = "darkred") |>
add_statline("min", phase = "B", linewidth = 0.2, color = "darkblue") |>
add_legend()
And here is a more advanced example that uses several arguments to defines the style of the legend:
scplot(exampleAB_add) |>
set_dataline(label = "Pychological Wellbeing") |>
set_dataline(variable = "depression", color = "darkblue", label = "Depression") |>
add_statline(stat = "mean", label = "Wellbeing mean") |>
add_statline(stat = "mean", variable = "depression", label = "Depression mean") |>
set_phasenames(position = "none") |>
set_panel(fill = c("lightblue", "grey80")) |>
add_legend(
position = "left",
section_labels = c("Variables", "Section"),
title = list(color = "brown", size = 10, face = 2),
text = list(color = "darkgreen", size = 10, face = 2),
background = list(color = "lightgrey")
)
When axis ticks are to close together set the increment argument to leave additional space (e.g. increment = 2 will annotate every other value). When you set increment_from = 0 an additional tick will be set at 1 although counting of the increments will start at 0.
scplot(exampleA1B1A2B2) |>
set_xaxis(increment_from = 0, increment = 5,
color = "darkred", size = 0.7, angle = -90) |>
set_yaxis(limits = c(0, 50), size = 0.7, color = "darkred") 
scplot(exampleA1B1A2B2) |>
set_ylabel("Score", color = "darkred", angle = 0) |>
set_xlabel("Session", color = "darkred")
scplot(exampleA1B1A2B2) |>
set_casenames(c("A", "B", "C"), color = "darkblue", size = 1)
Casenames as strips:
scplot(exampleA1B1A2B2) |>
set_casenames(position = "strip",
background = list(fill = "lightblue"))
add_labels(
object,
nudge_y = 5,
nudge_x = 0,
round = NULL,
text = list(),
background = list(),
variable = “.dvar”,
padding = NULL
)
This function adds value labels to each data point. By deafult, the labels are placed above the data points. This can be changed with the nudge_y and nudge_x arguments (e.g., nudge_y = 7 will nudge the labels 7 units above the data points). A round argument can be used to round the values. The text and background of the labels can be styled with the text and background arguments which take a list with styling arguments. The padding argument sets the space between the text and the background of the label. Here is an example with the labels nudged above the data points:
scplot(exampleABC) |>
add_labels(text = list(color = "black", size = 0.7),
background = list(fill = "grey98"), nudge_y = 7)Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_label()`).

If you set the nudge_y argument to 0, the label will be set on-top the datapoints:
scplot(exampleABC) |>
set_theme("minimal") |>
add_labels(text = list(color = "black", size = 0.7),
background = list(fill = "grey98"),
nudge_y = 0, padding = 0.25)
Adds a ridge element to an scplot object. Ridges mark the area below the dataline. The colour of the ridge is set by the color argument. The argument variable can be used to specify which dataline the ridge should be based on. If not specified, the default dataline will be used.
scplot(exampleAB_mpd) |>
add_ridge("grey50")
scplot() generates ggplot2 objects. You can keep the ggplot2 object and assign it into a new object with the as_ggplot() function. Thereby, you can use many ggplot2 functions to rework your graphics:
# remove caption and apply a new default theme for all following scplots
options(scplot.plot.caption = NULL,
scplot.plot.theme = c("basic","minimal"))
# rename cases
names(byHeart2011) <- c("Lisa", "Pat", "Anna", "Lena")
# create ggplot objects for each case
p1 <- scplot(byHeart2011[1]) |> as_ggplot()
p2 <- scplot(byHeart2011[2]) |> as_ggplot()
p3 <- scplot(byHeart2011[3]) |> as_ggplot()
p4 <- scplot(byHeart2011[4]) |> as_ggplot()
# combine the ggplot objects with patchwork and add a title
library(patchwork)
p1 + p2 + p3 + p4 + plot_annotation(
tag_levels = "a", tag_suffix = ")",
title = "Data from university students learning vocabulary by heart"
)
options(scplot.plot.caption = "auto", scplot.plot.theme = "default")Here are some more complex examples
scplot(example_A24) |>
add_statline("lowess", linewidth = 1.5) |>
add_statline("loess", linewidth = 1.5) |>
add_statline("moving mean", lag = 3, linewidth = 1.5) |>
set_xaxis(size = 0.8, angle = 35) |>
set_dataline(point = "none") |>
add_legend(position = c(0.8, 0.75), background = list(color = "grey50")) |>
set_phasenames(c("no speedlimit", "with speedlimit"),
position = "left", hjust = 0, vjust = 1) |>
set_casenames(position = "none") |>
add_title("Effect of a speedlimit on the A24") |>
add_caption("Moving mean calculated with lag three", face = 3, size = 1) |>
add_ridge(color = "lightblue")
scplot(exampleAB_add) |>
set_dataline("cigarrets", point = list(size = 1)) |>
add_statline("trend", linetype = "dashed", label = "Trend of wellbeing") |>
add_statline("mean", variable = "cigarrets", color = "darkred", label = "Mean of cigarrets") |>
add_marks(positions = c(14,20), size = 3, variable = "cigarrets")|>
add_marks(positions = "cigarrets > quantile(cigarrets, 0.75)", size = 3) |>
set_xaxis(increment = 5) |>
set_phasenames(color = NA) |>
set_casenames(position = "strip") |>
add_legend(
section_labels = c("", ""),
text = list(face = 3)
) |>
set_panel(fill = c("lightblue", "grey80")) |>
add_ridge(color = "snow", variable = "cigarrets") |>
add_labels(variable = "cigarrets", nudge_y = 2,
text = list(color = "blue", size = 0.5)) |>
add_labels(nudge_y = 2, text = list(color = "black", size = 0.5),
background = list(fill = "white"))Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_label()`).

scplot(exampleA1B1A2B2) |>
set_xaxis(increment = 4, size = 0.7) |>
set_yaxis(color = "sienna3") |>
set_ylabel("Points", color = "sienna3", angle = 0) |>
set_xlabel("Weeks", size = 1, color = "brown") |>
add_title("Points by week", color = "sienna4", face = 3) |>
add_caption("An extensive Example.",
color = "black", size = 1, face = 3) |>
set_phasenames(c("Baseline", "Intervention", "Fall-Back", "Intervention_2"),
size = 0) |>
add_ridge(scales::alpha("lightblue", 0.5)) |>
set_casenames(labels = sample_names(3), color = "steelblue4", size = 0.7) |>
set_panel(fill = c("grey80", "grey95"), color = "sienna4") |>
add_grid(color = "grey85", linewidth = 0.1) |>
set_dataline(linewidth = 0.5, linetype = "solid",
point = list(colour = "sienna4", size = 0.5, shape = 18)) |>
add_labels(text = list(color = "sienna", size = 0.7), nudge_y = 4) |>
set_separator(linewidth = 0.5, linetype = "solid", color = "sienna") |>
add_statline(stat = "trendA", color = "tomato2") |>
add_statline(stat = "max", phase = c(1, 3), linetype = "dashed") |>
add_marks(case = 1:2, positions = 14, color = "red3", size = 2, shape = 4) |>
add_marks(case = "all", positions = "values < quantile(values, 0.1)",
color = "blue3", size = 1.5) |>
add_marks(positions = outlier(exampleABAB), color = "brown", size = 2) |>
add_text(case = 1, x = 5, y = 35, label = "Interesting",
color = "darkgreen", angle = 20, size = 0.7) |>
add_arrow(case = 1, 5, 30, 5, 22, color = "steelblue") |>
set_background(fill = "white") |>
add_legend() |>
set_theme("basic") |>
set_theme_element(panel.spacing.y = unit(0, "points"))Warning: Removed 6 rows containing missing values or values outside the scale range
(`geom_text()`).

Some features are still experimental and might change in future versions. They are not included in the documentation yet but you can already try them out.
scplot(exampleABC) |>
set_separator(staircase = TRUE, color = "darkred", linetype = "solid", linewidth = 1.5)
scplot(exampleA1B1A2B2) |>
set_theme("minimal", "tiny", "staircase")
scplot(scan::example_atd) |>
split_dataline("treatment") |>
add_legend()
scplot(scan::example_atd) |>
split_dataline("treatment", labels = c("Maze", "PGC")) |>
add_legend()
type argument to "bar"0 to 41)0 with the expand argument.scplot(exampleAB_add) |>
set_xaxis(expand = c(0, 0), limits = c(0, 41)) |>
set_dataline("cigarrets", type = "bar", linewidth = 0.6, point = "none") |>
add_statline("mean", variable = "cigarrets", color = "darkred") |>
add_statline("trend", linetype = "dashed") |>
set_casenames(position = "strip")
It replaces the plot.scdf() (or: plotSC()) function already included in scan (see Section D.1). For the time being, the “old” plot.scdf will be kept in future versions of scan.↩︎
with install.packages("scplot")↩︎