Simple beeswarm 
julia
export SimpleBeeswarmThis is a simple beeswarm implementation as used in Matplotlib.
julia
"""
    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`.
"""
struct SimpleBeeswarm <: BeeswarmAlgorithm
end
function calculate!(buffer::AbstractVector{<: Point2}, alg::SimpleBeeswarm, positions::AbstractVector{<: Point2}, markersize, side::Symbol)
    @debug "Calculating..."
    ys = last.(positions)
    xs = first.(positions)
    for x_val in unique(xs)
        group = findall(==(x_val), xs)
        view_ys = view(ys, group)
        if isempty(view_ys)
            continue
        else
            ms = if markersize isa Number
                markersize
            else
                view_ms = view(markersize, group)
                maximum(view_ms)
            end
            xs[group] .= simple_xs(view_ys, ms, side)
        end
    end
    buffer .= Point2f.(xs .+ first.(positions), last.(positions))
end
function simple_xs(ys, markersize, side)
    n_points = length(ys)
    ymin, ymax = extrema(ys)
    nbins = round(Int, (ymax - ymin) ÷ markersize)
    if nbins ≤ 2
        nbins = 3
    end
    dy = markersize
    ybins = LinRange(ymin+dy, ymax-dy, nbins-1) # this is a center list of bins
    idxs = eachindex(ys)
    bin_idxs = Vector{Vector{Int}}()
    bin_vals = Vector{Vector{eltype(ys)}}()
    for (j, ybin) in enumerate(ybins)
        mask = ys .< ybin
        push!(bin_idxs, idxs[mask])
        push!(bin_vals, ys[mask])Remove the points that are already in the bin
julia
        mask .= (!).(mask)
        idxs = idxs[mask]
        ys = ys[mask]
    endAdd the remaning elements to the last bin
julia
    push!(bin_idxs, idxs)
    push!(bin_vals, ys)nmax = maximum(length, bin_idxs)
julia
    xs = zeros(eltype(ys), n_points)
    for (b_idxs, b_vals) in zip(bin_idxs, bin_vals)
        if length(idxs) < 1 # if only 1 element exists, continue
            continue
        else
            j = length(b_idxs) % 2Resort the indices in the bin by y-value, which allows us to ensure that all markers in the bin are monotonically increasing in the y direction as they go farther from the center.
julia
            resorted_b_idxs = b_idxs[sortperm(b_vals)]
            if side == :bothSplit the bin in two parts, evenly split.
julia
                a = resorted_b_idxs[begin:2:end]
                b = resorted_b_idxs[(begin+1):2:end]Populate the x-array.
julia
                xs[a] .= ((1:length(a))) .* markersize .- markersize/2
                xs[b] .= ((1:length(b))) .* (-markersize) .+ markersize/2
            elseif side == :leftPopulate the x-array.
julia
                xs[resorted_b_idxs] .= ((1:length(resorted_b_idxs))) .* markersize .- markersize/2
            elseif side == :rightPopulate the x-array.
julia
                xs[resorted_b_idxs] .= ((1:length(resorted_b_idxs))) .* (-markersize) .+ markersize/2
            end
        end
    end
    return xs
endThis page was generated using Literate.jl.