Skip to content

Commit

Permalink
Add more examples + a basic metadata framework (#233)
Browse files Browse the repository at this point in the history
* Update index.md

* Add a histogram example

Datashader won't work, but this is a good approximation

* Fix link in the rasters example

* Enable plotting MultiLineStrings

* Update the contour example to show all features

* Better theming for contour example

* Add the "annotation" and "Hurricane Katrina" examples from Cartopy

More to come soon

* Bugfixes for docs

* Remove individual activations from examples

* First foray into example card block

* Fully implement the example meta block

* Clean up make.jl

* add the Cartopy example for Vesta

* Fix the projection in is_it_a_plane

* Templates for new examples

* Change docs to the new way of doing things

* Add arrows example

* add params and data to vestaa3d

* add TopoPlots to docs/Project

* Fix errors in the examples

* set RDS_PATH in makedocs also

* actually deploy docs

* add ImageTransformations to the project

for `imresize` mainly.

* Fix cardmeta blocks not being commented

This sounds like a mistake I will keep making :D

* Add a streamplot example on geoaxis
  • Loading branch information
asinghvi17 authored Jun 8, 2024
1 parent 905c607 commit dc70cc3
Show file tree
Hide file tree
Showing 40 changed files with 536 additions and 100 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@ jobs:
Pkg.instantiate()'
env:
DISPLAY: ':0'
DATADEPS_ALWAYS_ACCEPT: 'true'
RASTERDATASOURCES_PATH: '~/.julia/artifacts/RasterDataSources'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # If authenticating with GitHub Actions token
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # If authenticating with SSH deploy key
DISPLAY: ':0'
DATADEPS_ALWAYS_ACCEPT: 'true'
RASTERDATASOURCES_PATH: '~/.julia/artifacts/RasterDataSources'
run: xvfb-run -s '-screen 0 1024x768x24' julia --project=docs/ docs/make.jl deploy
8 changes: 7 additions & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ Animations = "27a7e980-b3e6-11e9-2bcd-0b925532e340"
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
CoordinateTransformations = "150eb455-5306-5404-9cee-2592286d6298"
DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
DelaunayTriangulation = "927a84f5-c5f4-47a5-9785-b46e178433df"
DemoCards = "311a05b2-6137-4a5a-b473-18580a3d38b5"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
FHist = "68837c9b-b678-4cd5-9925-8a54edc8f695"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
FlyThroughPaths = "c11bb9a7-2755-425a-88f3-ebe93bbdb91f"
GADM = "a8dd9ffe-31dc-4cf5-a379-ea69100a8233"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
GMT = "5752ebe1-31b9-557e-87aa-f909b540aa54"
Expand All @@ -23,6 +27,8 @@ GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
GeometryOps = "3251bfac-6a57-4b6d-aa61-ac1fef2975ab"
GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
LibGEOS = "a90b1aa1-3769-5649-ba7e-abc5a9d163eb"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Expand All @@ -35,11 +41,11 @@ Proj = "c94c279d-25a6-4763-9509-64d165bea63e"
RasterDataSources = "3cb90ccd-e1b6-4867-9617-4276c8b2ca36"
Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4"
TopoPlots = "2bdbdf9c-dbd8-403f-947b-1a4e0dd41a7a"
WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea"

[compat]
Documenter = "1"
Makie = "0.21"
MakieThemes = "0.1.1"
# Rasters = ">= 0.11"
78 changes: 78 additions & 0 deletions docs/example_meta_block.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Documenter
using ImageTransformations # for resize

abstract type CardMetaBlocks <: Documenter.Expanders.ExpanderPipeline end

# Order doesn't really matter, because the expansion is done based on page location first.
Documenter.Selectors.order(::Type{CardMetaBlocks}) = 12.0
Documenter.Selectors.matcher(::Type{CardMetaBlocks}, node, page, doc) = Documenter.iscode(node, r"^@cardmeta")

GALLERY_DICT = Dict{String, Any}()

function Documenter.Selectors.runner(::Type{CardMetaBlocks}, node, page, doc)
# Bail early if in draft mode
if Documenter.is_draft(doc, page)
@debug "Skipping evaluation of @example block in draft mode:\n$(x.code)"
Documenter.create_draft_result!(node; blocktype="@example")
return
end

# Literate.jl uses the page filename as an "environment name" for the example block,
# so we need to extract that from the page. The code in the meta block has
# to be evaluated in the same module in order to have access to local variables.
page_name = first(splitext(last(splitdir(page.source))))
page_link_path = first(splitext(relpath(page.build, doc.user.build)))

meta = Dict{Symbol, Any}()

global GALLERY_DICT
GALLERY_DICT[page_link_path] = meta

# The sandboxed module -- either a new one or a cached one from this page.
current_mod = Documenter.get_sandbox_module!(page.globals.meta, "atexample", page_name)

x = node.element
lines = Documenter.find_block_in_file(x.code, page.source)
@debug "Evaluating @cardmeta block:\n$(x.code)"
# @infiltrate

for (ex, str) in Documenter.parseblock(x.code, doc, page)
# If not `isassign`, this might be a comment, or any code that the user
# wants to hide. We should probably warn, but it is common enough that
# we will silently skip for now.
if Documenter.isassign(ex)
if !(ex.args[1] in (:Title, :Description, :Cover, :Authors, :Date))
source = Documenter.locrepr(page.source, lines)
@warn(
"In $source: `@cardmeta` block has an unsupported " *
"keyword argument: $(ex.args[1])",
)
end
try
meta[ex.args[1]] = Core.eval(current_mod, ex.args[2])
catch err
Documenter.@docerror(doc, :meta_block,
"""
failed to evaluate `$(strip(str))` in `@cardmeta` block in $(Documenter.locrepr(page.source, lines))
```$(x.info)
$(x.code)
```
""", exception = err)
end
end
end

# TODO: get defaults
# How?
# Title: get the first heading node on the page as DocumenterVitepress does
# Description: empty string as default
# Cover: no image as default
# Author: Default should be hardcoded to `["Anshul Singhvi"](https://github.com/asinghvi17)`
# Date: nothing, don't include it if nothing

# Authors and Date are for the transformer and can be applied within this block, the first four
# params need to go to the gallery/card object though.

node.element = Documenter.MetaNode(x, page.globals.meta)

end
38 changes: 23 additions & 15 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,44 @@ using Documenter, DocumenterVitepress, Literate
using GeoMakie, CairoMakie, Makie, GeoInterfaceMakie

include("gallery_setup.jl")
include("example_meta_block.jl")
# Set some global settings
# Good quality CairoMakie with PNG
CairoMakie.activate!(px_per_unit = 3, type = :png)
CairoMakie.activate!(px_per_unit = 2, type = :png)
# Rasters should download into the artifacts folder (so they can be cached :D)
ENV["RASTERDATASOURCES_PATH"] = joinpath(first(Base.DEPOT_PATH), "artifacts")
# invoke some geomakie things to be sure it works
GeoMakie.coastlines()
GeoMakie.earth()

deploy = length(ARGS) == 1 && ARGS[1] == "deploy"
if deploy && !haskey(ENV, "GITHUB_TOKEN")
@warn("Not deploying, no GITHUB_TOKEN not found in ENV")
deploy = false
end

using Literate

examples = [
"basic.jl",
"new.jl",
"axis_config.jl",
"italy.jl",
"histogram.jl",
"contours.jl",
"world_population.jl",
"graph_on_usa.jl",
"orthographic.jl",
"german_lakes.jl",
"geostationary_image.jl",
"multiple_crs.jl",
"rasters.jl",
"is_it_a_plane.jl",
joinpath("cartopy", "annotation.jl"),
joinpath("cartopy", "katrina.jl"),
joinpath("cartopy", "arrows.jl"),
joinpath("cartopy", "vesta.jl"),
joinpath("cartopy", "streamplot.jl"),
joinpath("gmt", "antioquia.jl"),
"contourf.jl",
"world_population.jl",
"german_lakes.jl",
"field_and_countries.jl",
"meshimage.jl",
"projections.jl",
"tissot.jl",
"rotating_earth.jl",
"rasters.jl",

]
example_dir = joinpath(dirname(@__DIR__), "examples")
for filename in examples
Expand Down Expand Up @@ -72,8 +73,18 @@ Documenter.makedocs(;
sitename="GeoMakie.jl",
authors="Anshul Singhvi and the Makie.jl contributors",
warnonly = true,
draft = false,
)


deploydocs(;
repo="github.com/MakieOrg/GeoMakie.jl",
target="build",
push_preview = true,
forcepush = true
)


# publicpath = joinpath(@__DIR__, "build", ".documenter", "public")
# mkpath(publicpath)
# mv(joinpath(@__DIR__, "build", ".documenter", "examples", "covers"), joinpath(publicpath, "covers"))
Expand All @@ -92,9 +103,6 @@ Documenter.makedocs(;

# isdir(joinpath(@__DIR__, "src", "examples")) && rm.(readdir(joinpath(@__DIR__, "src", "examples"); join = true); force = true)

deploy && deploydocs(; repo="github.com/MakieOrg/GeoMakie.jl", target="build", push_preview=true, forcepush = true)


# "Examples" => [
# "Basic examples" => "examples/basic.md",
# "New API" => "examples/new.md",
Expand Down
20 changes: 11 additions & 9 deletions docs/src/adding_demos.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ Functional requirements are:
- At each stage, return a `FigureLike`. You can simply dispose of things for it to work...


When adding the code to save to `covers`, you must add the following exactly:
```julia
#
# make cover image #jl
mkpath("covers") #hide
save("covers/$(splitext(basename(@__FILE__))[1]).png", fig) #hide
nothing #hide
```
When adding the code to save to `covers`, you must add the following code to the bottom of your Julia file:
````julia
# ```@cardmeta
# Cover = fig
# Description = "A very short description of the example"
# Title = "Some title, optional"
# ```
````
assuming `fig` is the main figure of that example.

The first comment is important, so that there is a separation between the code block above this one, and this one. Otherwise, the last figure will not be displayed!
Note that all of this code is commented out - this is important, otherwise Documenter.jl will not be able to pick it up.

You can even pass a compound expression as `Cover = begin ... end` if you want to create a custom cover figure. This will all be evaluated in the same scope as your example, but after all the code is executed.

We also require that the comments in the file be of sufficient quantity and quality to explain what is going on to a newcomer.
7 changes: 3 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ features:
title: Pure Julia code
details: Fast, understandable, extensible functions
link: /introduction
- icon: <img width="64" height="64" src="https://fredrikekre.github.io/Literate.jl/v2/assets/logo.png" />
title: Literate programming
details: Documented source code with examples!
link: /source/methods/clipping/cut
- icon: <img width="64" height="64" src="https://rawcdn.githack.com/JuliaGeo/juliageo.github.io/4788480c2a5f7ae36df67a4b142e3a963024ac91/img/juliageo.svg" />
title: Full integration with GeoInterface
details: Use any GeoInterface.jl-compatible geometry
link: https://juliageo.org/GeoInterface.jl/stable
- title: Projections via Proj.jl
details: Plot in any projection, with data coming from any projection!
link: /examples/multiple_crs
---
Expand Down
12 changes: 8 additions & 4 deletions examples/basic.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# # Basic examples

using GeoMakie, CairoMakie # you could use GLMakie too

lons = -180:180
lats = -90:90

# Create some field of values across `lons` and `lats`
# This grid can be of any density, but note that the
# time it takes to plot scales with the grid size!
Expand Down Expand Up @@ -31,7 +33,9 @@ scatter!(slons, slats; color = sfield)
fig
# Again, to save, run e.g. `save("scatter_example.png", fig; px_per_unit=2)`.
#
# make cover image #jl
mkpath("covers") #hide
save("covers/$(splitext(basename(@__FILE__))[1]).png", fig) #hide
nothing #hide

# ```@cardmeta
# Title = "Basic examples"
# Description = "Basic examples of GeoMakie"
# Cover = fig
# ```
34 changes: 34 additions & 0 deletions examples/cartopy/annotation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# # Annotated plot
# This example is translated from [this Cartopy example](https://scitools.org.uk/cartopy/docs/latest/gallery/lines_and_polygons/feature_creation.html#sphx-glr-gallery-lines-and-polygons-feature-creation-py).

using CairoMakie, GeoMakie, Makie
using Makie: GeometryBasics
using NaturalEarth

states_fc = naturalearth("admin_1_states_provinces_lines", 50)


fig = Figure()
ga = GeoAxis(fig[1, 1]; limits = ((80, 170), (-45, 30)), dest = "+proj=longlat +datum=WGS84")
image!(ga, -180..180, -90..90, GeoMakie.earth() |> rotr90; interpolate = false)
poly!(ga, GeoMakie.land(); color = :lightyellow, strokecolor = :black, strokewidth = 1)
lines!(ga, GeoMakie.to_multilinestring.(states_fc.geometry); color = :gray)
fig
# Now to add the annotation:
const DATASOURCE = "Natural Earth"
const LICENSE = "public domain"
annotation_text = text!(
ga.scene, Point2f(0.05, 0.05); # plotting in relative coordinates - (0, 0) is bottom left, (1, 1) is top right
space = :relative, text = "© $DATASOURCE ($LICENSE)"
)
fig

_pad_rect(rect, padding::Real) = Rect(rect.origin .- padding, rect.widths .+ 2 * padding)
text_bbox = Makie.boundingbox(last(plots(ga.scene)))

annotation_box = poly!(ga.scene, _pad_rect(text_bbox, 4); space = :pixel, color = :white, strokecolor = :black, strokewidth = 2)
annotation_box.transformation.transform_func[] = identity
translate!(annotation_text, 0, 0, 110)
translate!(annotation_box, 0, 0, 109)
fig

38 changes: 38 additions & 0 deletions examples/cartopy/arrows.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# # Gridded arrows
# This example was taken from the [Cartopy gridded arrow example].

# The big idea is to plot arrows from one CRS in another!

using GeoMakie, CairoMakie

xs = LinRange(311.9, 391.1, 30)
ys = LinRange(-23.6, 24.8, 20)

us = @. 1 * (2 * cos(2 * deg2rad(xs) + 3 * deg2rad(ys' + 30)) ^ 2)
vs = @. 2 * cos(6 * deg2rad(xs)) .+ ys' * 0 # that last part is just to establish the shape

pole_longitude=177.5
pole_latitude=37.5
arrow_crs = "+proj=ob_tran +o_proj=latlon +o_lon_p=0 +o_lat_p=$(pole_latitude) +lon_0=$(180+pole_longitude) +to_meter=$(deg2rad(1) * 6378137.0)"

f, a, p = arrows(
xs, ys, us, vs;
arrowsize = 4,
source = arrow_crs,
axis = (; type = GeoAxis, dest = "+proj=ortho +lon_0=-10 +lat_0=45")
)
# Now we plot the background:
ep = surface!(a,
-180..180, -90..90,
zeros(axes(rotr90(GeoMakie.earth())));
shading = NoShading, color = rotr90(GeoMakie.earth())
)
translate!(ep, 0, 0, -1)
f

# ```@cardmeta
# Title = "Arrows"
# Description = "Gridded arrows"
# Cover = f
# ```

8 changes: 8 additions & 0 deletions examples/cartopy/aurora.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Plotting the aurora

aurora_colormap = cgrad(
[RGBAf(0.1725, 0.9294, 0.3843, 0), RGBAf(0.1725, 0.9294, 0.3843, 1), RGBAf(0.8353, 0.8235, 0.6549)],
[0, 0.5, 1];
categorical = false
)

Loading

0 comments on commit dc70cc3

Please sign in to comment.