• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Data Viz with Python and R

Learn to Make Plots in Python and R

  • Home
  • Seaborn
  • Matplotlib
  • ggplot2
  • Altair
  • About
    • Privacy Policy
  • Visualizing Activation Functions in Neural Networks
  • Confusion Matrix Calculator
  • Visualizing Dropout Rate in Neural Network
  • Visualizing Loss Functions in Neural Networks
  • Show Search
Hide Search

How To Annotate Clusters with Circle/Ellipse by a Variable in R

datavizpyr · May 28, 2021 ·

In this tutorial, we will learn how to annotate a plot by circle or ellipse based on a categorical variable in the data. We will use ggforce package’s geom_mark_circle() and geom_mark_ellipse() functions to annotate with circles and ellipse. Unlike geom_circle() function to annotate a plot, geom_mark_* functions automatically computes the circle/ellipse radius to draw around the points in a group.

Let us load the packages needed. We will use Palmer penguin dataset to make a scatter plot and annotate it with a circle.

library(tidyverse)
library(palmerpenguins)
theme_set(theme_bw(16))

Here we remove any rows with missing data.

penguins <- penguins %>%
            drop_na()
penguins %>% head()

First, let make a scatterplot using ggplot2’s geom_point().

penguins %>%
  ggplot(aes(x = bill_length_mm,
             y = flipper_length_mm))+
  geom_point(aes(color = species))
ggsave("scatterplot_with_ggplot2.png")
ggplot2 Scatterplot
Scatterplot with ggplot2

Annotate Groups in a scatterplot with circles using geom_mark_circle()

To add circles around cluster or data points belonging to groups, we can add geom_mark_circle() as additional layer. We have used color argument to color the circles based on the value of grouping variable.

penguins %>%
  ggplot(aes(x = bill_length_mm, 
             y = flipper_length_mm))+
  geom_mark_circle(aes(color = species))+
  geom_point(aes(color = species))
ggsave("annotate_clusters_with_circles_ggforce.png")

Note that ggforce has automatically computed the circle radii for each value of the grouping variable and has drawn the circles.

Annotate Clusters by Variable with Circles
Annotate Clusters by Variable with Circles using ggforce

We can customize the size of the circle little bit using “expand” argument to geom_mark_circle(). With expand option, we can see that the circle includes (and touches) the farthest data point for that group.

penguins %>%
  ggplot(aes(x = bill_length_mm,
             y = flipper_length_mm))+
  geom_mark_circle(aes(color=species),
                   expand = unit(0.5,"mm"))+
  geom_point(aes(color = species))
ggsave("annotate_clusters_with_circles_2_ggforce.png")
Annotate Clusters by Variable with Circles
Annotate Clusters by Variable with Circles

Annotate Groups in a scatterplot with ellipses using geom_mark_ellipse()

For this scatterplot annotating by circle does not seem like a that good fit. A better alternative is to annotate the groups by ellipse using ggforce’s geom_mark_ellipse() function. In this example, in addition to adding colors to ellipses, we also label the ellipses with group names. And we use “label.buffer” argument to adjust the location of the labels.

penguins %>%
  ggplot(aes(x = bill_length_mm,
             y = flipper_length_mm))+
  geom_mark_ellipse(aes(color = species,
                        label=species),
                    expand = unit(0.5,"mm"),
                    label.buffer = unit(-5, 'mm'))+
  geom_point(aes(color=species))+
  theme(legend.position = "none")
ggsave("annotate_groups_clusters_with_ellipse_ggplot2.png")
Annotate Groups/Clusters with Ellipse
Annotate Groups/Clusters with Ellipse

We can also use “fill” argument instead of “color” argument inside geom_mark_ellpse() function’s aes() to elevate the annotation with circles.

penguins %>%
  ggplot(aes(x = bill_length_mm,
             y = flipper_length_mm))+
  geom_mark_ellipse(aes(fill = species,
                        label = species),
                    expand = unit(0.5,"mm"),
                    label.buffer = unit(-5, 'mm'))+
  geom_point(aes(color = species))+
  theme(legend.position = "none")
ggsave("annotate_groups_clusters_with_ellipse_labels_fill_ggplot2.png")
Annotate Clusters with Ellipse with Labels ggforce
Annotate Clusters with Ellipse with Labels ggforce

Explore the Complete ggplot2 Guide

35+ tutorials with code: scatterplots, boxplots, themes, annotations, facets, and more—tested and beginner-friendly.

Visit the ggplot2 Hub → No fluff—just code and visuals.

Related posts:

Customizing Labels on Bars in Side by side Stacked BarplotHow To Add Labels to Grouped Barplot with Bars Side-By-Side in R? Customizing Mean mark to boxplot with ggplot2How To Show Mean Value in Boxplots with ggplot2? Scatterplot with marginal multi-histogram with ggExtraHow To Make Scatterplot with Marginal Histograms in R? ggforce geom_circle(): Annotate with a circleHow To Annotate a Plot with Circle in R

Filed Under: ggplot2, R Tagged With: ggplot2, R

Primary Sidebar

Python & R Viz Hubs

  • Seaborn Guide & Cookbook
  • ggplot2 Guide & Cookbook
  • Matplotlib Guide & Cookbook
  • Confusion Matrix Calculator
  • Visualizing Activation Functions
  • Visualizing Dropout
  • Visualizing Loss Functions

Buy Me a Coffee

Copyright © 2026 · Daily Dish Pro on Genesis Framework · WordPress · Log in

Go to mobile version