Skip to content

Commit

Permalink
Get simple algorithm kind of working
Browse files Browse the repository at this point in the history
  • Loading branch information
asinghvi17 committed Mar 9, 2024
1 parent 46f0ce2 commit b7ce228
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
39 changes: 36 additions & 3 deletions src/algorithms/simple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,44 @@ struct SimpleBeeswarm <: BeeswarmAlgorithm
end

function calculate!(buffer::AbstractVector{<: Point2}, alg::SimpleBeeswarm, positions::AbstractVector{<: Point2}, markersize)
@info "Calculating..."
ys = last.(positions)
ymin, ymax = extrema(ys)
nbins = (ymax - ymin) ÷ markersize
nbins = round(Int, (ymax - ymin) ÷ markersize)
dy = markersize
ybins = LinRange(ymin+dy, ymax-dy, nbins-1) # this is a center list of bins
i = eachindex(ys)
return
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
mask .= (!).(mask)
idxs = idxs[mask]
ys = ys[mask]
end

# Add the remaning elements to the last bin
push!(bin_idxs, idxs)
push!(bin_vals, ys)

nmax = maximum(length, bin_idxs)

xs = zeros(eltype(ys), size(positions))
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) % 2
resorted_b_idxs = b_idxs[sortperm(b_vals)]
a = resorted_b_idxs[begin:2:end]
b = resorted_b_idxs[(begin+1):2:end]
xs[a] .= ((1:length(a))) .* markersize
xs[b] .= ((1:length(b))) .* (-markersize)
end
end
buffer .= Point2f.(xs, last.(positions))
end
19 changes: 9 additions & 10 deletions src/recipe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function Makie.plot!(plot::Beeswarm)
# Note that this only works for 2-D Scenes, and gets us the transformed space limits,
# so if you're trying to run this in a scene with a `transform_func`, that's something to
# be aware of.
finalwidths = lift(scene.camera.projectionview) do pv
final_widths = lift(scene.camera.projectionview) do pv
isnothing(pv) && return Vec2f(0)
xmin, xmax = minmax((((-1, 1) .- pv[1, 4]) ./ pv[1, 1])...)
ymin, ymax = minmax((((-1, 1) .- pv[2, 4]) ./ pv[2, 2])...)
Expand All @@ -52,17 +52,17 @@ function Makie.plot!(plot::Beeswarm)
# and its viewport (in case the scene changes size)
pixel_widths = @lift widths($(scene.viewport))
old_pixel_widths = Ref(pixel_widths[])
old_finalwidths = Ref(finalwidths[])
old_finalwidths = Ref(final_widths[])

should_update_based_on_zoom = Observable{Bool}(true)
onany(plot, finalwidths, pixel_widths) do fw, pw # if we change more than 5%, recalculate.
onany(plot, final_widths, pixel_widths) do fw, pw # if we change more than 5%, recalculate.
if !all(isapprox.(fw, old_finalwidths[]; rtol = 0.05)) || !all(isapprox.(pw, old_pixel_widths[]; rtol = 0.05))
old_pixel_widths[] = pw
old_finalwidths[] = fw
notify(should_update_based_on_zoom)
end
end
notify(finalwidths)
notify(final_widths)


# set up buffers
Expand All @@ -73,25 +73,24 @@ function Makie.plot!(plot::Beeswarm)
onany(plot, plot.converted[1], plot.algorithm, plot.color, plot.markersize, should_update_based_on_zoom) do positions, algorithm, colors, markersize, _
if length(positions) != length(point_buffer[])
# recreate point buffer if lengths have changed
point_buffer.val = zeros(Point2f, length(positions))
point_buffer.val = copy(positions)
pixelspace_point_buffer.val = zeros(Point2f, length(positions))
# color_buffer.val = zeros(RGBA{Float32}, length(positions))
end
pixelspace_point_buffer.val .= Makie.project.((scene.camera, ), :data, :pixel, positions)
calculate!(point_buffer.val, algorithm, pixelspace_point_buffer.val, markersize)
point_buffer.val .= Makie.project.((scene.camera,), :pixel, :data, pixelspace_point_buffer.val)
point_buffer.val .= Makie.project.((scene.camera,), :pixel, :data, point_buffer.val)
# color_buffer.val .= colors # TODO: figure out some way to make this better.

# update the scatter plot
notify(point_buffer)
end
# create a set of Attributes that we can pass down
attrs = copy(plot.attributes)
pop!(attrs, :algorithm)
pop!(attrs, :space)
# pop!(attrs, :space)
# attrs[:color] = color_buffer
attrs[:space] = :data
attrs[:markerspace] = :pixel
# attrs[:space] = :data
# attrs[:markerspace] = :pixel
# create the scatter plot
scatter_plot = scatter!(
plot,
Expand Down

0 comments on commit b7ce228

Please sign in to comment.