The ggtext package provides simple Markdown and HTML rendering for ggplot2. Under the hood, the package uses the gridtext package for the actual rendering, and consequently it is limited to the feature set provided by gridtext.

It is important to realize that gridtext implements 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, it’s good to assume that any Markdown, HTML, or CSS feature that isn’t shown in any of the ggtext or gridtext documentation doesn’t exist.

Support is provided for Markdown both in theme elements and in geoms. In both cases, there are two alternatives, one for creating simple text labels and one for creating text boxes with word wrapping.

Markdown text in theme elements

The ggtext package defines two new theme elements, element_markdown() and element_textbox()/element_textbox_simple(), which can be used in place of element_text() in ggplot2 themes.

Simple text labels

Simple text labels are created with element_markdown(). To demonstrate typical usage, let’s start with a basic plot of a parabola.


base <- ggplot(data.frame(x = c(-5, 5)), aes(x)) +
  stat_function(fun = ~ .x*.x)


This plot would benefit from nicer axis labels. In particular, assume we want the x axis label to read “independent variable x” and the y axis label to read “dependent variable y = x2”. In Markdown, we could write the axis labels as independent variable *x* and dependent variable *y* = *x*<sup>2</sup>. However, if we do so, we need to tell ggplot2 to interpret the axis labels as Markdown and not as plain text. We do this by setting axis.title.x and axis.title.y to element_markdown(). (Note that both are set to element_text() in the default theme.)

The new element element_markdown() behaves just like element_text(). For example, we can modify the color or the font size.

Inheritance of theme settings also works. For example, we can set both color and font size for axis.title, and then both axis.title.x and axis.title.y inherit the setting.

Note that we used element_text() instead of element_markdown() for axis.title in the above plot. We could have used element_markdown() as well and the result would have been the same. It doesn’t matter that we set axis.title = element_text(), because the axis.title element isn’t actually rendered, only the axis.title.x and axis.title.y elements are. We’re setting axis.title only for the purpose of providing shared parameter values to axis.title.x and axis.title.y.

This is important to keep in mind when trying to create more unusual plots, e.g. with the y axis on the right. The naive code fails:

This happens because the axis title on the right is actually drawn by axis.title.y.right. Therefore, setting that element to element_markdown() creates the desired result.

Additional styling can be applied via inline CSS. The CSS properties color, font-size, and font-family are currently supported. Multi-line labels can be created by placing <br> tags where line breaks are desired.

We set the lineheight property to 1.2 because the default lineheight is too small for multi-line text labels rendered with element_markdown().

Text boxes

Text boxes can be created with element_textbox() or element_textbox_simple(). Text boxes differ from labels created with element_markdown() in that they tend to have a specific width and wrap their contents so it fits that width. The height of a textbox is normally calculated automatically so it matches the content height, but explicitly setting the height is also possible. Finally, while markdown labels can be displayed at any angle, textboxes have only four possible orientations, upright, left-rotated, right-rotated, and inverted.

In practice, setting a theme element to element_textbox() in a ggplot2 theme will frequently not have the desired result, because textboxes require many additional parameters that are not set by the parent text elements present in standard themes. To work around this issue, you can use element_textbox_simple(). It sets reasonable defaults for the additional parameters and thus can be used more readily. You will usually be able to use element_textbox_simple() as is, with only a few parameter adjustments required.

The following example adds both a title and a subtitle to the plot by drawing one single text box.

Text boxes can have a background color and a border, and they have internal padding and external margins.

We can explicitly restrict the width of the box, and we can align the box relative to the enclosing space (with hjust and vjust) and the box content relative to the box edges (with halign and valign, not shown).

If we want a box to be rotated, we can use the orientation parameter.

Plotting with markdown text

Simple text labels

Markdown-formatted text labels can be placed into a plot with geom_richtext().

Text boxes

Markdown-formatted text boxes (with word wrap) can be placed into a plot with geom_textbox().