diff --git a/DESCRIPTION b/DESCRIPTION
index bb688a8..de810b9 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: nflplotR
Title: NFL Logo Plots in 'ggplot2'
-Version: 1.1.0.9001
+Version: 1.1.0.9002
Authors@R:
person("Sebastian", "Carl", , "mrcaseb@gmail.com", role = c("aut", "cre"))
Description: A set of functions to visualize National Football League
@@ -24,10 +24,12 @@ Imports:
rlang (>= 0.4.11),
scales (>= 1.1.0)
Suggests:
+ base64enc (>= 0.1-3),
covr,
dplyr (>= 1.0.0),
ggtext (>= 0.1.1),
gridtext (>= 0.1.4),
+ gt (>= 0.8.0),
knitr,
rmarkdown,
rstudioapi (>= 0.13),
@@ -38,4 +40,4 @@ Suggests:
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
-RoxygenNote: 7.2.1
+RoxygenNote: 7.2.3
diff --git a/NAMESPACE b/NAMESPACE
index e7430ab..4bbe206 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -23,6 +23,8 @@ export(geom_nfl_headshots)
export(geom_nfl_logos)
export(geom_nfl_wordmarks)
export(ggpreview)
+export(gt_nfl_logos)
+export(gt_nfl_wordmarks)
export(nfl_team_factor)
export(nfl_team_tiers)
export(nflverse_sitrep)
diff --git a/NEWS.md b/NEWS.md
index ff34e2f..ec64250 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,7 @@
# nflplotR (development version)
* Import/export `nflverse_sitrep()`
+* Add new functions `gt_nfl_logos()` and `gt_nfl_wordmarks()` to render logos and wordmarks in `gt()` html tables. (#161)
# nflplotR 1.1.0
diff --git a/R/gt_nfl_logos.R b/R/gt_nfl_logos.R
new file mode 100644
index 0000000..b46d3ce
--- /dev/null
+++ b/R/gt_nfl_logos.R
@@ -0,0 +1,123 @@
+#' Render Logos and Wordmarks in 'gt' Tables
+#'
+#' @description Translate NFL team abbreviations into logos and wordmarks and
+#' render these images in html tables with the 'gt' package.
+#' @param gt_object A table object that is created using the [gt::gt()] function.
+#' @param columns The columns for which the image translation should be applied.
+#' Argument has no effect if `locations` is not `NULL`.
+#' @param height The absolute height (px) of the image in the table cell.
+#' @param locations If `NULL` (the default), the function will render
+#' logos/wordmarks in argument `columns`.
+#' Otherwise, the cell or set of cells to be associated with the team name
+#' transformation. Only the [gt::cells_body()], [gt::cells_stub()],
+#' [gt::cells_column_labels()], and [gt::cells_row_groups()] helper functions
+#' can be used here. We can enclose several of these calls within a `list()`
+#' if we wish to make the transformation happen at different locations.
+#'
+#' @return An object of class `gt_tbl`.
+#' @export
+#' @section Output of below example:
+#' \if{html}{\figure{logo_tbl.png}{options: width=75\%}}
+#' @examples
+#' \donttest{
+#' library(gt)
+#' library(nflplotR)
+#' teams <- valid_team_names()
+#' # remove conference logos from this example
+#' teams <- teams[!teams %in% c("AFC", "NFC", "NFL")]
+#' # create dataframe with all 32 team names
+#' df <- data.frame(
+#' team_a = head(teams, 16),
+#' logo_a = head(teams, 16),
+#' wordmark_a = head(teams, 16),
+#' team_b = tail(teams, 16),
+#' logo_b = tail(teams, 16),
+#' wordmark_b = tail(teams, 16)
+#' )
+#' # create gt table and translate team names to logo/wordmark images
+#' table <- df %>%
+#' gt() %>%
+#' gt_nfl_logos(columns = gt::starts_with("logo")) %>%
+#' gt_nfl_wordmarks(columns = gt::starts_with("wordmark"))
+#' }
+gt_nfl_logos <- function(gt_object,
+ columns,
+ height = 30,
+ locations = NULL){
+ gt_nflplotR_image(
+ gt_object = gt_object,
+ columns = columns,
+ height = height,
+ locations = locations,
+ type = "logos"
+ )
+}
+
+#' @rdname gt_nfl_logos
+#' @export
+gt_nfl_wordmarks <- function(gt_object,
+ columns,
+ height = 30,
+ locations = NULL){
+ gt_nflplotR_image(
+ gt_object = gt_object,
+ columns = columns,
+ height = height,
+ locations = locations,
+ type = "wordmarks"
+ )
+}
+
+gt_nflplotR_image <- function(gt_object,
+ columns,
+ height = 30,
+ locations = NULL,
+ type = c("logos", "wordmarks")){
+
+ rlang::check_installed("gt (>= 0.8.0)", "to render images in gt tables.")
+
+ type <- match.arg(type)
+
+ if(is.null(locations)){
+ locations <- gt::cells_body({{ columns }})
+ }
+
+ if (is.numeric(height)) {
+ height <- paste0(height, "px")
+ }
+
+ gt::text_transform(
+ data = gt_object,
+ locations = locations,
+ fn = function(x){
+ team_abbr <- nflreadr::clean_team_abbrs(as.character(x), keep_non_matches = FALSE)
+ # Create the image URI
+ uri <- get_image_uri(team_abbr = team_abbr, type = type)
+ # Generate the Base64-encoded image and place it within tags
+ paste0("")
+ }
+ )
+
+}
+
+# Taken from gt package and modified for nflplotR purposes
+# Get image URIs from image lists as a vector Base64-encoded image strings
+get_image_uri <- function(team_abbr, type = c("logos", "wordmarks")) {
+
+ lookup_list <- switch (type,
+ "logos" = logo_list,
+ "wordmarks" = wordmark_list
+ )
+
+ vapply(
+ team_abbr,
+ FUN.VALUE = character(1),
+ USE.NAMES = FALSE,
+ FUN = function(team) {
+ paste0(
+ "data:", "image/png",
+ ";base64,", base64enc::base64encode(lookup_list[[team]])
+ )
+ }
+ )
+}
diff --git a/man/figures/logo_tbl.png b/man/figures/logo_tbl.png
new file mode 100644
index 0000000..b0d0373
Binary files /dev/null and b/man/figures/logo_tbl.png differ
diff --git a/man/geom_from_path.Rd b/man/geom_from_path.Rd
index a2cae83..c644f97 100644
--- a/man/geom_from_path.Rd
+++ b/man/geom_from_path.Rd
@@ -16,10 +16,10 @@ geom_from_path(
)
}
\arguments{
-\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}} or
-\code{\link[ggplot2:aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
-default), it is combined with the default mapping at the top level of the
-plot. You must supply \code{mapping} if there is no plot mapping.}
+\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and
+\code{inherit.aes = TRUE} (the default), it is combined with the default mapping
+at the top level of the plot. You must supply \code{mapping} if there is no plot
+mapping.}
\item{data}{The data to be displayed in this layer. There are three
options:
@@ -37,10 +37,14 @@ will be used as the layer data. A \code{function} can be created
from a \code{formula} (e.g. \code{~ head(.x, 10)}).}
\item{stat}{The statistical transformation to use on the data for this
-layer, as a string.}
-
-\item{position}{Position adjustment, either as a string, or the result of
-a call to a position adjustment function.}
+layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the
+stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than
+\code{"stat_count"})}
+
+\item{position}{Position adjustment, either as a string naming the adjustment
+(e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a
+position adjustment function. Use the latter if you need to change the
+settings of the adjustment.}
\item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{ggplot2::layer()}}. These are
often aesthetics, used to set an aesthetic to a fixed value. See the below
diff --git a/man/geom_lines.Rd b/man/geom_lines.Rd
index 5a6ac5f..3122c97 100644
--- a/man/geom_lines.Rd
+++ b/man/geom_lines.Rd
@@ -24,7 +24,7 @@ geom_mean_lines(
)
}
\arguments{
-\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}} or \code{\link[ggplot2:aes_]{aes_()}}.}
+\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}.}
\item{data}{The data to be displayed in this layer. There are three
options:
diff --git a/man/geom_nfl_headshots.Rd b/man/geom_nfl_headshots.Rd
index 8dff732..4d5b4f3 100644
--- a/man/geom_nfl_headshots.Rd
+++ b/man/geom_nfl_headshots.Rd
@@ -16,10 +16,10 @@ geom_nfl_headshots(
)
}
\arguments{
-\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}} or
-\code{\link[ggplot2:aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
-default), it is combined with the default mapping at the top level of the
-plot. You must supply \code{mapping} if there is no plot mapping.}
+\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and
+\code{inherit.aes = TRUE} (the default), it is combined with the default mapping
+at the top level of the plot. You must supply \code{mapping} if there is no plot
+mapping.}
\item{data}{The data to be displayed in this layer. There are three
options:
@@ -37,10 +37,14 @@ will be used as the layer data. A \code{function} can be created
from a \code{formula} (e.g. \code{~ head(.x, 10)}).}
\item{stat}{The statistical transformation to use on the data for this
-layer, as a string.}
-
-\item{position}{Position adjustment, either as a string, or the result of
-a call to a position adjustment function.}
+layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the
+stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than
+\code{"stat_count"})}
+
+\item{position}{Position adjustment, either as a string naming the adjustment
+(e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a
+position adjustment function. Use the latter if you need to change the
+settings of the adjustment.}
\item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{ggplot2::layer()}}. These are
often aesthetics, used to set an aesthetic to a fixed value. See the below
diff --git a/man/geom_nfl_logos.Rd b/man/geom_nfl_logos.Rd
index f31684f..ac89940 100644
--- a/man/geom_nfl_logos.Rd
+++ b/man/geom_nfl_logos.Rd
@@ -16,10 +16,10 @@ geom_nfl_logos(
)
}
\arguments{
-\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}} or
-\code{\link[ggplot2:aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
-default), it is combined with the default mapping at the top level of the
-plot. You must supply \code{mapping} if there is no plot mapping.}
+\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and
+\code{inherit.aes = TRUE} (the default), it is combined with the default mapping
+at the top level of the plot. You must supply \code{mapping} if there is no plot
+mapping.}
\item{data}{The data to be displayed in this layer. There are three
options:
@@ -37,10 +37,14 @@ will be used as the layer data. A \code{function} can be created
from a \code{formula} (e.g. \code{~ head(.x, 10)}).}
\item{stat}{The statistical transformation to use on the data for this
-layer, as a string.}
-
-\item{position}{Position adjustment, either as a string, or the result of
-a call to a position adjustment function.}
+layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the
+stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than
+\code{"stat_count"})}
+
+\item{position}{Position adjustment, either as a string naming the adjustment
+(e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a
+position adjustment function. Use the latter if you need to change the
+settings of the adjustment.}
\item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{ggplot2::layer()}}. These are
often aesthetics, used to set an aesthetic to a fixed value. See the below
diff --git a/man/geom_nfl_wordmarks.Rd b/man/geom_nfl_wordmarks.Rd
index 8045215..4aa9e28 100644
--- a/man/geom_nfl_wordmarks.Rd
+++ b/man/geom_nfl_wordmarks.Rd
@@ -16,10 +16,10 @@ geom_nfl_wordmarks(
)
}
\arguments{
-\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}} or
-\code{\link[ggplot2:aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the
-default), it is combined with the default mapping at the top level of the
-plot. You must supply \code{mapping} if there is no plot mapping.}
+\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2:aes]{aes()}}. If specified and
+\code{inherit.aes = TRUE} (the default), it is combined with the default mapping
+at the top level of the plot. You must supply \code{mapping} if there is no plot
+mapping.}
\item{data}{The data to be displayed in this layer. There are three
options:
@@ -37,10 +37,14 @@ will be used as the layer data. A \code{function} can be created
from a \code{formula} (e.g. \code{~ head(.x, 10)}).}
\item{stat}{The statistical transformation to use on the data for this
-layer, as a string.}
-
-\item{position}{Position adjustment, either as a string, or the result of
-a call to a position adjustment function.}
+layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the
+stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than
+\code{"stat_count"})}
+
+\item{position}{Position adjustment, either as a string naming the adjustment
+(e.g. \code{"jitter"} to use \code{position_jitter}), or the result of a call to a
+position adjustment function. Use the latter if you need to change the
+settings of the adjustment.}
\item{...}{Other arguments passed on to \code{\link[ggplot2:layer]{ggplot2::layer()}}. These are
often aesthetics, used to set an aesthetic to a fixed value. See the below
diff --git a/man/gt_nfl_logos.Rd b/man/gt_nfl_logos.Rd
new file mode 100644
index 0000000..833c01d
--- /dev/null
+++ b/man/gt_nfl_logos.Rd
@@ -0,0 +1,62 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/gt_nfl_logos.R
+\name{gt_nfl_logos}
+\alias{gt_nfl_logos}
+\alias{gt_nfl_wordmarks}
+\title{Render Logos and Wordmarks in 'gt' Tables}
+\usage{
+gt_nfl_logos(gt_object, columns, height = 30, locations = NULL)
+
+gt_nfl_wordmarks(gt_object, columns, height = 30, locations = NULL)
+}
+\arguments{
+\item{gt_object}{A table object that is created using the \code{\link[gt:gt]{gt::gt()}} function.}
+
+\item{columns}{The columns for which the image translation should be applied.
+Argument has no effect if \code{locations} is not \code{NULL}.}
+
+\item{height}{The absolute height (px) of the image in the table cell.}
+
+\item{locations}{If \code{NULL} (the default), the function will render
+logos/wordmarks in argument \code{columns}.
+Otherwise, the cell or set of cells to be associated with the team name
+transformation. Only the \code{\link[gt:cells_body]{gt::cells_body()}}, \code{\link[gt:cells_stub]{gt::cells_stub()}},
+\code{\link[gt:cells_column_labels]{gt::cells_column_labels()}}, and \code{\link[gt:cells_row_groups]{gt::cells_row_groups()}} helper functions
+can be used here. We can enclose several of these calls within a \code{list()}
+if we wish to make the transformation happen at different locations.}
+}
+\value{
+An object of class \code{gt_tbl}.
+}
+\description{
+Translate NFL team abbreviations into logos and wordmarks and
+render these images in html tables with the 'gt' package.
+}
+\section{Output of below example}{
+
+\if{html}{\figure{logo_tbl.png}{options: width=75\%}}
+}
+
+\examples{
+\donttest{
+library(gt)
+library(nflplotR)
+teams <- valid_team_names()
+# remove conference logos from this example
+teams <- teams[!teams \%in\% c("AFC", "NFC", "NFL")]
+# create dataframe with all 32 team names
+df <- data.frame(
+ team_a = head(teams, 16),
+ logo_a = head(teams, 16),
+ wordmark_a = head(teams, 16),
+ team_b = tail(teams, 16),
+ logo_b = tail(teams, 16),
+ wordmark_b = tail(teams, 16)
+)
+# create gt table and translate team names to logo/wordmark images
+table <- df \%>\%
+ gt() \%>\%
+ gt_nfl_logos(columns = gt::starts_with("logo")) \%>\%
+ gt_nfl_wordmarks(columns = gt::starts_with("wordmark"))
+}
+}
diff --git a/man/scale_axes_nfl.Rd b/man/scale_axes_nfl.Rd
index c543b6f..948dfba 100644
--- a/man/scale_axes_nfl.Rd
+++ b/man/scale_axes_nfl.Rd
@@ -86,6 +86,7 @@ omitted.}
\item \code{waiver()} for the default labels computed by the
transformation object
\item A character vector giving labels (must be same length as \code{breaks})
+\item An expression vector (must be the same length as breaks). See ?plotmath for details.
\item A function that takes the breaks as input and returns labels
as output. Also accepts rlang \link[rlang:as_function]{lambda} function
notation.
diff --git a/man/scale_nfl.Rd b/man/scale_nfl.Rd
index cd75530..23b9e2c 100644
--- a/man/scale_nfl.Rd
+++ b/man/scale_nfl.Rd
@@ -82,6 +82,7 @@ omitted.}
\item \code{waiver()} for the default labels computed by the
transformation object
\item A character vector giving labels (must be same length as \code{breaks})
+\item An expression vector (must be the same length as breaks). See ?plotmath for details.
\item A function that takes the breaks as input and returns labels
as output. Also accepts rlang \link[rlang:as_function]{lambda} function
notation.
diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml
index 9409745..77b6d1e 100644
--- a/pkgdown/_pkgdown.yml
+++ b/pkgdown/_pkgdown.yml
@@ -96,6 +96,7 @@ reference:
Various helper functions.
contents:
- ggpreview
+ - starts_with("gt_nfl")
- nfl_team_factor
- nfl_team_tiers
- valid_team_names
diff --git a/tests/testthat/_snaps/nfl_team_factors/p1.svg b/tests/testthat/_snaps/nfl_team_factors/p1.svg
new file mode 100644
index 0000000..836be75
--- /dev/null
+++ b/tests/testthat/_snaps/nfl_team_factors/p1.svg
@@ -0,0 +1,593 @@
+
+
diff --git a/tests/testthat/_snaps/nfl_team_factors/p2.svg b/tests/testthat/_snaps/nfl_team_factors/p2.svg
new file mode 100644
index 0000000..08eb1dc
--- /dev/null
+++ b/tests/testthat/_snaps/nfl_team_factors/p2.svg
@@ -0,0 +1,593 @@
+
+
diff --git a/tests/testthat/_snaps/scale_nfl/p1.svg b/tests/testthat/_snaps/scale_nfl/p1.svg
index febedfd..9061743 100644
--- a/tests/testthat/_snaps/scale_nfl/p1.svg
+++ b/tests/testthat/_snaps/scale_nfl/p1.svg
@@ -66,38 +66,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0.00
diff --git a/tests/testthat/_snaps/theme-elements/p1.svg b/tests/testthat/_snaps/theme-elements/p1.svg
index 5aa4a65..df07824 100644
--- a/tests/testthat/_snaps/theme-elements/p1.svg
+++ b/tests/testthat/_snaps/theme-elements/p1.svg
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/tests/testthat/_snaps/theme-elements/p2.svg b/tests/testthat/_snaps/theme-elements/p2.svg
index c194dff..8d5faec 100644
--- a/tests/testthat/_snaps/theme-elements/p2.svg
+++ b/tests/testthat/_snaps/theme-elements/p2.svg
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/tests/testthat/test-nfl_team_factors.R b/tests/testthat/test-nfl_team_factors.R
index 90ab4b6..2f49850 100644
--- a/tests/testthat/test-nfl_team_factors.R
+++ b/tests/testthat/test-nfl_team_factors.R
@@ -4,6 +4,8 @@ test_that("nfl team factors work", {
library(ggplot2)
+ set.seed(20220128)
+
# unsorted vector including NFL team abbreviations
teams <- c("LAC", "LV", "CLE", "BAL", "DEN", "PIT", "CIN", "KC")