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!