{"id":13400700,"url":"https://github.com/wilkelab/ggtext","last_synced_at":"2025-12-30T11:08:41.291Z","repository":{"id":41167567,"uuid":"201365380","full_name":"wilkelab/ggtext","owner":"wilkelab","description":"Improved text rendering support for ggplot2","archived":false,"fork":false,"pushed_at":"2023-12-19T20:16:47.000Z","size":6162,"stargazers_count":656,"open_issues_count":44,"forks_count":37,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-06T03:19:02.801Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://wilkelab.org/ggtext/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wilkelab.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-08-09T01:29:50.000Z","updated_at":"2025-02-27T12:36:55.000Z","dependencies_parsed_at":"2024-01-17T22:13:43.349Z","dependency_job_id":"8e4a9905-c167-4ae0-86bb-1e3c88f8327c","html_url":"https://github.com/wilkelab/ggtext","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wilkelab%2Fggtext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wilkelab%2Fggtext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wilkelab%2Fggtext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wilkelab%2Fggtext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wilkelab","download_url":"https://codeload.github.com/wilkelab/ggtext/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243537868,"owners_count":20307098,"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":[],"created_at":"2024-07-30T19:00:54.762Z","updated_at":"2025-12-30T11:08:41.190Z","avatar_url":"https://github.com/wilkelab.png","language":"R","funding_links":[],"categories":["R","Themes and aesthetics","ggplot"],"sub_categories":["Text"],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, echo = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\"\n)\n```\n\n# ggtext: Improved text rendering support for ggplot2\n\n\n\u003c!-- badges: start --\u003e\n[![R build status](https://github.com/wilkelab/ggtext/workflows/R-CMD-check/badge.svg)](https://github.com/wilkelab/ggtext/actions)\n[![Coverage Status](https://img.shields.io/codecov/c/github/wilkelab/ggtext/master.svg)](https://codecov.io/github/wilkelab/ggtext?branch=master)\n[![CRAN status](https://www.r-pkg.org/badges/version/ggtext)](https://cran.r-project.org/package=ggtext)\n[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#maturing)\n\u003c!-- badges: end --\u003e\n\nThe ggtext package provides simple Markdown and HTML rendering for ggplot2. Under the hood, the package uses the [gridtext](https://CRAN.R-project.org/package=gridtext) package for the actual rendering, and consequently it is limited to the feature set provided by gridtext.\n\nSupport is provided for Markdown both in theme elements (plot titles, subtitles, captions, axis labels, legends, etc.) and in geoms (similar to `geom_text()`). In both cases, there are two alternatives, one for creating simple text labels and one for creating text boxes with word wrapping.\n\nImportantly, the gridtext package that provides the rendering support **implements only an extremely limited subset of Markdown/HTML/CSS.** It currently can make text bold or italics, can change the font, color, or size of a piece of text, can place text as sub- or superscript, and has extremely rudimentary image support. No other features are currently supported. As a general rule, any Markdown, HTML, or CSS feature that isn't shown in any of the ggtext or gridtext documentation likely doesn't exist.\n\n## Installation\n\nYou can install the latest stable release from CRAN via `install.packages()`:\n\n```{r eval = FALSE}\ninstall.packages(\"ggtext\")\n```\n\nTo install the latest development version of this package, please run the following line in your R console:\n\n```{r eval = FALSE}\nremotes::install_github(\"wilkelab/ggtext\")\n```\n\n## Markdown in theme elements\n\nThe ggtext package defines two new theme elements, `element_markdown()` and `element_textbox()`. Both behave similarly to `element_text()` but render the provided text as markdown/html. `element_markdown()` is meant as a direct replacement for `element_text()`, and it renders text without word wrapping. To start a new line, use the `\u003cbr\u003e` tag or add two spaces before the end of a line.\n\nAs an example, we can mix regular, italics, and bold text, and we can also apply colors to axis tick labels. This particular example was inspired by [this stackoverflow post.](https://stackoverflow.com/questions/39282293/r-ggplot2-using-italics-and-non-italics-in-the-same-category-label)\n\n```{r message = FALSE}\nlibrary(tidyverse)\nlibrary(ggtext)\nlibrary(glue)\n\ndata \u003c- tibble(\n  bactname = c(\"Staphylococcaceae\", \"Moraxella\", \"Streptococcus\", \"Acinetobacter\"),\n  OTUname = c(\"OTU 1\", \"OTU 2\", \"OTU 3\", \"OTU 4\"),\n  value = c(-0.5, 0.5, 2, 3)\n)\n\ndata %\u003e% mutate(\n  color = c(\"#009E73\", \"#D55E00\", \"#0072B2\", \"#000000\"),\n  name = glue(\"\u003ci style='color:{color}'\u003e{bactname}\u003c/i\u003e ({OTUname})\"),\n  name = fct_reorder(name, value)\n)  %\u003e%\n  ggplot(aes(value, name, fill = color)) + \n  geom_col(alpha = 0.5) + \n  scale_fill_identity() +\n  labs(caption = \"Example posted on **stackoverflow.com**\u003cbr\u003e(using made-up data)\") +\n  theme(\n    axis.text.y = element_markdown(),\n    plot.caption = element_markdown(lineheight = 1.2)\n  )\n```\n\nVery basic support for the `\u003cimg\u003e` tag exists, and it can be used, for example, to employ images as axis labels.\n\n```{r}\nlabels \u003c- c(\n  setosa = \"\u003cimg src='https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Iris_setosa.JPG/180px-Iris_setosa.JPG'\n    width='100' /\u003e\u003cbr\u003e*I. setosa*\",\n  virginica = \"\u003cimg src='https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Iris_virginica_-_NRCS.jpg/320px-Iris_virginica_-_NRCS.jpg'\n    width='100' /\u003e\u003cbr\u003e*I. virginica*\",\n  versicolor = \"\u003cimg src='https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/20140427Iris_versicolor1.jpg/320px-20140427Iris_versicolor1.jpg'\n    width='100' /\u003e\u003cbr\u003e*I. versicolor*\"\n)\n\nggplot(iris, aes(Species, Sepal.Width)) +\n  geom_boxplot() +\n  scale_x_discrete(\n    name = NULL,\n    labels = labels\n  ) +\n  theme(\n    axis.text.x = element_markdown(color = \"black\", size = 11)\n  )\n```\n\n`element_textbox()` offers support for rendering larger amounts of text that require word wrapping. Unlike `element_markdown()`, it cannot be used for axis tick labels, and it cannot draw text at arbitrary angles, only at fixed orientations corresponding to 0, 90, 180, and 270 degrees. In practice, you will usually want to use `element_textbox_simple()` instead of `element_textbox()`, as it sets useful defaults for many parameters not usually defined in ggplot2 themes.\n\n```{r}\nggplot(mtcars, aes(disp, mpg)) + \n  geom_point() +\n  labs(\n    title = \"\u003cb\u003eFuel economy vs. engine displacement\u003c/b\u003e\u003cbr\u003e\n    \u003cspan style = 'font-size:10pt'\u003eLorem ipsum *dolor sit amet,*\n    consectetur adipiscing elit, **sed do eiusmod tempor incididunt** ut\n    labore et dolore magna aliqua. \u003cspan style = 'color:red;'\u003eUt enim\n    ad minim veniam,\u003c/span\u003e quis nostrud exercitation ullamco laboris nisi\n    ut aliquip ex ea commodo consequat.\u003c/span\u003e\",\n    x = \"displacement (in\u003csup\u003e3\u003c/sup\u003e)\",\n    y = \"Miles per gallon (mpg)\u003cbr\u003e\u003cspan style = 'font-size:8pt'\u003eA measure of\n    the car's fuel efficiency.\u003c/span\u003e\"\n  ) +\n  theme(\n    plot.title.position = \"plot\",\n    plot.title = element_textbox_simple(\n      size = 13,\n      lineheight = 1,\n      padding = margin(5.5, 5.5, 5.5, 5.5),\n      margin = margin(0, 0, 5.5, 0),\n      fill = \"cornsilk\"\n    ),\n    axis.title.x = element_textbox_simple(\n      width = NULL,\n      padding = margin(4, 4, 4, 4),\n      margin = margin(4, 0, 0, 0),\n      linetype = 1,\n      r = grid::unit(8, \"pt\"),\n      fill = \"azure1\"\n    ),\n    axis.title.y = element_textbox_simple(\n      hjust = 0,\n      orientation = \"left-rotated\",\n      minwidth = unit(1, \"in\"),\n      maxwidth = unit(2, \"in\"),\n      padding = margin(4, 4, 2, 4),\n      margin = margin(0, 0, 2, 0),\n      fill = \"lightsteelblue1\"\n    )\n  )\n```\n\nAnother example, replacing facet strips with text boxes. \n```{r message = FALSE}\nlibrary(cowplot)\n\nggplot(mpg, aes(cty, hwy)) + \n  geom_point() +\n  facet_wrap(~class) +\n  theme_half_open(12) +\n  background_grid() +\n  theme(\n    strip.background = element_blank(),\n    strip.text = element_textbox(\n      size = 12,\n      color = \"white\", fill = \"#5D729D\", box.color = \"#4A618C\",\n      halign = 0.5, linetype = 1, r = unit(5, \"pt\"), width = unit(1, \"npc\"),\n      padding = margin(2, 0, 1, 0), margin = margin(3, 3, 3, 3)\n    )\n  )\n```\n\n## Geoms\n\nThe geom `geom_richtext()` provides markdown/html labels. Unlike `geom_label()`, the labels can be rotated.\n\n```{r}\ndf \u003c- tibble(\n  label = c(\n    \"Some text **in bold.**\",\n    \"Linebreaks\u003cbr\u003eLinebreaks\u003cbr\u003eLinebreaks\",\n    \"*x*\u003csup\u003e2\u003c/sup\u003e + 5*x* + *C*\u003csub\u003e*i*\u003c/sub\u003e\",\n    \"Some \u003cspan style='color:blue'\u003eblue text **in bold.**\u003c/span\u003e\u003cbr\u003eAnd *italics text.*\u003cbr\u003e\n    And some \u003cspan style='font-size:18pt; color:black'\u003elarge\u003c/span\u003e text.\"\n  ),\n  x = c(.2, .1, .5, .9),\n  y = c(.8, .4, .1, .5),\n  hjust = c(0.5, 0, 0, 1),\n  vjust = c(0.5, 1, 0, 0.5),\n  angle = c(0, 0, 45, -45),\n  color = c(\"black\", \"blue\", \"black\", \"red\"),\n  fill = c(\"cornsilk\", \"white\", \"lightblue1\", \"white\")\n)\n\n\nggplot(df) +\n  aes(\n    x, y, label = label, angle = angle, color = color, fill = fill,\n    hjust = hjust, vjust = vjust\n  ) +\n  geom_richtext() +\n  geom_point(color = \"black\", size = 2) +\n  scale_color_identity() +\n  scale_fill_identity() +\n  xlim(0, 1) + ylim(0, 1)\n```\n\nLabels without frame or background are also possible.\n\n```{r}\nggplot(df) +\n  aes(\n    x, y, label = label, angle = angle, color = color,\n    hjust = hjust, vjust = vjust\n  ) +\n  geom_richtext(\n    fill = NA, label.color = NA, # remove background and outline\n    label.padding = grid::unit(rep(0, 4), \"pt\") # remove padding\n  ) +\n  geom_point(color = \"black\", size = 2) +\n  scale_color_identity() +\n  xlim(0, 1) + ylim(0, 1)\n```\n\nThe geom `geom_textbox()` can draw boxes with word-wrapped text. It does not support arbitrary rotation angles, only fixed orientations, just like `element_textbox()`.\n\n```{r}\ndf \u003c- tibble(\n  label = rep(\"Lorem ipsum dolor **sit amet,** consectetur adipiscing elit,\n    sed do *eiusmod tempor incididunt* ut labore et dolore magna\n    aliqua.\", 2),\n  x = c(0, .6),\n  y = c(1, .6),\n  hjust = c(0, 0),\n  vjust = c(1, 0),\n  orientation = c(\"upright\", \"right-rotated\"),\n  color = c(\"black\", \"blue\"),\n  fill = c(\"cornsilk\", \"white\")\n)\n\nggplot(df) +\n  aes(\n    x, y, label = label, color = color, fill = fill,\n    hjust = hjust, vjust = vjust,\n    orientation = orientation\n  ) +\n  geom_textbox(width = unit(0.4, \"npc\")) +\n  geom_point(color = \"black\", size = 2) +\n  scale_discrete_identity(aesthetics = c(\"color\", \"fill\", \"orientation\")) +\n  xlim(0, 1) + ylim(0, 1)\n```\n\n## Acknowledgments\n\nThis project received [financial support](https://www.r-consortium.org/all-projects/awarded-projects) from the [R consortium.](https://www.r-consortium.org)\n\n\u003cimg src=\"https://www.r-consortium.org/wp-content/uploads/sites/13/2016/09/RConsortium_Horizontal_Pantone.png\" width=\"250\"\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilkelab%2Fggtext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilkelab%2Fggtext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilkelab%2Fggtext/lists"}