Yes, it's possible to do this in one of several ways. Unless you have an svg file of a 7-sided polygon available, one quick solution would be to define this shape as a grob
and plot it using geom_grob
from package ggpmisc
. This keeps things in vector format.
Creating the heptagon is the hard part:
library(ggplot2)
library(dplyr)
library(grid)
library(ggpmisc)
# Make heptagon
septs <- seq(0, 2 * pi, length.out = 8)
devratio <- dev.size()[2]/dev.size()[1]
heptagon <- linesGrob(x = unit(0.5 + 0.2 * devratio * sin(septs), "npc"),
y = unit(0.5 + 0.2 * cos(septs), "npc"),
gp = gpar(lwd = 2))
The plot itself is straightforward:
# Plot 10 random points with the heptagon
set.seed(69)
tibble(x = rnorm(10), y = rnorm(10), shape = list(heptagon)) %>%
ggplot() +
geom_grob(aes(x, y, label = shape))

As you can see from this example, custom shapes aren't necessarily all that easy to use, since the shape has to be defined pointwise by the user, it is difficult to match its size and lineweight to existing points, and the user would have to define what/where their fill is, etc. I don't think it's an omission from ggplot to not have a simple interface for creating custom shapes - ggplot has great extensibility for advanced users, and it's not clear that you could have a useful shape-creating interface for beginners. Meanwhile there are more than enough shapes to provide informative plots for all but the most niche applications.