Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/evamaerey/ggjudge
Say what you think about a plot up front
https://github.com/evamaerey/ggjudge
Last synced: 11 days ago
JSON representation
Say what you think about a plot up front
- Host: GitHub
- URL: https://github.com/evamaerey/ggjudge
- Owner: EvaMaeRey
- Created: 2023-08-23T03:59:28.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-28T20:26:58.000Z (about 1 year ago)
- Last Synced: 2023-08-29T03:59:31.475Z (about 1 year ago)
- Language: R
- Size: 472 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
Awesome Lists containing this project
README
---
output: github_document
---```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```# ggjudge
Discussion about the successes and failures of data visualization can be lengthy and nuanced. This is in contrast to the speed at which data visualizations themselves communicate. Data visualization is powerful because of 'preattentive' visual processing: patterns are perceived almost instantaneously compared with raw data counterparts.
To facilitate in a 'bottom-line-up-front' discussion of data visualization questions, analysts have used meta annotation of plots to communicate their perspectives and overall assessments of plots' success. Wilke 2018.
The goal of ggjudge is to easily allow for more meta annotation in the ggplot2 framework. Using FDV (Wilke) strategy for expressing high level judgments about plot's effectiveness, also extending to code, and to text console output. Uses cowplot's ggdraw functions.
The code is based on code that was used in Wilke's book.
Furthermore, given the visual creators are likely to return to code, the same 'final judge' approach may be applied to code snippets to quickly communicate overall assessments of coding strategies.
Therefore, ggjudge also makes functions available for code judgement; the downside is that this code is imaged in a data visualization which is not lightweight and does not allow for copy/paste. Finally, ggjudge provides the ability to judge text outputs.
Current functions are:
- judge_plot
- judge_chunk_code
- judge_chunk_output_plot
- judge_chunk_output_textLater 3 assume use of .Rmds;
These is not very customizable presently, but follows pretty closely to Wilk's choices, which were very effective.
# Judge plot
```{r judge_plot, include = T}
#' Title
#'
#' @param plot
#' @param color
#' @param alpha
#' @param judgement
#' @param family
#' @param fontface
#' @param clip
#' @param plot.margin
#' @param x
#' @param y
#' @param vjust
#' @param hjust
#' @param size
#' @param angle
#'
#' @return
#' @export
#'
#' @examples
judge_plot <- function(
plot = NULL,
color = "red",
alpha =.9,
judgement = "you made\na plot",
family = "Helvetica",
fontface = "bold",
clip = "off",
plot.margin = margin(50, 70, 10, 10),
x=1, y=1, vjust=1.1, hjust=1.1, size=35, angle = 0
){
if(is.null(plot)){plot <- ggplot2::last_plot()}
cowplot::ggdraw(plot + theme(plot.margin = plot.margin),
clip = clip) +
cowplot::draw_text(paste0(judgement, ""), x=x, y=y, vjust=vjust, hjust=hjust, size=size, angle = angle,
color=color, alpha=alpha, family = family, fontface = fontface) +
cowplot::draw_line(c(1, 1), c(0, 1), size= 2.8, color=color, alpha=alpha)
}
``````{r survived_plot}
library(tidyverse)p <- tidytitanic::passengers %>%
mutate(adult = age >= 18 ) %>%
filter(!is.na(age)) %>%
ggplot() +
aes(x = adult) +
geom_bar()judge_plot(plot = p, judgement = "awkward")
```# Judge chunk plot output
```{r judge_chunk_output_plot}
#' Title
#'
#' @param chunk_name
#' @param judgement
#'
#' @return
#' @export
#'
#' @examples
judge_chunk_output_plot <- function(chunk_name, judgement = "some output"){
knitr::knit_code$get(name = chunk_name) |>
paste(collapse = "\n") ->
text
eval(parse(text = text)) -> pp %>% judge_plot(family = "Helvetica", color = "red", alpha = .9, judgement = judgement, fontface = "bold")
}
``````{r survived_plot2}
# chunk name: survived_plot2
p <- tidytitanic::passengers %>%
mutate(adult = age >= 18 ) %>%
filter(!is.na(age)) %>%
ggplot() +
aes(x = adult) +
geom_bar()
``````{r}
judge_chunk_output_plot(chunk_name = "survived_plot2")
```# Judge code chunk code
```{r judge_chunk_code}
#' Title
#'
#' @param chunk_name
#' @param judgement
#' @param ...
#'
#' @return
#' @export
#'
#' @examples
judge_chunk_code <- function(chunk_name, judgement = "you wrote code", ...){
knitr::knit_code$get(name = chunk_name) |>
paste(collapse = "\n") ->
code# text <- "tidytitanic::passengers %>% \n mutate(adult = age >=18 ) %>% \n filter(!is.na(age)) %>% \nggplot() + \n aes(x = adult) + \n geom_bar()"
ggplot2::ggplot(data = data.frame(x = c(0, 1), y = c(0,1))) +
ggplot2::aes(x = x, y = y) +
ggplot2::geom_blank() +
ggplot2::annotate("text", label = code, x = 0, y = 1, hjust = 0, vjust = 1, size = 5, family = "Courier") +
ggplot2::theme_void() ->
syntax_plotsyntax_plot %>% judge_plot(judgement = judgement, ...)
}
``````{r titanic_plot, eval = F}
tidytitanic::passengers %>%
ggplot() +
aes(x = ifelse(survived,
"survived",
"not survived")) +
geom_bar() +
labs(x = NULL)
``````{r}
judge_chunk_code("titanic_plot", judgement = "repetative")
```# Judge chunk text output
```{r judge_chunk_output_text, eval = T}
#' Title
#'
#' @param chunk_name
#' @param judgement
#'
#' @return
#' @export
#'
#' @examples
judge_chunk_output_text <- function(chunk_name, judgement = "some output"){
knitr::knit_code$get(name = chunk_name) |>
paste(collapse = "\n") ->
text
capture.output(eval(parse(text = text))) -> outputoutput %>%
paste(collapse = "\n") ->
output_cleanlibrary(ggplot2)
ggplot(data = data.frame(x = c(0, 1), y = c(0,1))) +
aes(x = x, y = y) +
geom_blank() +
annotate("text", label = output_clean,
x = 0, y = 1, hjust = 0, vjust = 1,
size = 5, family = "Courier") +
theme_void() ->
output_plotoutput_plot %>% judge_plot(family = "Helvetica", color = "red", alpha = .9, judgement = judgement, fontface = "bold")
}
``````{r titanic_table}
library(magrittr)
tidytitanic::passengers |>
janitor::tabyl(sex, survived)
``````{r}
judge_chunk_output_text(chunk_name = "titanic_table")
```# send functions to package .R dir
```{r}
chunk_send_to_dir_r <- function(chunk_name){
for(i in 1:length(chunk_name)){knitr::knit_code$get(name = chunk_name[i]) |>
paste(collapse = "\n") |>
writeLines(con = paste0("R/", chunk_name[i], ".R"))
}
}chunk_send_to_dir_r(chunk_name = c("judge_plot", "judge_chunk_code", "judge_chunk_output_plot", "judge_chunk_output_text"))
```# send tests to tests
```{r}
chunk_send_to_dir_tests_testthat <- function(chunk_name){
for(i in 1:length(chunk_name)){knitr::knit_code$get(name = chunk_name[i]) |>
paste(collapse = "\n") |>
writeLines(con = paste0("tests/testthat/", chunk_name[i], ".R"))
}
}```
```{r test_judge_chunk_code, eval = F}
testthat::test_that("multiplication works", {
expect_equal(2 * 2, 4)
})
``````{r}
chunk_send_to_dir_tests_testthat("test_judge_chunk_code")
```# maybe later ideas
```{r, eval = F}
library(patchwork)judge_chunk_plot <- function
judge_chunk <- function(chunk_name,
judgement_code = "code",
judgement_output = "output",
...){
judge_chunk_code(chunk_name = chunk_name,
judgement = judgement_code) /
judge_chunk_output(chunk_name = chunk_name,
judgement = judgement_output)
}```
```{r, fig.width=7, fig.height=10, eval = F}
judge_chunk(chunk_name = "table_chunk",
judgement_code = "code: using indicator variable directly",
judgement_output = "output: information is lost")
```