I have 100 values that I would like to visualise in a certain way.
sorted <- sort(rnorm(100000))
dots <- c(rep(0, 100))
for (i in (1:100)){
dots[i] <- sorted[i*1000-500]
}
plot(data.frame(dots, 1))
However, this has many small circles that overlap one another. Therefore I would like to move the circles up and down (not sideways) in such a way that they do not overlap anymore. In fact, I would like that the circles don’t even touch each other. (So, some kind of minimal distance is required.) Moreover, I would like keep everything as close to the original as possible. (I’m not looking for some random jitter.)
Something that looks like this (although this example is not perfectly optimised):
This calls for some kind of optimisation, that I suspect might already be provided in some existing library.
The question: Which library could have such a routine?
>Solution :
Thanks for adding the expected output; that looks to me like a beeswarm plot, e.g.
# install.packages("beeswarm")
library(beeswarm)
sorted <- sort(rnorm(100000))
dots <- c(rep(0, 100))
for (i in (1:100)){
dots[i] <- sorted[i*1000-500]
}
beeswarm(data.frame(dots),
horizontal = TRUE)

Created on 2024-02-05 with reprex v2.1.0
With the ‘original’ dots in red for comparison:
beeswarm(data.frame(dots),
horizontal = TRUE)
# add the original points
points(data.frame(dots, 1.1), col = "red")

Created on 2024-02-05 with reprex v2.1.0
If you look into the beeswarm package (https://rdrr.io/cran/beeswarm/man/beeswarm.html) there are different methods you can use (method = c("swarm", "compactswarm", "center", "hex", "square")) and different priorities (priority = c("ascending", "descending", "density", "random", "none")). You can also change the spacing so that the dots don’t touch, but beware that the spacing can change the x pos as well as the y pos. Regardless, you should be able to adjust your plot to get your desired outcome.

