Skip to content

Commit

Permalink
Add image_from_paths/image_from_paths!
Browse files Browse the repository at this point in the history
  • Loading branch information
brenhinkeller committed Dec 26, 2024
1 parent f2a8c32 commit d85bc7e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Images.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
## --- Calculate a 2d path density image from x-y path distributions

"""
```julia
image_from_paths(xpoints::AbstractMatrix, ypoints::AbstractMatrix;
xresolution::Int=1800,
yresolution::Int=1200,
xrange=nanextrema(xpoints),
yrange=nanextrema(ypoints),
)
```
Produce a 2d image (histogram) of path densities given a set of x and y paths
stored column-wise in separate matrices `xpoints` and `ypoints`.
### Examples
```julia
julia> nsims = 1000
1000
julia> xdist = rand(10, nsims);
julia> ydist = rand(10, nsims);
julia> imgcounts, xbincenters, ybincenters = image_from_paths(xpaths, ypaths; xresolution=50, yresolution=50)
([8 15 … 9 11; 12 4 … 14 11; … ; 9 15 … 9 9; 10 17 … 10 14], -3.715247394908744:0.1523101612461508:3.747950506152645, -3.86556932981587:0.1497772964483582:3.4735181961536803)
```
"""
image_from_paths(xpoints, ypoints; xresolution::Int=1800, yresolution::Int=1200, xrange=nanextrema(xpoints), yrange=nanextrema(ypoints)) = image_from_paths!(copy(xpoints), copy(ypoints); xresolution, yresolution, xrange, yrange)
export image_from_paths

function image_from_paths!(xpoints::AbstractMatrix, ypoints::AbstractMatrix; xresolution::Int=1800, yresolution::Int=1200, xrange=nanextrema(xpoints), yrange=nanextrema(ypoints))
@assert axes(xpoints, 1) == axes(ypoints, 1)
nsims = size(xpoints, 2)
@assert axes(xpoints, 2) == axes(ypoints, 2) == Base.OneTo(nsims)

# Interpolate paths to match image resolution
xbinedges = range(first(xrange), last(xrange), length=xresolution+1)
xq = cntr(xbinedges)
ybinedges = range(first(yrange), last(yrange), length=yresolution+1)
yq = cntr(ybinedges)
xinterpdist = Array{Float64}(undef, xresolution, nsims)
for i in Base.OneTo(nsims)
linterp1s!(view(xinterpdist,:,i), view(xpoints, :, i), view(ypoints, :, i), xq)
end
yinterpdist = Array{Float64}(undef, yresolution, nsims)
for i in Base.OneTo(nsims)
linterp1s!(view(yinterpdist,:,i), view(xpoints, :, i), view(ypoints, :, i), yq)
end

# Calculate composite image, scanning both by x and y
imgcounts = zeros(Int, yresolution, xresolution)
for i in Base.OneTo(xresolution) # scan by x (one column at a time)
histcounts!(view(imgcounts,:,i), view(xinterpdist,i,:), ybinedges)
end
for j in Base.OneTo(yresolution) # scan by y (one row at a time)
histcounts!(view(imgcounts,j,:), view(yinterpdist,j,:), xbinedges)
end

return imgcounts, xq, yq
end
export image_from_paths!

## --- Map colormaps to images

"""
Expand Down
13 changes: 13 additions & 0 deletions test/testImages.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
## --- Images.jl

using Random
rng = Xoshiro(1234)

nsims = 1000
xpaths = rand(rng, 10, nsims)
ypaths = rand(rng, 10, nsims)
imgcounts, xq, yq = image_from_paths(xpaths, ypaths; xresolution=50, yresolution=50, xrange=(0,1), yrange=(0,1))

@test sum(imgcounts, dims=1) == [715 999 1107 1268 1424 1502 1624 1636 1810 1837 1858 1925 1970 2041 2112 2059 2114 2139 2175 2175 2193 2200 2237 2265 2217 2169 2242 2303 2257 2225 2236 2187 2127 2130 2121 2060 2023 2015 1948 1870 1858 1755 1731 1643 1476 1410 1250 1103 916 713]
@test sum(imgcounts, dims=2) == [715; 999; 1107; 1268; 1424; 1502; 1624; 1636; 1810; 1837; 1858; 1925; 1970; 2041; 2112; 2059; 2114; 2139; 2175; 2175; 2193; 2200; 2237; 2265; 2217; 2169; 2242; 2303; 2257; 2225; 2236; 2187; 2127; 2130; 2121; 2060; 2023; 2015; 1948; 1870; 1858; 1755; 1731; 1643; 1476; 1410; 1250; 1103; 916; 713;;]
@test xq == 0.01:0.02:0.99
@test yq == 0.01:0.02:0.99

using Colors: Color

cmap = resize_colormap(viridis, 10)
Expand Down

0 comments on commit d85bc7e

Please sign in to comment.