Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datashader #2883

Merged
merged 48 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
71e7981
copy ShadeYourData.jl and make a recipe
jkrumbiegel Apr 21, 2023
4933f31
use points and threads
jkrumbiegel Apr 21, 2023
569afc2
improve performance + add examples
SimonDanisch May 2, 2023
260e67c
avoid aggregation matrix reallocation on every update
jkrumbiegel May 3, 2023
b63a5c6
use on_latest
SimonDanisch May 3, 2023
9cf6566
fix points
SimonDanisch May 3, 2023
757c300
remove unused destructured args
SimonDanisch May 3, 2023
f0dd80b
rearrange thread array and avoid clamp
jkrumbiegel May 4, 2023
653ce7f
remove `@time`
jkrumbiegel May 4, 2023
7a82854
Merge branch 'master' into jk/datashader
SimonDanisch May 9, 2023
57382f5
Merge branch 'jk/datashader' of https://github.com/MakieOrg/Makie.jl …
SimonDanisch May 9, 2023
bb6705f
clean up and documentation
SimonDanisch May 10, 2023
0a15b9b
categorical prototype
SimonDanisch Jun 2, 2023
47aee0d
Merge branch 'master' into jk/datashader
SimonDanisch Aug 17, 2023
be26d65
improve wording
SimonDanisch Aug 17, 2023
e76bf09
clean up + legend for categorical
SimonDanisch Aug 18, 2023
c3176b0
dont use async for output
SimonDanisch Aug 21, 2023
2463441
Merge branch 'master' into jk/datashader
SimonDanisch Aug 21, 2023
901477c
update link to script
SimonDanisch Aug 21, 2023
80eb008
Merge branch 'jk/datashader' of https://github.com/JuliaPlots/Makie.j…
SimonDanisch Aug 21, 2023
0011239
start adding docstrings
SimonDanisch Aug 22, 2023
ae5b366
improve docs and names
SimonDanisch Aug 23, 2023
9a148f8
cleanup
SimonDanisch Aug 23, 2023
a9042ed
fix imports
SimonDanisch Aug 23, 2023
9ad504a
fix docs
SimonDanisch Aug 23, 2023
205f946
address code review by @jkrumbiegel
SimonDanisch Aug 23, 2023
c1f5cc6
make videos autoplay
SimonDanisch Aug 28, 2023
d570a02
fix missing var
SimonDanisch Aug 28, 2023
2ba020e
Merge branch 'master' into jk/datashader
SimonDanisch Aug 29, 2023
63e6861
fix import
SimonDanisch Aug 29, 2023
4e17504
merge master
SimonDanisch Sep 13, 2023
500541c
update docs + support Colorbar
SimonDanisch Sep 13, 2023
eccc033
add test
SimonDanisch Sep 14, 2023
e22e2b0
Merge branch 'master' into jk/datashader
SimonDanisch Sep 18, 2023
ba40f64
clean up
SimonDanisch Sep 18, 2023
ce76931
Merge branch 'jk/datashader' of https://github.com/MakieOrg/Makie.jl …
SimonDanisch Sep 18, 2023
8fd0bb0
remove unused + better stacktrace
SimonDanisch Sep 19, 2023
790ccb7
implement texture resizing for WGLMakie
SimonDanisch Sep 19, 2023
83d1ea1
forgot new
SimonDanisch Sep 19, 2023
d0b483c
don't make legend elements half transparent
SimonDanisch Sep 19, 2023
1c74e41
Hack into JS to get some logs in Julia
SimonDanisch Sep 19, 2023
4d82c31
stringify doesnt work on any object
SimonDanisch Sep 19, 2023
a13e262
try catch!?
SimonDanisch Sep 19, 2023
f8de0d0
did this time out simply because its slow?!
SimonDanisch Sep 19, 2023
fdc363c
bring beck fewer airports
SimonDanisch Sep 19, 2023
5fe4cc2
fix test
SimonDanisch Sep 19, 2023
8e5243f
Merge branch 'master' into jk/datashader
SimonDanisch Sep 19, 2023
969cb0d
add comment
SimonDanisch Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/_assets/datashader-14million.gif
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is huge, should be mp4

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and you can also embed videos such that they auto-play and auto-loop)

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_assets/datashader_2-7_billion.gif
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
169 changes: 169 additions & 0 deletions docs/examples/plotting_functions/datashader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# datashader

{{doc datashader}}

## Examples

### Airports

\begin{examplefigure}{}
```julia
using DelimitedFiles, GLMakie
GLMakie.activate!() # hide
# For saving/showing/inlining into documentation we need to disable async calculation.
Makie.set_theme!(DataShader = (; async_latest=false))
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
airports = Point2f.(eachrow(readdlm(assetpath("airportlocations.csv"))))
fig, ax, ds = datashader(airports,
colormap=[:white, :black],
# use type=Axis, so that Makie doesn't need to infer
# the axis type, which can be expensive for a large amount of points
axis = (; type=Axis),
figure = (; figurepadding=0, resolution=(360*3, 160*3))
)
hidedecorations!(ax); hidespines!(ax)
fig
```
\end{examplefigure}

### Strange Attractors

