It is an interesting yet hard exercise. geom_density2d
is just plotting lines based on point densities, according to certain parameters (bins = 5
). You can approximate
the "center of mass" of your points using spatial analysis:
library(ggplot2)
set.seed(1)
df <- data.frame(x = rnorm(50), y = rnorm(50))
# Spatial analysis
library(sf)
library(raster)
# Your points as spatial
points <- st_as_sf(df, coords=c("x", "y"))
# Create a raster (grid 100x100)
rast <- raster(points, ncols=10, nrows=10)
# Count the number of points on each pixel
rasterized <- rasterize(points, rast, fun="count")
plot(rasterized)

So with that we have detected which pixel (square) has more points, hence this square has the higher density of points. Now we can extract the coordinates of that pixel and plot that:
df_points <- as.data.frame(rasterized, xy=TRUE, na.rm=TRUE)
cent <- df_points[df_points$layer == max(df_points$layer), ]
cent$label <- "centroid?"
ggplot() +
geom_density2d(data = df, aes(x, y), color = "#ff0000", bins = 5) +
geom_point(data=cent, aes(x, y, color=label)) +
scale_color_manual(values="green") +
# For contrast only
geom_sf(data=points, alpha=0.15) +
theme(
axis.title = element_blank(),
panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(size = 0.5, linetype = "solid", colour = "black"), panel.background = element_rect(fill = "white", colour = "white", size = 10, linetype = "solid"), text = element_text(family = "sans")
)

The point on cent
is not the centroid of the contour plot, but represent where the higher concentration of points can be located.
You can also compute the mean of your coordinates...
ggplot() +
geom_density2d(data = df, aes(x, y), color = "#ff0000", bins = 5) +
geom_point(aes(mean(df$x), mean(df$y))) +
# For contrast only
geom_sf(data=points, alpha=0.15) +
theme(
axis.title = element_blank(),
panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(size = 0.5, linetype = "solid", colour = "black"), panel.background = element_rect(fill = "white", colour = "white", size = 10, linetype = "solid"), text = element_text(family = "sans")
)
Hope that helps!