GeoMakie.jl

repository·master·Indexed 42 days ago

https://github.com/makieorg/geomakie.jl

A Julia package for plotting geospatial data on map projections within the Makie.jl ecosystem. It provides GeoAxis for handling Coordinate Reference Systems (CRS) via PROJ-strings and includes utilities for plotting coastlines, landmasses, and earth images using standard Makie plotting functions.

Tokens
5K
Snippets
14
Records
26
Agent score
49%

What's inside GeoMakie

  1. What is GeoMakie.jl?

    master
    GeoMakie.jl is a Julia package for plotting geospatial data on map projections, built on top of the Makie.jl ecosystem. It provides the GeoAxis type, which handles Coordinate Reference Systems (CRS) and projections. GeoAxis is designed to be a drop-in replacement for Makie.Axis and works seamlessly with standard Makie plotting functions.
  2. Configure metadata for example cards using @cardmeta

    master

    GeoMakie uses a custom @cardmeta block to generate metadata for the documentation gallery. This metadata is used to render cover images, titles, and descriptions in the HTML grid.

    To ensure Documenter.jl processes this correctly, you must wrap the @cardmeta block in a Julia comment block (#= ... =#). This prevents Documenter.jl from attempting to execute the metadata as code while allowing the custom GeoMakie build stage to parse it.

    Place this block at the bottom of your Julia file.

    #=
    ```@cardmeta
    Cover = fig
    Description = "A very short description of the example"
    Title = "Some title, optional"

    =#

  3. Choose between vector and raster data for plotting

    master

    When working with geographic data in GeoMakie, you must choose the appropriate plotting method based on whether your data is vector or raster:

    Vector Data

    Vector data uses points and line segments to identify locations. It is typically plotted using:

    • lines
    • scatter
    • poly

    Raster Data

    Raster data uses a series of cells to represent locations. It is typically plotted using:

    • surface
    • meshimage
    • heatmap
    • image (specifically for GeoMakie.earth)
  4. Understand nonlinear transformations in GeoMakie

    master

    GeoMakie distinguishes between different types of coordinate transformations to manage how data is mapped to the screen. Understanding these helps in predicting how shapes, lines, and bounding boxes will behave.

    Key Terminology

    • Data space (Input space): The coordinate system of your raw data (e.g., Longitude/Latitude).
    • Transformed space: The coordinate system after the transformation is applied, which can then be mapped to pixel space.

    Categories of Transformations

    1. Affine: Transformations like translation, scale, and rotation. These are treated as linear; straight lines in data space remain straight in transformed space.
    2. Nonlinear but separable: Each coordinate in the transformed space depends only on its corresponding coordinate in the input space (e.g., applying a log or log10 scale to axes). The $x$ transformation does not affect $y$.
    3. Nonlinear and inseparable: The transformed $x$ and $y$ coordinates depend on both input $x$ and $y$ coordinates. Geographic projections (like those used with GeoAxis) are the primary example of this.
  5. How to handle longitudinal wrapping in surface and contour plots

    master

    When using surface or contour plots, the longitudinal dimension may "wrap" around the planet, causing errors because each data point is transformed individually.

    To resolve this, you should:

    1. Change the central longitude of the map transformation using the lon_0 parameter in the dest PROJ-string.
    2. Use circshift to shift your data (lons and the field) so they align with the new central longitude.

    Below is a recommended implementation for a cshift helper function to perform this adjustment.

    # Helper to shift data to a new central longitude
    function cshift(lons, field, lon_0)
       shift = @. lons - lon_0 > 180
       nn = sum(shift)
       (circshift(lons - 360shift, nn), circshift(field, (nn, 0)))
    end
    
    # Usage example:
    lons = -180:180
    lats = -90:90
    field = [exp(cosd(l)) + 3(y/90) for l in lons, y in lats]
    
    lon_0 = -160
    (lons_shift, field_shift) = cshift(lons, field, lon_0)
    
    fig = Figure()
    ax = GeoAxis(fig[1,1]; dest = "+proj=eqearth +lon_0=$(lon_0)")
    surface!(ax, lons_shift, lats, field_shift, colormap=:balance)
    lines!(ax, GeoMakie.coastlines(ax), color=:black, overdraw = true)
    fig
  6. Core components of GeoMakie

    master

    GeoMakie extends the Makie.jl plotting ecosystem with three primary capabilities for geographic data visualization:

    1. Geographic Projections: Integration with Proj.jl to define and use various geographic projections.
    2. GeoAxis: A specialized nonlinear axis designed specifically for geographic coordinate systems.
    3. Geographic Utilities: A collection of helper tools for plotting geographic features such as coastlines and earth images.
  7. Use GeoAxis for geospatial plotting

    master

    GeoMakie provides GeoAxis, a specialized axis for plotting geospatial data on map projections. It integrates with the Makie.jl ecosystem, allowing you to use standard plotting functions like surface!, scatter!, poly!, and contour! on a geographic coordinate system.

    using GeoMakie, CairoMakie
    
    lons = -180:180
    lats = -90:90
    field = [exp(cosd(l)) + 3(y/90) for l in lons, y in lats]
    
    fig = Figure()
    ax = GeoAxis(fig[1,1])
    surface!(ax, lons, lats, field; shading = NoShading)
    fig
  8. Identify valid data regions in complex projections

    master

    In certain projections (like orthographic), the valid range of data in transformed space does not map to a simple rectangle in input space. To find which input points (e.g., lon/lat) are actually visible/valid in the transformed space, you can use Makie.apply_transform on the axis's transform_func and check for finite results.

    Warning: Standard bounding boxes in input space may be either too small (missing parts of the data) or too large (including invalid/infinite regions) when dealing with these projections.

    # Example: Checking validity of points in an orthographic projection
    # ga is a GeoAxis instance
    lons = LinRange(-180, 180, 500)
    lats = LinRange(-90, 90, 500)
    
    valid_points = [isfinite(Makie.apply_transform(ga.transform_func[], Point2f(lon, lat))) for lon in lons, lat in lats]
    
    # valid_points can then be used in a heatmap to visualize the valid domain
    heatmap(lons, lats, valid_points)
  9. Install GeoMakie.jl

    master

    You can install GeoMakie via the Julia REPL using the add command. Note that the package is currently in development and the interface may change.

    ]add GeoMakie
  10. Add a new demo or example to GeoMakie

    master

    To add a new demo or example to the GeoMakie documentation, follow these steps:

    1. Create the file: Add a Julia file to the appropriate subfolder within the examples/ directory.
    2. Register in the gallery: Add the filename to the overview gallery blocks in docs/src/examples.md.
    3. Whitelist the file: Add the filename to the whitelist array in docs/src/make.jl.

    Requirements for the Julia file:

    • Use Literate.jl syntax.
    • The file must start with a level-1 heading (# Title) as the title.
    • Every stage of the code must return a FigureLike object.
    • Include a @cardmeta block at the bottom of the page (see metadata requirements below).
    • Ensure comments are of sufficient quality to explain the code to newcomers.
  11. Quick start with GeoAxis

    master

    The primary entry point is GeoAxis(fig[i, j]; kw_args...). It creates an axis that accepts nonlinear projections via PROJ-strings. By default, the source CRS is "+proj=longlat +datum=WGS84". You can specify the destination projection using the dest keyword argument.

    To plot data, use standard Makie functions like lines!, scatter!, surface!, etc., passing the GeoAxis instance as the first argument.

    using CairoMakie, GeoMakie
    
    fig = Figure()
    ga = GeoAxis(
        fig[1, 1]; # any cell of the figure's layout
        dest = "+proj=wintri", # the CRS in which you want to plot
    )
    # plot coastlines from Natural Earth as a reference
    lines!(ga, GeoMakie.coastlines())
    
    # Plot data using standard Makie syntax
    scatter!(ga, -120:15:120, -60:7.5:60; color = -60:7.5:60, strokecolor = (:black, 0.2))
    fig
  12. Plotting scalar fields and images in GeoAxis

    master

    The recommended way to plot data depends on your Makie backend:

    CairoMakie

    Use image!(ax, ...) or heatmap!(ax, ...) for images or scalar fields.

    GLMakie

    image! and heatmap! do not work in GLMakie and will result in an empty axis. Instead, use surface! with an interval range to sample the grid:

    • For an image img: surface!(ga, lonmin..lonmax, latmin..latmax, ones(size(img)...); color = img, shading = NoShading)
    • For a scalar field: surface!(ga, lonmin..lonmax, latmin..latmax, field)

    Note: The .. notation creates a Makie interval that is automatically sampled to provide the x and y points.