\begin{examplefigure}{}
```julia
# Taken from Lazaro Alonso in Beautiful Makie:
# https://beautiful.makie.org/dev/examples/generated/2d/datavis/strange_attractors/?h=cliffo#trajectory
Clifford((x, y), a, b, c, d) = Point2f(sin(a * y) + c * cos(a * x), sin(b * x) + d * cos(b * y))

function trajectory(fn, x0, y0, kargs...; n=1000) # kargs = a, b, c, d
xy = zeros(Point2f, n + 1)
xy[1] = Point2f(x0, y0)
@inbounds for i in 1:n
xy[i+1] = fn(xy[i], kargs...)
end
return xy
end

cargs = [[0, 0, -1.3, -1.3, -1.8, -1.9],
[0, 0, -1.4, 1.6, 1.0, 0.7],
[0, 0, 1.7, 1.7, 0.6, 1.2],
[0, 0, 1.7, 0.7, 1.4, 2.0],
[0, 0, -1.7, 1.8, -1.9, -0.4],
[0, 0, 1.1, -1.32, -1.03, 1.54],
[0, 0, 0.77, 1.99, -1.31, -1.45],
[0, 0, -1.9, -1.9, -1.9, -1.0],
[0, 0, 0.75, 1.34, -1.93, 1.0],
[0, 0, -1.32, -1.65, 0.74, 1.81],
[0, 0, -1.6, 1.6, 0.7, -1.0],
[0, 0, -1.7, 1.5, -0.5, 0.7]
]

fig = Figure(resolution=(1000, 1000))
fig_grid = CartesianIndices((3, 4))
cmap = to_colormap(:BuPu_9)
cmap[1] = RGBAf(1, 1, 1, 1) # make sure background is white
for (i, arg) in enumerate(cargs)
# localy, one can go pretty crazy with n,
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
# e.g. 4*(10^7), but we don't want the docbuild to become too slow.
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
points = trajectory(Clifford, arg...; n=10^6)
r, c = Tuple(fig_grid[i])
ax, plot = datashader(fig[r, c], points;
colormap=cmap,
axis=(; type=Axis, title=join(string.(arg), ", ")))
hidedecorations!(ax)
hidespines!(ax)
end
rowgap!(fig.layout,5)
colgap!(fig.layout,1)
fig
```
\end{examplefigure}

### Bigger examples

Timings in the comments are from running this on a 32gb Ryzen 5800H laptop.
Both examples aren't fully optimized yet, and just use raw, unsorted, memory mapped Point2f arrays.
In the future, we'll want to add acceleration structures to optimize access to sub-regions.

#### 14 million point NYC taxi dataset

```julia
using GLMakie, Downloads, Parquet2
bucket = "https://ursa-labs-taxi-data.s3.us-east-2.amazonaws.com"
year = 2009
month = "01"
filename = join([year, month, "data.parquet"], "/")
out = joinpath("$year-$month-data.parquet")
url = bucket * "/" * filename
Downloads.download(url, out)
# Loading ~1.5s
@time begin
ds = Parquet2.Dataset(out)
dlat = Parquet2.load(ds, "dropoff_latitude")
dlon = Parquet2.load(ds, "dropoff_longitude")
# One could use struct array here, but dlon/dlat are
# a custom array type from Parquet2 supporting missing and some other things, which slows the whole thing down.
# points = StructArray{Point2f}((dlon, dlat))
points = Point2f.(dlon, dlat)
end

# ~0.06s
@time begin
f, ax, ds = datashader(points;
colormap=:fire,
axis=(; type=Axis, autolimitaspect = 1),
figure=(;figure_padding=0, resolution=(1200, 600))
)
# make image fill the whole screen
hidedecorations!(ax)
hidespines!(ax)
display(f)
end
```
![](/assets/datashader-14million.gif)

### 2.7 billion OSM GPS points

Download the data from [OSM GPS points](https://planet.osm.org/gps)
and use the script from [drawing-2-7-billion-points-in-10s](https://medium.com/hackernoon/drawing-2-7-billion-points-in-10s-ecc8c85ca8fa) to convert the CSV to a binary blob that we can memory map.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to copy the script to our repo into some examples folder or so


The script needed some updates for the current Julia version
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
that you can find [here](https://gist.github.com/SimonDanisch/c5a92afe63476343e5b6b45be84774b7#file-fast-csv-parse-jl).

```julia
using GLMakie, Mmap
path = "gpspoints.bin"

points = Mmap.mmap(open(path, "r"), Vector{Point2f});
# ~ 26s
@time begin
f, ax, pl = datashader(
points;
# For a big dataset its interesting to see how long each aggregation takes
show_timings = true,
# Use a local operation which is faster to calculate and looks good!
local_post=x-> log10(x + 1),
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
#=
in the code we used to save the binary, we had the points in the wrong order.
A good chance to demonstrate the `point_func` argument,
Which gets applied to every point before aggregating it
=#
point_func=reverse,
SimonDanisch marked this conversation as resolved.
Show resolved Hide resolved
axis=(; type=Axis, autolimitaspect = 1),
figure=(;figure_padding=0, resolution=(1200, 600))
)
hidedecorations!(ax)
hidespines!(ax)
display(f)
end
```
```
aggregation took 1.395s
aggregation took 1.176s
aggregation took 0.81s
aggregation took 0.791s
aggregation took 0.729s
aggregation took 1.272s
aggregation took 1.117s
aggregation took 0.866s
aggregation took 0.724s
```
![](/assets/datashader_2-7_billion.gif)
1 change: 1 addition & 0 deletions src/Makie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ include("basic_recipes/buffers.jl")
include("basic_recipes/bracket.jl")
include("basic_recipes/contours.jl")
include("basic_recipes/contourf.jl")
include("basic_recipes/datashader.jl")
include("basic_recipes/error_and_rangebars.jl")
include("basic_recipes/hvlines.jl")
include("basic_recipes/hvspan.jl")
Expand Down
Loading