Hi,
I’ve been exploring GMT.jl again lately (thanks to Joaquim for this amazing package and his responses to my questions on github) and I thought I would put this here for reference, since I didn’t find so many examples out there. In the following Julia code I will show two methods for plotting a memory-resident data matrix (in this case just coordinates) on a global basemap. I will use GeoJSON formatted tectonic plate boundary data saved in the file plate_boundaries.json
(in the same directory as the Julia script).
The first method uses Julia’s Cmd
syntax to run the external gmt
binary. This is unsurprisingly much slower than using GMT.jl (second method). The trick with GMT.jl is to use the mat2ds
function to convert the matrix to a GMTdataset
which is an allowed object type for the GMT.jl functions. It was much simpler than I had thought – I was overcomplicating things a lot until I found this function. Note that there is an even simpler method on the latest GMT.jl master using gmtread in this case, see comment below. Here goes:
using BenchmarkTools # https://github.com/JuliaCI/BenchmarkTools.jl
using DelimitedFiles
using GMT
using GeoJSON # https://github.com/JuliaGeo/GeoJSON.jl
function read()
# Although GMT.jl can "read" GeoJSON via `gmtread("plate_boundaries.json", data = true)`,
# the JSON string is not parsed into native data types.
# I didn't really want to write a GeoJSON parser, and luckily it's already available!
boundaries = open("plate_boundaries.json") do file
geo2dict(GeoJSON.read(file))
end
return boundaries
end
function gmtcall()
run(`gmt begin plate_boundaries`)
run(`gmt psbasemap -Rg -JR14c -Baf -BWSen`)
boundaries = read()
for data in boundaries["features"]
open(`gmt plot -Wthinner,black`, write = true) do io
writedlm(io, reduce(hcat, data["geometry"]["coordinates"]) |> transpose |> collect)
end
end
run(`gmt end`)
end
function gmtjl()
boundaries = read()
basemap(region = :g, projection = :Winkel)
for data in boundaries["features"]
plot!(
mat2ds(reduce(hcat, data["geometry"]["coordinates"]) |> transpose |> collect),
pen = (:thinner, :black),
)
end
end
function main()
# Benchmarking in global scope is discouraged, so we do it in here.
@btime gmtcall() # ~ 9.6s and 21 MiB
@btime gmtjl() # ~ 0.4s and 20 MiB
end
main()
If you can see any obvious flaws with this code, please don’t hesitate to point them out! I’m quite new to both Juila and GMT…
Well, that’s all for now. Thanks to everyone who is working on GMT software