--- title: "Overview" output: rmarkdown::html_vignette: toc: true vignette: > %\VignetteIndexEntry{ospsuite.plots} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, dpi = 300, fig.show = "hold", fig.align = "center", fig.width = 7, out.width = "80%", comment = "#>" ) ``` ```{r setup, echo=FALSE} options(rmarkdown.html_vignette.check_title = FALSE) library(ospsuite.plots) library(tidyr) ``` # 1. Introduction ## 1.1 Objectives of ospsuite.plots The main purpose of the `ospsuite.plots` library is to provide standardized plots typically used in the context of PBPK modeling. The library supports plot generation for the packages `OSPSuiteR` and `OSPSuite.ReportingEngine`. The library is based on `ggplot2` functionality and also utilizes the `ggh4x` package. # 2. Default Settings for Layout `ospsuite.plots` provides default settings for the layout, including theme, geometric aesthetics, colors, and shapes for distinct scales. Examples within this vignette are plotted using the following test data: ```{r get-test-data, results='asis'} testData <- exampleDataCovariates |> dplyr::filter(SetID == "DataSet1") |> dplyr::select(c("ID", "Age", "Obs", "Pred", "Sex")) knitr::kable(head(testData), digits = 3) ``` ## 2.1 Plots with and without Default Layout ### 2.1.1 Default ggplot Layout - A plot created using the `ospsuite.plots` function - B customized plot ```{r default-layout-comparison, warning=FALSE, fig.alt="Two plots comparing default ggplot styling (A) versus ospsuite.plots styling (B). Plot A shows a histogram with default ggplot formatting. Plot B shows a scatter plot with customized colors, shapes, and legend positioning demonstrating enhanced styling capabilities."} # ospsuite.plots function ospsuite.plots::plotHistogram(data = testData, mapping = aes(x = Age)) + labs(tag = "A") # Customized plot ggplot(data = testData, mapping = aes(x = Obs, y = Pred, color = Sex, shape = Sex)) + geom_point() + theme(legend.position = "top") + labs(tag = "B") ``` ### 2.1.2 Set ospsuite.plots Layout To set the default layout, we use the same logic as in `ggplot2::theme_set()`. The previous settings are returned invisibly, so you can easily save them and restore them later. `setDefaults()` sets the theme, discrete color palette, and various options. All objects can also be set separately as described below. Shape ordering for OSP-aware geoms is controlled per plot via `scale_shape_osp()` or `scale_shape_osp_manual()`. ```{r set-ospsuite-defaults, warning=FALSE, fig.show='hold', fig.alt="Two plots showing the effect of setting ospsuite.plots defaults. Plot A shows a histogram with ospsuite.plots styling applied. Plot B shows a scatter plot that now automatically adopts the ospsuite.plots theme, colors, shapes, and formatting after setDefaults() is called."} # Set default layout and save previous layout in variable oldDefaults oldDefaults <- ospsuite.plots::setDefaults(defaultOptions = list(), colorMapList = NULL) # ospsuite.plots function ospsuite.plots::plotHistogram(data = testData, mapping = aes(x = Age)) + labs(tag = "A") # Customized plot ggplot(data = testData, mapping = aes(x = Obs, y = Pred, color = Sex, fill = Sex, shape = Sex)) + geom_point() + theme(legend.position = "top") + labs(tag = "B") ``` ### 2.1.3 Reset to Previously Saved Layout ```{r reset-to-previous-defaults, warning=FALSE, fig.show='hold', fig.alt="Two plots demonstrating resetting to previously saved layout defaults. Plot A shows the histogram reverting to original default styling after resetDefaults() is called. Plot B shows the scatter plot also returning to the original ggplot defaults, confirming that the layout reset worked correctly."} # Reset to previously saved layout options ospsuite.plots::resetDefaults(oldDefaults = oldDefaults) # ospsuite.plots function ospsuite.plots::plotHistogram(data = testData, mapping = aes(x = Age)) + labs(tag = "A") # Customized plot ggplot(data = testData, mapping = aes(x = Obs, y = Pred, color = Sex, shape = Sex)) + geom_point() + theme(legend.position = "top") + labs(tag = "B") ``` ## 2.2 Default Theme Functions to set the `ospsuite.plots` default theme only are `setDefaultTheme()` and `resetDefaultTheme()`. These functions are called by `setDefaults()` and `resetDefaults()`. ```{r defaultTheme} # Set ospsuite.plots Default Theme oldTheme <- ospsuite.plots::setDefaultTheme() # Customize theme using ggplot functionalities theme_update(legend.position = "top") theme_update(legend.title = element_blank()) # Reset to the previously saved theme ospsuite.plots::resetDefaultTheme(oldTheme) ``` ## 2.3 Default Color Functions to set the `ospsuite.plots` default color only are `setDefaultColorMapDistinct()` and `resetDefaultColorMapDistinct()`. These functions are called by `setDefaults()` and `resetDefaults()`. Colors are set to discrete and ordinal scales for `fill` and `colour`. The package provides some color palettes in the object `colorMaps` (see `?colorMaps`). The example below shows plots with: - A plot with default settings for up to 6 different colors - B plot with default settings for more than 6 different colors - C customized settings for all following plots using the `colorMaps[["grays"]]` - D customized plot: set gray scale for this plot only using function `scale_fill_grey()` - E customized settings for all following plots using `ggsci::pal_lancet()(9)` - F customized plots: set gray scale for this plot only using function `ggsci::scale_color_lancet()` ```{r default-color-settings-6colors, fig.alt="Tile plot demonstrating default color settings for up to 6 different colors. The plot shows a 3x2 grid of colored tiles, each representing a different discrete color from the default ospsuite.plots color palette for small categorical datasets."} # Set ospsuite.plots Default Color oldColors <- ospsuite.plots::setDefaultColorMapDistinct() ggplot() + geom_tile(aes(x = rep(seq(1, 3), 2), y = rep(seq(1, 2), each = 3), fill = as.factor(seq(1, 6)))) + labs(title = "Default settings for up to 6 different colors", tag = "A") + theme(legend.position = "none", axis.title = element_blank()) ``` ```{r default-color-settings-many-colors, fig.alt="Tile plot demonstrating default color settings for more than 6 different colors. The plot shows a 7x7 grid plus 2 additional tiles (51 total), illustrating how ospsuite.plots handles large categorical datasets by cycling through and extending the color palette."} ggplot() + geom_tile(aes(x = c(rep(seq(1, 7), 7), 1, 2), y = c(rep(seq(1, 7), each = 7), 8, 8), fill = as.factor(seq(1, 51)))) + labs(title = "Default settings for more than 6 different colors") + theme(legend.position = "none", axis.title = element_blank()) ``` ```{r customize-colors-gray, fig.alt="Tile plot demonstrating customized gray color palette. The plot shows a 3x3 grid of tiles using grayscale colors from the ospsuite.plots colorMaps gray palette, illustrating how to apply monochromatic color schemes for accessibility or publication requirements."} # Customize colors: set to gray colors ospsuite.plots::setDefaultColorMapDistinct(colorMaps[["grays"]]) ggplot() + geom_tile(aes(x = rep(seq(1, 3), 3), y = rep(seq(1, 3), each = 3), fill = as.factor(seq(1, 9)))) + theme(legend.position = "none", axis.title = element_blank()) + labs(title = "colorMaps gray", tag = "C") ``` ```{r ggplot-scale-fill-grey, fig.alt="Tile plot using ggplot2's built-in scale_fill_grey() function. The plot shows a 3x3 grid of tiles demonstrating how to override ospsuite.plots defaults with standard ggplot2 gray scale functions for individual plots."} ggplot() + geom_tile(aes(x = rep(seq(1, 3), 3), y = rep(seq(1, 3), each = 3), fill = as.factor(seq(1, 9)))) + theme(legend.position = "none", axis.title = element_blank()) + scale_fill_grey() + labs(title = "scale_fill_grey", tag = "D") ``` ```{r ggsci-lancet-colors, fig.alt="Tile plot using ggsci Lancet journal color palette. The plot shows a 3x3 grid of tiles demonstrating how to set ospsuite.plots defaults to use professional journal color schemes inspired by The Lancet publication style."} # Set to color palettes inspired by plots in Lancet journals ospsuite.plots::setDefaultColorMapDistinct(ggsci::pal_lancet()(9)) ggplot() + geom_tile(aes(x = rep(seq(1, 3), 3), y = rep(seq(1, 3), each = 3), fill = as.factor(seq(1, 9)))) + theme(legend.position = "none", axis.title = element_blank()) + labs(title = "ggsci::pal_lancet", tag = "E") ``` ```{r ggsci-color-lancet-override, fig.alt="Tile plot using ggsci Lancet color palette with scale override. The plot shows a 3x3 grid of tiles demonstrating how to use ggsci::scale_color_lancet() to override the default color mapping for individual plots while maintaining the Lancet color scheme."} # Set to color palettes inspired by plots in Lancet journals ospsuite.plots::setDefaultColorMapDistinct(ggsci::pal_lancet()(9)) ggplot() + geom_tile(aes(x = rep(seq(1, 3), 3), y = rep(seq(1, 3), each = 3), fill = as.factor(seq(1, 9)))) + theme(legend.position = "none", axis.title = element_blank()) + ggsci::scale_color_lancet() + labs(title = "ggsci::scale_color_lancet", tag = "F") ``` ### Reset to Previously Saved Color Map ```{r resetColorMap} # Reset to the previously saved color map ospsuite.plots::resetDefaultColorMapDistinct(oldColorMaps = oldColors) ``` ## 2.4 Default Shapes All point layers produced by `ospsuite.plots` use `geom_point_osp()`, which draws from the OSP shape palette defined in `ospShapeNames`. When you build your own plots and want them to combine consistently with `ospsuite.plots` outputs, prefer `geom_point_osp()` over the raw `ggplot2::geom_point()`. Shape ordering is controlled per plot, not via a global option: - `geom_point_osp()` paired with `scale_shape_osp()` assigns shapes automatically from `ospShapeNames`. - `scale_shape_osp_manual(values = c(level1 = "circle", level2 = "diamond", ...))` sets an explicit mapping. - `scale_shape_osp_identity()` is the right choice when the data already contains shape names. Raw `ggplot2::geom_point()` keeps using ggplot2's native pch shapes and is unaffected. ## 2.5 Default Options `getDefaultOptions()` returns a list of options used in this package. These options are set by the function `setDefaults()` via the variable `defaultOptions`. ```{r, eval=FALSE} ospsuite.plots::setDefaults(defaultOptions = ospsuite.plots::getDefaultOptions()) ``` The names of all options defined by this package start with the package name `ospsuite.plots` as a prefix and a suffix. The suffixes are listed in the enumeration `OptionKeys`. There are two helper functions (`setOspsuite.plots.option` and `getOspsuite.plots.option`) to set and get these options. ## 2.5.1 Options to Customize Watermark All plots in this packages are created with the function `ggplotWithWatermark()` instead of `ggplot()`. This function creates a `ggplot` with a customized print function which adds a watermark. The watermark is **enabled by default** — plots produced without any configuration will already carry the watermark. Setting the option to `NULL` is treated the same as using the default, so the watermark will still appear. No opt-in is required; you only need to interact with these options if you want to customize or remove the watermark. To override this default in your `.Rprofile` (e.g., to disable watermarks globally): ```r # Disable watermarks globally options(ospsuite.plots.watermarkEnabled = FALSE) ``` You can edit your `.Rprofile` with `usethis::edit_r_profile()`. **Attention!** If you combine plots e.g. with `cowplot:plot_grid` the default print function without watermark is called. In this case you have to add the watermark with the function `addWatermark(plotObject)` before the print. The watermark can be customized by these options: - Switch the watermark on and off (option key = `watermarkEnabled`, default = `TRUE`) - Define the label (option key = `watermarkLabel`, default = "preliminary analysis") - Customize format (option key = `watermarkFormat`, default = `list(x = 0.5, y = 0.5, color = "lightgrey", angle = 30, fontsize = 12, alpha = 0.7)`) ### Examples to Customize Watermark - A: Change format of watermark - B: Disable watermark - C: Reset to default ```{r customize-watermark, fig.alt="Plot demonstrating customized watermark formatting. The plot shows a blank coordinate system with a red watermark rotated 90 degrees, positioned at specific coordinates with increased font size and reduced transparency, labeled 'NEW' instead of the default text."} # Change format and label of watermark setOspsuite.plots.option(optionKey = OptionKeys$watermarkFormat, value = list(x = 0.2, y = 0.6, color = "red", angle = 90, fontsize = 24, alpha = 0.2)) setOspsuite.plots.option(optionKey = OptionKeys$watermarkLabel, value = "NEW") # Initialize plot ggplotWithWatermark() + labs(title = "Changed Watermark", tag = "A") ``` ```{r disable-watermark, fig.alt="Plot demonstrating disabled watermark functionality. The plot shows a clean blank coordinate system with no watermark text overlay, illustrating how the watermarkEnabled option can be set to FALSE for clean publication-ready plots."} # Disable watermark setOspsuite.plots.option(optionKey = OptionKeys$watermarkEnabled, value = FALSE) # Initialize plot ggplotWithWatermark() + labs(title = "No Watermark", tag = "B") ``` ```{r reset-watermark-default, fig.alt="Plot demonstrating reset watermark to default settings. The plot shows a blank coordinate system with the default watermark restored - gray text reading 'preliminary analysis' at 30-degree angle in the center with standard transparency and font size."} # Reset to default setOspsuite.plots.option(optionKey = OptionKeys$watermarkFormat, value = NULL) setOspsuite.plots.option(optionKey = OptionKeys$watermarkLabel, value = NULL) setOspsuite.plots.option(optionKey = OptionKeys$watermarkEnabled, value = TRUE) # Initialize plot ggplotWithWatermark() + labs(title = "Default Watermark", tag = "C") ``` ## 2.5.2 Options to Set the Defaults for Geom Layer Attributes All plot functions have input variables `geom*Attributes` which are passed as variables to the corresponding ggplot layer. The defaults of the input variables can be set by options. ```{r options_defaultgeoms, echo=FALSE} df <- rbind( data.frame(defaultOption = "Line", inputVariable = c("geomLineAttributes"), functions = c("plotTimeProfile()")), data.frame(defaultOption = "Ribbon", inputVariable = "geomRibbonAttributes", functions = c("plotTimeProfile()")), data.frame(defaultOption = "Point", inputVariable = "geomPointAttributes", functions = c("plotTimeProfile()", "plotResVsCov()", "plotRatioVsCov()", "plotPredVsObs()")), data.frame(defaultOption = "Errorbar", inputVariable = "geomErrorbarAttributes", functions = c("plotTimeProfile()", "plotResVsCov()", "plotRatioVsCov()", "plotPredVsObs()")), data.frame(defaultOption = "LLOQ", inputVariable = "geomLLOQAttributes", functions = c("plotTimeProfile()", "plotResVsCov()", "plotRatioVsCov()", "plotPredVsObs()")), data.frame(defaultOption = "Hist", inputVariable = "geomHistAttributes", functions = c("plotHistogram()")), data.frame(defaultOption = "Boxplot", inputVariable = c("geomBoxplotAttributes", "geomPointAttributes"), functions = c("plotBoxWhisker()", "plotBoxWhisker()")), data.frame(defaultOption = "ComparisonLine", inputVariable = c("geomComparisonLineAttributes"), functions = c("plotResVsCov()", "plotRatioVsCov()", "plotPredVsObs()")), data.frame(defaultOption = "GuestLine", inputVariable = c("geomGuestLineAttributes"), functions = c("plotResVsCov()", "plotRatioVsCov()", "plotPredVsObs()")) ) |> data.table::setDT() |> (\(x) x[, .(inputVariable = paste(inputVariable, collapse = ", ")), by = c("defaultOption", "functions")])() |> tidyr::pivot_wider(names_from = defaultOption, values_from = inputVariable, values_fill = " ") knitr::kable(df, align = "c", caption = "Usage of options for geom attributes") ``` With default options: - `LineAttributes = list()` - `Ribbon = list(color = NA)` - `PointAttributes = list()` - `ErrorbarAttributes = list(width = 0)` - `LLOQAttributes = list()` - `ComparisonLineAttributes = list(linetype = "dashed")` - `GuestLineAttributes = list(linetype = "dashed")` - `BoxplotAttributes = list(position = position_dodge(width = 1), color = "black")` - `HistAttributes = list(bins = 10, position = ggplot2::position_nudge())` ## 2.5.3 Options to Set Defaults for Aesthetics Options to set the face alpha of ribbons, filled points and options to set the filled points for values below and above LLOQ. ```{r default-aesthetics, eval=FALSE} # Default alpha = 0.5 getOspsuite.plots.option(optionKey = "alpha") # Alpha of LLOQ values c("TRUE" = 0.3, "FALSE" = 1) getOspsuite.plots.option(optionKey = "lloqAlphaVector") # Linetype LLOQ comparison lines "dashed" getOspsuite.plots.option(optionKey = "lloqLineType") ``` ## 2.5.4 Options for Percentiles There are two percentile-related options controlling default behavior: - `percentiles`: A numeric vector of five quantiles defining the lower whisker, lower box, median, upper box, and upper whisker used by `plotBoxWhisker()` (default = `c(0.05, 0.25, 0.5, 0.75, 0.95)`). - `defaultPercentiles`: A numeric vector of three quantiles used as the default for `plotRangeDistribution()` (default = `c(0.05, 0.5, 0.95)`). ```{r default-percentiles, eval=FALSE} # Get current box-whisker percentiles (5 values) getOspsuite.plots.option(optionKey = OptionKeys$percentiles) # Change box-whisker percentiles globally setOspsuite.plots.option(optionKey = OptionKeys$percentiles, value = c(0.1, 0.25, 0.5, 0.75, 0.9)) # Get current range-plot percentiles (3 values) getOspsuite.plots.option(optionKey = OptionKeys$defaultPercentiles) # Change range-plot default percentiles globally setOspsuite.plots.option(optionKey = OptionKeys$defaultPercentiles, value = c(0.1, 0.5, 0.9)) ``` ## 2.5.5 Options to Define Export Format There are options to define the export format using the function `exportPlot` (see details below): - `exportWidth`: Width of the exported file - `exportUnits`: Units for width and height - `exportDevice`: Device for plot export - `exportDpi`: Plot resolution The latter options are used directly as input for `ggplot2::ggsave`, so check the help for available values. # 3. Plot Functions All plot functions listed below call internally the function `initializePlot()`. This function constructs labels from the metadata and adds a watermark layer. It can also be used to create a customized ggplot. ## 3.1 `plotTimeProfile()` [Time Profile Plots](plot-time-profile.html) ## 3.2 `plotBoxWhisker()` [Box Whisker Plots](box-whisker-vignette.html) ## 3.3 `plotHistogram()` [Histogram Plots](histogram.html) ## 3.4 `plotPredVsObs()` [Goodness of Fit](Goodness_of_fit.html) ## 3.5 `plotResVsCov()` [Goodness of Fit](Goodness_of_fit.html) ## 3.6 `plotRatioVsCov()` [Goodness of Fit](Goodness_of_fit.html) ## 3.7 `plotQQ()` [Goodness of Fit](Goodness_of_fit.html) # 4. Additional Aesthetics This package provides some additional aesthetics. For more details, see the examples within the vignettes for the respective functions. - `groupby`: Shortcut to use different aesthetics to group. All functions where this aesthetic is used have also a variable `groupAesthetics`. The mapping `groupby` is copied to all aesthetics listed within this variable and to the aesthetic `group`. - `lloq`: Mapped to a column with values indicating the lower limit of quantification, adds horizontal (or vertical) lines to the plot. All observed values below the "lloq" are plotted with a lighter alpha. As values are compared row by row, it is possible to have more than one LLOQ. - `error`: Mapped to a column with additive error (e.g., standard deviation); error bars are plotted. This is a shortcut to map `ymin` and `ymax` directly (`ymin = y - error` and `ymax = y + error`). Additionally, if `yScale` is set, `ymin` values below 0 are set to `y`. - `error_relative`: Mapped to a column with relative error (e.g., geometric standard deviation); error bars are plotted. This is a shortcut to map `ymin` and `ymax` directly (`ymin = y / error_relative` and `ymax = y * error_relative`). - `y2axis`: Creates a plot with 2 y axes. It is used to map to a column with a logical value. Values where this column has a TRUE entry will be displayed with a secondary axis. - `mdv`: Mapped to a logical column. Rows where this column has entries set to TRUE are not plotted (MDV = missing data value, taken from NONMEM notation). - `observed` / `predicted`: For the function `plotPredVsObs()`, `observed` is mapped to `x` and `predicted` is mapped to `y`. Residuals and ratios must be pre-calculated before passing them to the plotting functions. If you are using the `{ospsuite}` package, use `ospsuite::addResidualColumn()` to add a residual column to your data. See `vignette("Goodness of Fit", package = "ospsuite.plots")` for examples. ```{r additional-aesthetic-table, echo=FALSE} df <- rbind( data.frame(aesthetic = "`groupby`", functions = c("plotTimeProfile()", "plotHistogram()", "plotPredVsObs()", "plotResVsCov()", "plotRatioVsCov()", "plotQQ()")), data.frame(aesthetic = "`lloq`", functions = c("plotTimeProfile()", "plotPredVsObs()")), data.frame(aesthetic = "`error`", functions = c("plotTimeProfile()", "plotRatioVsCov()", "plotPredVsObs()", "plotResVsCov()")), data.frame(aesthetic = "`error_relative`", functions = c("plotTimeProfile()", "plotRatioVsCov()", "plotPredVsObs()", "plotResVsCov()")), data.frame(aesthetic = "`y2axis`", functions = "plotTimeProfile()"), data.frame(aesthetic = "`mdv`", functions = c("plotTimeProfile()", "plotBoxWhisker()", "plotHistogram()", "plotPredVsObs()", "plotResVsCov()", "plotRatioVsCov()", "plotQQ()")), data.frame(aesthetic = "`observed` / `predicted`", functions = c("plotPredVsObs()")) ) |> dplyr::mutate(used = "X") |> tidyr::pivot_wider(names_from = aesthetic, values_from = used, values_fill = " ") knitr::kable(df, align = "c", caption = "Applicability of additional aesthetics in functions") ``` # 5. Plot Export This section demonstrates how to use the `exportPlot` function to save `ggplot` objects to files, adjusting the width and height of the exported plots as necessary. This function is part of the `ospsuite.plots` package and simplifies the process of exporting plots for various purposes, such as publication or presentation. ## 5.1 Basic Usage To export a plot, you need a ggplot object. Here's a basic example: Create a simple ggplot object: ```{r export-object, eval=FALSE} plotObject <- ospsuite.plots::plotHistogram(data = testData, mapping = aes(x = Age)) ``` Exporting the Plot: Using the `exportPlot` function, you can easily save this plot to a file: Replace "path/to/save" with the actual directory path where you want to save the plot, and adjust the width and height parameters as needed. ```{r export-basic, eval=FALSE} exportPlot(plotObject = plotObject, filepath = "path/to/save", filename = "myplot", width = 10, height = 8) ``` ## 5.2 Advanced Usage ### Adjusting Plot Dimensions Based on Content The `exportPlot` function can automatically adjust the plot dimensions based on its content, such as the presence of a legend or the aspect ratio. Assuming `plotObject` is your ggplot object: ```{r export-advanced, eval=FALSE} exportPlot(plotObject = plotObject, filepath = "path/to/save", filename = "adjusted_plot.png") ``` In this case, you don't need to specify the width and height explicitly; the function calculates them for you. The default width value saved in the `ospsuite.plots` option `exportWidth` is used. If an aspect ratio is defined in the theme of the plot, height will be adjusted accordingly; otherwise, the function exports square figures. # 6. Shapes ## 6.1 Default Shapes ```{r default-shapes, out.width = "90%", fig.asp = 0.7, fig.width = 8, fig.alt="Chart displaying all default OSP shape types available in ospsuite.plots. Shows various point shapes arranged in a grid with labels, demonstrating the visual appearance of each shape option."} shapes <- data.frame( shapeNames = ospShapeNames, x = rep(1:6, length.out = length(ospShapeNames)), y = rep(1:4, each = 6, length.out = length(ospShapeNames)) ) ggplot(shapes, aes(x, y, shape = shapeNames)) + geom_point_osp(size = 5, color = "blue", fill = "red") + scale_shape_osp_identity() + geom_text(aes(label = shapeNames), nudge_y = -0.3, size = 3) + theme_void() ``` ## 6.2 Using OSP Shapes in Plot Functions OSP shapes are available in all `ospsuite.plots` functions via the default shape scale set by `setDefaults()`. You can also apply them directly with `scale_shape_osp()`. ```{r osp-shapes-demo, fig.alt="Scatter plot demonstrating OSP shapes in ospsuite.plots. Shows four data points representing different species using distinct OSP shapes with each species having a distinct symbol and color."} oldDefaults <- ospsuite.plots::setDefaults() dt <- data.frame(x = c(1, 2, 1, 2), y = c(1, 1, 2, 2), species = c("dog", "cat", "mouse", "rat")) plotObject <- plotYVsX(data = dt, mapping = aes(x = x, y = y, groupby = species), xScale = "linear", xScaleArgs = list(limits = c(0.5, 2.5)), yScale = "linear", yScaleArgs = list(limits = c(0.5, 2.5))) plot(plotObject) ``` ```{r cleanup, echo=FALSE} resetDefaults(oldDefaults) ``` ```