Author MakieOrg
9 Stars
Updated Last
7 Months Ago
Started In
January 2023


Stable Dev Build Status Coverage

Plot an interactive canvas of GeometryBaseics Point, LineString or Polygon, or an ms-paint style canvas for any numerical or color Array. These can be overlayed and activated/deactivated to have multiple drawing task on the same Axis.


Drawing into a DynamicGrids.jl game of life simulation

Example use cases

  • GeometryCanvas can be used to manually crreate GeoInterface.jl compatible FeatureCollections (and even add metadata columns for each geometry), which can be done over a heatmap or other spatial plot. A GeometryCanvas can be written directly to disk with GeoJSON.jl or Shapefile.jl.
  • GeometryCanvas can also be used to edit any GeoInterface.jl compatible geometries and feature collections.
  • PaintCanvas can be used to manually edit matrices of any kind that Makie can plot. You could make Bool mask layers over maps or other images, edit categorical images, or just draw some retro pictures on a Matrix{RGB}.
  • MakieDraw could also be used for live interaction, such as using PaintCanvas as a mask or aux layer in DynamicGrids.jl simulations.

Or try this example over Tyler.jl tiles:

using MakieDraw
using GLMakie
using GeoJSON
using GeometryBasics
using GeoInterface
using TileProviders
using Tyler
using Extents
provider = Google(:satelite)

figure = Figure()
axis = Axis(figure[1:10, 1:10])
tyler = Tyler.Map(Extent(Y=(-27.0, 0.025), X=(0.04, 38.0)); 
    figure, axis, provider=Google()
categories = Observable(Int[])
point_canvas = GeometryCanvas{Point}(; 
  figure, axis, properties=(; categories), mouse_property=:categories,
  scatter_kw=(; color=categories, colorrange=(0, 2), colormap=:spring)

line_canvas = GeometryCanvas{LineString}(; figure, axis)[] = true[] = true

poly_canvas = GeometryCanvas{Polygon}(; figure, axis)

layers = Dict(

MakieDraw.CanvasSelect(fig[11, 1], axis; layers)

# Write the polygons to JSON
# Have to convert here because GeometryBasics `isgeometry` has a bug, see PR #193
polygons = GeoInterface.convert.(Ref(GeoInterface), poly_canvas.geoms[])
mp = GeoInterface.MultiPolygon(polygons)
GeoJSON.write("multipolygon.json", mp)

# Reload and edit again
polygons = collect(GeoInterface.getgeom("multipolygon.json"))))
tyler = Tyler.Map(Extent(Y=(-27.0, 0.025), X=(0.04, 38.0)); provider)
fig = tyler.figure;
axis = tyler.axis;
poly_canvas = GeometryCanvas(polygons; figure, axis)

GeometryCanvas keys:

Left click to add, grab or drag points, right click to remove them.

Shift + left click starts new lines and polygons.

PaintCanvas keys:

Left click draws with fill_left, right click draws with fill_right.