Skip to content

Commit

Permalink
datashader fixes for AggMean (#4346)
Browse files Browse the repository at this point in the history
* store `value` not intermediate aggregator in pixelbuffer

* add reference tests

* fix bb method for 3d points

* add mean example to docs

* add changelog

* fix and spruce up docs example

* Update examples2d.jl

* Update examples2d.jl

* change interpolate to false by default and add note to docstring

---------

Co-authored-by: Simon <[email protected]>
  • Loading branch information
jkrumbiegel and SimonDanisch authored Oct 15, 2024
1 parent 0033b7d commit 7cb44c7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Changed image, heatmap and surface picking indices to correctly index the relevant matrix arguments. [#4459](https://github.com/MakieOrg/Makie.jl/pull/4459)
- Improved performance of `record` by avoiding unnecessary copying in common cases [#4475](https://github.com/MakieOrg/Makie.jl/pull/4475).
- Fix usage of `AggMean()` and other aggregations operating on 3d data for `datashader` [#4346](https://github.com/MakieOrg/Makie.jl/pull/4346).

## [0.21.14] - 2024-10-11

Expand Down Expand Up @@ -49,7 +50,7 @@
- `plotfunc()` and `func2type()` support functions ending with `!` [#4275](https://github.com/MakieOrg/Makie.jl/pull/4275).
- Fixed Boundserror in clipped multicolor lines in CairoMakie [#4313](https://github.com/MakieOrg/Makie.jl/pull/4313)
- Fix float precision based assertions error in GLMakie.volume [#4311](https://github.com/MakieOrg/Makie.jl/pull/4311)
- Support images with reversed axes [#4338](https://github.com/MakieOrg/Makie.jl/pull/4338)
- Support images with reversed axes [#4338](https://github.com/MakieOrg/Makie.jl/pull/4338)

## [0.21.9] - 2024-08-27

Expand Down
26 changes: 26 additions & 0 deletions ReferenceTests/src/tests/examples2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,32 @@ end
f
end

@reference_test "Datashader AggCount" begin
data = [RNG.randn(Point2f, 10_000); (Ref(Point2f(1, 1)) .+ 0.3f0 .* RNG.randn(Point2f, 10_000))]
f = Figure()
ax = Axis(f[1, 1])
datashader!(ax, data; async = false)
ax2 = Axis(f[1, 2])
datashader!(ax2, data; async = false, binsize = 3)
ax3 = Axis(f[2, 1])
datashader!(ax3, data; async = false, operation = xs -> log10.(xs .+ 1))
ax4 = Axis(f[2, 2])
datashader!(ax4, data; async = false, point_transform = -)
f
end

@reference_test "Datashader AggMean" begin
with_z(p2) = Point3f(p2..., cos(p2[1]) * sin(p2[2]))
data2d = RNG.randn(Point2f, 100_000)
data3d = map(with_z, data2d)
f = Figure()
ax = Axis(f[1, 1])
datashader!(ax, data3d; agg = Makie.AggMean(), operation = identity, async = false)
ax2 = Axis(f[1, 2])
datashader!(ax2, data3d; agg = Makie.AggMean(), operation = identity, async = false, binsize = 3)
f
end

@reference_test "Heatmap Shader" begin
data = Makie.peaks(10_000)
data2 = map(data) do x
Expand Down
17 changes: 17 additions & 0 deletions docs/src/reference/plots/datashader.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ hidedecorations!(ax); hidespines!(ax)
fig
```

### Mean aggregation

The `AggMean` aggregation type requires `Point3`s where the mean is taken over the z values of all points that fall into the same x/y bin.

```@figure backend=GLMakie
with_z(p2) = Point3f(p2..., cos(p2[1]) * sin(p2[2]))
points = randn(Point2f, 100_000)
points_with_z = map(with_z, points)
f = Figure()
ax = Axis(f[1, 1], title = "AggMean")
datashader!(ax, points_with_z, agg = Makie.AggMean(), operation = identity)
ax2 = Axis(f[1, 2], title = "AggMean binsize = 3")
datashader!(ax2, points_with_z, agg = Makie.AggMean(), operation = identity, binsize = 3)
f
```

### Strange Attractors

```@figure backend=GLMakie
Expand Down
22 changes: 14 additions & 8 deletions src/basic_recipes/datashader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ function Canvas(bounds::Rect2; resolution::Tuple{Int,Int}=(800, 800), op=AggCoun
xsize, ysize = resolution
n_elements = xsize * ysize
o0 = null(op)
v0 = value(op, o0)
aggbuffer = fill(o0, n_elements)
pixelbuffer = fill(o0, n_elements)
pixelbuffer = fill(v0, n_elements)
# using ReshapedArray directly like this is not advised, but as it lives only briefly it should be ok
return Canvas(Rect2{Float64}(bounds), resolution, op, aggbuffer, pixelbuffer, (o0, o0))
return Canvas(Rect2{Float64}(bounds), resolution, op, aggbuffer, pixelbuffer, (v0, v0))
end

n_threads(::AggSerial) = 1
Expand All @@ -116,9 +117,10 @@ end
function change_op!(canvas::Canvas, op::AggOp)
op == canvas.op && return false
o0 = null(op)
v0 = value(op, o0)
if eltype(canvas.aggbuffer) != typeof(o0)
canvas.aggbuffer = fill(o0, size(c.aggbuffer))
canvas.pixelbuffer = fill(o0, size(c.pixelbuffer))
canvas.pixelbuffer = fill(v0, size(c.pixelbuffer))
end
return true
end
Expand Down Expand Up @@ -334,8 +336,11 @@ For best performance, use `method=Makie.AggThreads()` and make sure to start jul
show_timings = false
"""
If the resulting image should be displayed interpolated.
Note that interpolation can make NaN-adjacent bins also NaN in some backends, for example
due to interpolation schemes used in GPU hardware. This can make it look
like there are more NaN bins than there actually are.
"""
interpolate = true
interpolate = false
MakieCore.mixin_generic_plot_attributes()...
MakieCore.mixin_colormap_attributes()...
end
Expand All @@ -344,13 +349,14 @@ function fast_bb(points, f)
N = length(points)
NT = Threads.nthreads()
slices = ceil(Int, N / NT)
results = fill(Point2f(0), NT, 2)
results = fill(Point2d(0), NT, 2)
R = eltype(points) isa Point2 ? Rect2d : Rect3d
Threads.@threads for i in 1:NT
start = ((i - 1) * slices + 1)
stop = min(length(points), i * slices)
pmin, pmax = extrema(Rect2f(view(points, start:stop)))
results[i, 1] = f(pmin)
results[i, 2] = f(pmax)
pmin, pmax = extrema(R(view(points, start:stop)))
results[i, 1] = f(Point2d(Point3d(pmin)))
results[i, 2] = f(Point2d(Point3d(pmax)))
end
return Rect3f(Rect2f(vec(results)))
end
Expand Down

0 comments on commit 7cb44c7

Please sign in to comment.