{"id":13712623,"url":"https://csdaw.github.io/ggprism/","last_synced_at":"2025-05-06T22:31:20.015Z","repository":{"id":49185984,"uuid":"251058802","full_name":"csdaw/ggprism","owner":"csdaw","description":"ggplot2 extension inspired by GraphPad Prism","archived":false,"fork":false,"pushed_at":"2025-05-04T14:47:58.000Z","size":98711,"stargazers_count":175,"open_issues_count":7,"forks_count":20,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-04T15:34:22.740Z","etag":null,"topics":["ggplot-extension","ggplot2","prism","r"],"latest_commit_sha":null,"homepage":"https://csdaw.github.io/ggprism/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csdaw.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-29T14:59:24.000Z","updated_at":"2025-05-04T14:42:54.000Z","dependencies_parsed_at":"2022-09-17T22:01:49.108Z","dependency_job_id":"666abc9e-8bbc-46c8-bb3e-16ef77e66c69","html_url":"https://github.com/csdaw/ggprism","commit_stats":{"total_commits":258,"total_committers":1,"mean_commits":258.0,"dds":0.0,"last_synced_commit":"0e411f4f186346d13834ed2d5187355cf549cbd8"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdaw%2Fggprism","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdaw%2Fggprism/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdaw%2Fggprism/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdaw%2Fggprism/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csdaw","download_url":"https://codeload.github.com/csdaw/ggprism/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252359800,"owners_count":21735452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ggplot-extension","ggplot2","prism","r"],"created_at":"2024-08-02T23:01:20.588Z","updated_at":"2025-05-06T22:31:18.931Z","avatar_url":"https://github.com/csdaw.png","language":"R","funding_links":[],"categories":["Themes and aesthetics"],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(\n  echo = FALSE,\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  dpi = 120,\n  fig.width = 6,\n  out.width = 400,\n  fig.path = \"man/figures/README-\"\n)\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(ggprism)\nlibrary(ggnewscale)\n```\n\n# ggprism \u003cimg src=\"man/figures/ggprism_logo.png\" align = \"right\" width = \"150\" /\u003e\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/csdaw/ggprism/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/csdaw/ggprism/actions/workflows/R-CMD-check.yaml)\n[![Codecov test coverage](https://codecov.io/gh/csdaw/ggprism/branch/master/graph/badge.svg)](https://app.codecov.io/gh/csdaw/ggprism?branch=master)\n[![CRAN version](https://www.r-pkg.org/badges/version/ggprism?color=green)](https://cran.r-project.org/package=ggprism)\n[![Website https://csdaw.github.io/ggprism](https://img.shields.io/website-up-down-green-red/https/csdaw.github.io/ggprism.svg)](https://csdaw.github.io/ggprism/)\n[![DOI](https://zenodo.org/badge/251058802.svg)](https://zenodo.org/badge/latestdoi/251058802)\n\u003c!-- badges: end --\u003e\n\nThe `ggprism` package provides various themes, palettes, and other useful \nfunctions to customise ggplots and give them the _'GraphPad Prism'_ look.\n\n## Install\n\nInstall the latest version from CRAN:\n\n```{r, eval=FALSE, echo=TRUE}\ninstall.packages(\"ggprism\")\n```\n\nInstall the development version from GitHub:\n\n```{r, eval=FALSE, echo=TRUE}\nremotes::install_github(\"csdaw/ggprism\")\n```\n\n## How to Use\n\nSee the [Getting Started](https://csdaw.github.io/ggprism/articles/ggprism.html) \npage for a quick overview of `ggprism` features.\nDetailed examples and instructions can be found below and on the \n[`ggprism` website](https://csdaw.github.io/ggprism/).\n\n```{r, echo=TRUE}\nlibrary(ggplot2)\nlibrary(ggprism)\n\ntg \u003c- ToothGrowth\ntg$dose \u003c- as.factor(tg$dose)\n\nbase \u003c- ggplot(tg, aes(x = dose, y = len)) + \n  geom_violin(aes(colour = dose, fill = dose), trim = FALSE) + \n  geom_boxplot(aes(fill = dose), width = 0.2, colour = \"black\") + \n  scale_y_continuous(limits = c(-5, 40))\n\np_vals \u003c- tibble::tribble(\n  ~group1, ~group2, ~p.adj,   ~y.position,\n  \"0.5\",   \"1\",     8.80e-14, 35,\n  \"0.5\",   \"2\",     1.27e-7,  39\n)\n```\n\n```{r ex, echo=TRUE, fig.show='hold'}\nbase\n\nbase + \n  scale_color_prism(\"floral\") + \n  scale_fill_prism(\"floral\") + \n  guides(y = \"prism_offset_minor\") + \n  theme_prism(base_size = 16) + \n  theme(legend.position = \"none\") + \n  add_pvalue(p_vals, label = \"p = {p.adj}\", tip.length = 0, label.size = 4)\n```\n\n## Feedback and Contributions\n\nAny feedback, questions, and suggestions are welcome and should be \nshared via [GitHub discussions](https://github.com/csdaw/ggprism/discussions). \n\nBug reports should be submitted via \n[GitHub issues](https://github.com/csdaw/ggprism/issues) \nwith a minimal reproducible example, e.g. using the \n[`reprex`](https://reprex.tidyverse.org) package. \n\nContributions to `ggprism` are also welcome and pull requires should also be\nsubmitted via [GitHub issues](https://github.com/csdaw/ggprism/issues). \nPlease fork/clone this repository and **create a new branch** to develop \nyour contribution in. Some ways to contribute might include:\n\n- Updates and corrections to documentation\n- Examples and vignettes for existing functions\n- Bug fixes\n- New functions with associated documentation, examples, and tests\n\n## Cite\n\nI would be very grateful if you could cite this package if you use it in your\npublication:\n\nCharlotte Dawson (`r format(Sys.Date(), \"%Y\")`). \n_ggprism: A 'ggplot2' Extension Inspired by 'GraphPad Prism'_. R package version\n`r getNamespaceVersion(\"ggprism\")`. \u003chttps://cran.r-project.org/package=ggprism\u003e\ndoi: 10.5281/zenodo.4556067\n\n```\n# BibTex for LaTeX users\n@Manual{\ntitle = {ggprism: A 'ggplot2' Extension Inspired by 'GraphPad Prism'},\nauthor = {Charlotte Dawson},\nyear = {`r format(Sys.Date(), \"%Y\")`},\nnote = {R package version `r getNamespaceVersion(\"ggprism\")`},\nurl = {https://cran.r-project.org/package=ggprism},\ndoi = {10.5281/zenodo.4556067}\n}\n```\n\n## More Examples\n\nRecreates [this figure](https://cdn.graphpad.com/assets/0.27.0/images/srcset/prism-get-actionable-help-w1920-800.png)\nfrom the GraphPad Prism website. See \n[this vignette](https://csdaw.github.io/ggprism/articles/web-only/ex1-dose.html) for the \nsource code and step-by-step instructions.\n\n```{r}\ndf \u003c- data.frame(\n  agonist = c(1e-10, 1e-8, 3e-8, 1e-7, 3e-7, 1e-6, 3e-6, 1e-5, 3e-5, 1e-4, 3e-4),\n  ctr1 = c(0, 11, 125, 190, 258, 322, 354, 348, NA, 412, NA),\n  ctr2 = c(3, 33, 141, 218, 289, 353, 359, 298, NA, 378, NA),\n  ctr3 = c(2, 25, 160, 196, 345, 328, 369, 372, NA, 399, NA),\n  trt1 = c(3, NA, 11, 52, 80, 171, 289, 272, 359, 352, 389),\n  trt2 = c(5, NA, 25, 55, 77, 195, 230, 333, 306, 320, 338), \n  trt3 = c(4, NA, 28, 61, 44, 246, 243, 310, 297, 365, NA)\n) %\u003e% \n  mutate(log.agonist = log10(agonist)) %\u003e% \n  pivot_longer(\n    c(-agonist, -log.agonist), \n    names_pattern = \"(.{3})([0-9])\", names_to = c(\"treatment\", \"rep\")\n  ) %\u003e% \n  filter(!is.na(value))\n\ndr_eq \u003c- y ~ min + ((max - min) / (1 + 10^(ec50 - (x))))\n```\n\n```{r ex2, warning=FALSE}\n# Before\nggplot(df, aes(x = log.agonist, y = value, colour = treatment, shape = treatment)) + \n  geom_point() + \n  geom_smooth(method = \"nls\", formula = dr_eq, se = FALSE,\n              method.args = list(start = list(min = 1.67, max = 397, ec50 = -7))) + \n  scale_x_continuous(\n    limits = c(-10, -3), breaks = -10:-3,\n    minor_breaks = log10(rep(1:9, 7)*(10^rep(-10:-4, each = 9)))\n  ) + \n  scale_y_continuous(limits = c(-100, 500), breaks = seq(-100, 500, 100)) + \n  theme_grey(base_size = 11) +\n  scale_colour_discrete(labels = c(\"No inhibitor\", \"Inhibitor\")) + \n  scale_shape_discrete(labels = c(\"No inhibitor\", \"Inhibitor\")) +\n  guides(colour = guide_legend(position = \"inside\"),\n         shape = guide_legend(position = \"inside\")) +\n  theme(axis.title.y = element_blank(),\n        legend.title = element_blank(),\n        legend.position.inside = c(0.05, 0.95),\n        legend.justification = c(0.05, 0.95)) + \n  labs(x = \"[Agonist], M\")\n\n# After\nexp_bold \u003c- function(lab) {\n  do.call(\n    expression,\n    lapply(paste(lab), function(x) bquote(bold(\"10\"^.(x))))\n  )\n}\n\nggplot(df, aes(x = log.agonist, y = value, shape = treatment)) + \n  geom_smooth(aes(colour = treatment),\n              method = \"nls\", formula = dr_eq, se = FALSE,\n              method.args = list(start = list(min = 1.67, max = 397, ec50 = -7))) + \n  scale_colour_manual(labels = c(\"No inhibitor\", \"Inhibitor\"),\n                      values = c(\"#00167B\", \"#9FA3FE\")) +\n  scale_x_continuous(\n    limits = c(-10, -3), breaks = -10:-3,\n    minor_breaks = log10(rep(1:9, 7)*(10^rep(-10:-4, each = 9))),\n    labels = exp_bold,\n    guide = \"prism_offset_minor\"\n  ) + \n  scale_y_continuous(\n    limits = c(-100, 500), breaks = seq(-100, 500, 100),\n    guide = \"prism_offset\"\n  ) + \n  guides(colour = guide_legend(position = \"inside\"),\n         shape = guide_legend(position = \"inside\")) +\n  theme(legend.title = element_blank(),\n        legend.position.inside = c(0.05, 0.95),\n        legend.justification = c(0.05, 0.95)) +\n  new_scale_colour() + \n  geom_point(aes(colour = treatment), size = 3) + \n  theme_prism(\"winter_bright\", base_size = 16) + \n  theme(legend.title = element_blank(),\n        legend.position.inside = c(0.05, 0.95),\n        legend.justification = c(0.05, 0.95)) +\n  scale_colour_prism(\"winter_bright\", labels = c(\"No inhibitor\", \"Inhibitor\")) + \n  scale_shape_prism(labels = c(\"No inhibitor\", \"Inhibitor\")) + \n  theme(axis.title.y = element_blank()) + \n  labs(x = \"[Agonist], M\")\n```\n\nRecreates Figure 2B from \n[Matsushita \u0026 Nishimura (2020)](https://doi.org/10.1038/s42003-020-0889-1), \nwhich was originally created using GraphPad Prism. See \n[this vignette](https://csdaw.github.io/ggprism/articles/web-only/ex2-wings.html) for the \nsource code and step-by-step instructions.\n\n```{r}\ndf2 \u003c- wings %\u003e%\n  mutate(measure = stringr::str_to_title(measure))\n\nwings.pvals \u003c- df2 %\u003e%\n  group_by(sex, measure) %\u003e%\n  rstatix::t_test(percent.change ~ genotype, p.adjust.method = \"BH\", var.equal = TRUE, ref.group = \"Tps1MIC/+\") %\u003e%\n  rstatix::add_x_position(x = \"measure\", dodge = 0.9) %\u003e%\n  mutate(label = c(\"***\", \"*\", \"P = 0.26\", \"***\", \"***\", \"P = 0.65\"))\n```\n\n```{r ex3}\n# Before\nggplot(df2, aes(\n  x = factor(measure, levels = c(\"Wing.size\", \"Cell.size\", \"Cell.number\")),\n  y = percent.change)\n) +\n  ggbeeswarm::geom_beeswarm(\n    aes(fill = genotype),\n    dodge.width = 0.9, \n    #spacing = 1.6, \n    shape = 21\n  ) +\n  scale_y_continuous(\n    limits = c(-20, 12),\n    expand = c(0, 0),\n    breaks = seq(-20, 10, 5)\n  ) +\n  scale_x_discrete(\n    labels = function(x) stringr::str_wrap(gsub(\"\\\\.\", \" \", x), width = 5)\n  ) +\n  facet_wrap(\n    ~ sex, \n    scales = \"free\",\n    labeller = labeller(sex = c(male = \"\\u2642\", female = \"\\u2640\"))\n  ) +\n  scale_fill_manual(\n    values = c(\"#026FEE\", \"#87FFFF\"), \n    labels = c(expression(\"Tps\"*1^italic(\"MIC\")~\"/ +\"), expression(\"Tps\"*1^italic(\"MIC\")))\n  ) +\n  labs(y = \"% change\") +\n  theme(\n    legend.position = \"bottom\",\n    axis.title.x = element_blank(),\n    strip.text = element_text(size = 14),\n    legend.spacing.x = unit(0, \"pt\"),\n    legend.text = element_text(margin = margin(r = 20))\n  ) +\n  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.3) +\n  stat_summary(\n    geom = \"crossbar\",\n    aes(fill = genotype),\n    fun = mean,\n    position = position_dodge(0.9),\n    colour = \"red\",\n    linewidth = 0.4, width = 0.7,\n    show.legend = FALSE\n  ) +\n  geom_text(\n    data = data.frame(\n      sex = factor(\"female\", levels = c(\"male\", \"female\")), \n      measure = \"Cell.number\", \n      percent.change = -18.5, \n      lab = \"(n = 10)\"\n    ), \n    aes(label = lab)\n  ) +\n  guides(fill = guide_legend(override.aes = list(size=3)))\n\n# After\nggplot(df2, aes(\n  x = factor(measure, levels = c(\"Wing.size\", \"Cell.size\", \"Cell.number\")),\n  y = percent.change)\n) +\n  ggbeeswarm::geom_beeswarm(\n    aes(fill = genotype),\n    dodge.width = 0.9, \n    #spacing = 1.6, \n    shape = 21\n  ) +\n  scale_y_continuous(\n    limits = c(-20, 12),\n    expand = c(0, 0),\n    breaks = seq(-20, 10, 5),\n    guide = \"prism_offset\"\n  ) +\n  scale_x_discrete(\n    guide = guide_prism_bracket(width = 0.15), \n    labels = function(x) stringr::str_wrap(gsub(\"\\\\.\", \" \", x), width = 5)\n  ) +\n  facet_wrap(\n    ~ sex, \n    scales = \"free\",\n    labeller = labeller(sex = c(male = \"\\u2642\", female = \"\\u2640\"))\n  ) +\n  theme_prism(base_fontface = \"plain\", base_line_size = 0.7, base_family = \"Arial\") +\n  scale_fill_manual(\n    values = c(\"#026FEE\", \"#87FFFF\"), \n    labels = c(expression(\"Tps\"*1^italic(\"MIC\")~\"/ +\"), expression(\"Tps\"*1^italic(\"MIC\")))\n  ) +\n  labs(y = \"% change\") +\n  theme(\n    legend.position = \"bottom\",\n    axis.title.x = element_blank(),\n    strip.text = element_text(size = 14),\n    legend.spacing.x = unit(0, \"pt\"),\n    legend.text = element_text(margin = margin(r = 20))\n  ) +\n  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.3) +\n  stat_summary(\n    geom = \"crossbar\",\n    aes(fill = genotype),\n    fun = mean,\n    position = position_dodge(0.9),\n    colour = \"red\",\n    linewidth = 0.4, width = 0.7,\n    show.legend = FALSE\n  ) +\n  add_pvalue(\n    wings.pvals, y = 10, xmin = \"xmin\", xmax = \"xmax\", tip.length = 0, \n    fontface = \"italic\", lineend = \"round\", bracket.size = 0.5\n  ) +\n  geom_text(\n    data = data.frame(\n      sex = factor(\"female\", levels = c(\"male\", \"female\")), \n      measure = \"Cell.number\", \n      percent.change = -18.5, \n      lab = \"(n = 10)\"\n    ), \n    aes(label = lab)\n  ) +\n  guides(fill = guide_legend(override.aes = list(size=3)))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/csdaw.github.io%2Fggprism%2F","html_url":"https://awesome.ecosyste.ms/projects/csdaw.github.io%2Fggprism%2F","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/csdaw.github.io%2Fggprism%2F/lists"}