Algorithms
SwarmMakie aims to offer several beeswarm algorithms, which give different results. You can change the algorithm which SwarmMakie uses by passing it as a keyword argument algorithm, or mutating plot.algorithm after the fact.
Currently, it offers the SimpleBeeswarm and WilkinsonBeeswarm algorithms, which are inspired by Matplotlib and Leland Wilkinson's original paper respectively, and a no-op NoBeeswarm algorithm which simply decomposes back to the original data.
In addition, SwarmMakie offers jittered scatter plots as algorithms to beeswarm. These aren't exactly beeswarm plots since they don't guarantee that all points are non-overlapping, but they can still be useful to show distributions, especially for larger numbers of points where all points cannot fit into a beeswarm. These algorithms are accessible as UniformJitter, PseudorandomJitter, and QuasirandomJitter, similar to ggbeeswarm's options.
Comparison
Here's a comparison of all the available algorithms:
using SwarmMakie, CairoMakie
algorithms = [NoBeeswarm() SimpleBeeswarm() WilkinsonBeeswarm(); UniformJitter() PseudorandomJitter() QuasirandomJitter()]
fig = Figure(; size = (800, 450))
xs = rand(1:3, 400); ys = randn(400)
ax_plots = [beeswarm(fig[Tuple(idx)...], xs, ys; color = xs, algorithm = algorithms[idx], markersize = 3, axis = (; title = string(algorithms[idx]))) for idx in CartesianIndices(algorithms)]
jitter_plots = getproperty.(ax_plots[2, :], :plot)
setproperty!.(jitter_plots, :markersize, 7)
setproperty!.(jitter_plots, :alpha, 0.3)
fig
Documentation
SwarmMakie.SimpleBeeswarm Type
SimpleBeeswarm()A simple implementation like Matplotlib's algorithm.
This algorithm dodges in x but preserves the exact y coordinate of each point. If you don't want to preserve the y coordinate, check out WilkinsonBeeswarm.
SwarmMakie.SimpleBeeswarm2 Type
SimpleBeeswarm2()A simple beeswarm implementation, that minimizes overlaps. This is the default algorithm used in beeswarm.
This algorithm dodges in x but preserves the exact y coordinate of each point. If you don't want to preserve the y coordinate, check out WilkinsonBeeswarm.
SwarmMakie.WilkinsonBeeswarm Type
WilkinsonBeeswarm()A beeswarm algorithm that implements Leland Wilkinson's original dot-hist algorithm.
This is essentially a histogram with dots, where all dots are binned in the y (non-categorical) direction, and then dodged in the x (categorical) direction.
Original y-coordinates are not preserved, and if you want that try SimpleBeeswarm instead.
SwarmMakie.NoBeeswarm Type
A simple no-op algorithm, which causes the scatter plot to be drawn as if you called scatter and not beeswarm.
Code exists for the algorithm suggested by Michael Borregaard in this StatsPlots.jl PR, but it is currently nonfunctional. If you'd like to take a crack at getting it working, please do!
SwarmMakie.UniformJitter Type
UniformJitter(; jitter_width = 1.0)A jitter algorithm that uses a uniform distribution to create the jitter.
sourceSwarmMakie.PseudorandomJitter Type
PseudorandomJitter(; jitter_width = 1.0)A jitter algorithm that uses a pseudorandom distribution to create the jitter. A pseudorandom distribution is a uniform distribution weighted by the PDF of the data.
sourceSwarmMakie.QuasirandomJitter Type
QuasirandomJitter(; jitter_width = 1.0)A jitter algorithm that uses a quasirandom (van der Corput) distribution weighted by the data's pdf to jitter the data points.
sourceWe also welcome any new algorithms you may have in mind. Just open a PR!
Adding a new algorithm
In order to add a new algorithm, you must simply define a struct which subtypes SwarmMakie.BeeswarmAlgorithm.
There must also be a corresponding dispatch on SwarmMakie.calculate!(buffer, alg, positions, markersize) which loads the new positions calculated in pixel space into buffer. Note that buffer must be modified here.
See the Wilkinson source page for a deep dive into how to write a beeswarm algorithm!