Home

Awesome

ggbrace

An R package that draws curly braces in ggplot2.

Table of contents

<img src="readme_files/frontImage.png"/>

Updates

Version 0.1.1 (Feb 2024) of ggbrace removed the original geom_brace function, which plots braces within the confines of the x-y-values. The same functionality can now be achieved with stat_brace( outside = FALSE ). Additionally, the text functionality is now its own function stat_bracetext which allows for more customization of the text using the same arguments that would be used in geom_text or geom_label. By default stat_brace uses geom="text" which can be changed e.g. by stat_brace(geom="label").

Installation

Install the package from CRAN

install.packages("ggbrace")

or from this git repository:

devtools::install_github("nicolash2/ggbrace")

Plotting braces

The new version of ggbrace uses only stat_brace to automatically enclose data points. stat_bracetext is used to generate fitting text.

In our example we use the iris data to create a dotplot. Then we look at how each of the three different modes draws braces to that plot.

library(ggplot2)
library(ggbrace)
data(iris)

plt <- ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species, label=Species)) + 
  geom_point() +
  theme_classic() +
  theme(legend.position="none")

plt + stat_brace()
<img src="readme_files/default_braces.png"/>

Labels & Modifications

Labels

We can add labels to the braces. For that the stat_bracetext is used.

plt + 
  stat_brace() +
  stat_bracetext()
<img src="readme_files/braces_with_text.png"/>

We can modify the text in the same way we would modify other text in ggplot. We can also switch between different text geoms (e.g. geom=label).

plt + 
  stat_brace() +
  stat_bracetext(size=6, angle=15, fontface="bold")
<img src="readme_files/custom_text.png"/>

Rotation

We can rotate the braces by 90, 180 or 270 degrees via the rotate argument. Note that any changes in stat_brace also have to be made in stat_bracetext so that the text appears at the right position

plt + 
  stat_brace(rotate = 90) + 
  stat_bracetext(rotate = 90)
<img src="readme_files/custom_rotation.png"/>

Location

By default, the location of the brace is beside the data points by default. We can change that by setting the paramter outside to FALSE.

plt + stat_brace(outside = FALSE)
<img src="readme_files/inside.png"/>

By default, braces have a position and shape that is calculated based on their data points.The position can be changed with the parameters distance (to the data points) and outerstart (in the coordinate system). The width of the braces can be set with the width argument (absolute coordinate system units), while the bending of the brace can be set with bending (number from 0 to 1).

plt + stat_brace(distance = 2) # the braces are put at a defined distance to the last data point of their group
plt + stat_brace(outerstart = 5) # all braces are put at the same position
plt + stat_brace(outerstart = 5, width = 1) # all braces get the same width
plt + stat_brace(outerstart = 5, width = 1, bending = 0.1) # all braces get the same curvature
<img src="readme_files/custom_distance.png"/>

Outside of plotting area

To vizualize the brace outside of the plotting area, we can simply use two ggplot2 functions.

plt + stat_brace(outerstart = 4.5) + 
  coord_cartesian(y=range(iris$Sepal.Width), clip = "off") + #for the range just use the data for the respective axis
  theme(plot.margin = unit(c(0.25, 0.11, 0.11, 0.11), units="npc"))
<img src="readme_files/outside.png"/>

Discrete values

Unfortunately, as of now, ggbrace isn't behaving well with discrete x/y axes, which is why they will have to be wrapped into the seq_along function within the aes().

df <- data.frame(x = c("a","b","c","d","e"), y = 1:5)     

ggplot(df, aes(x, y)) +
  geom_point() +
  stat_brace(aes(x=seq_along(x)))

This wrapping into the seq_along function is also used in the coord_cartesian function when trying to plot outside the plotting area.

df <- data.frame(x = c("a","b","c","d","e"), y = 1:5)     

ggplot(df, aes(x, y)) +
  geom_point() +
  stat_brace(aes(x=seq_along(x)), rotate=90) +
  coord_cartesian(x=range(seq_along(df$x)), clip = "off") + 
  theme(plot.margin = unit(c(0.5, 7, 0.5, 0.5), units="lines")) #other units would be "cm" etc.