# Plotting countries with GeoMakie: reduce size and more

**URL:** <https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966>\
**Category:** Visualization\
**Tags:** geo, makie\
**Created:** [April 26, 2023, 7:52pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966 "2023-04-26T19:52:07Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 26, 2023, 7:52pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/1 "2023-04-26T19:52:07Z")

</div>

I am trying visualize some specific countries with [GeoMakie.jl](https://github.com/MakieOrg/GeoMakie.jl).  
I 've seen [Examples · GeoMakie.jl](https://geo.makie.org/stable/examples/#Italy's-states) and I tried to do something similar:

```julia
begin
	# Acquire data
	ger_states = Downloads.download("https://raw.githubusercontent.com/isellsoap/deutschlandGeoJSON/main/2_bundeslaender/4_niedrig.geo.json")
	geoger = GeoJSON.read(read(ger_states, String))

	fra_states = Downloads.download("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/regions.geojson")
	geofra = GeoJSON.read(read(fra_states, String))
	
	fig = Figure()
	ga = GeoAxis(fig[1, 1]; source = "+proj=longlat +datum=WGS84", dest = "+proj=lcc +lon_0=2 +lat_1=10 lat_2=20", lonlims=(12, 13), latlims = (30, 44), title="Simulation topology", coastlines=true)
	poly!(ga, geoger; strokewidth = 1, color=:lightblue)
	poly!(ga, geofra; strokewidth = 1, color=:royalblue)
	datalims!(ga)

	save("gerfratop.pdf", fig)
	fig
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/0/2031006bfbe70eb438d85daf5cffadacc8837708.jpeg)

It would be great if you could help me refine this figure a bit. Following are my problems:

1. My biggest problem is that this figure is 43MB. As a result, it’s not very usable. Is there a way to reduce the size to the KB range ? Maybe somehow sample the found `geometry` in the json files ?
2. The details of the coastlines are too coarse. How can I increase it to make it much the shapefiles used ? Also the coastlines shouldn’t escape the frame.
3. How can I paint the sea ?
4. Bottom right the latitude text is cut in half and it’s a bit ugly.
5. How can I also add lakes, and a sketch of the neighboring countries borders (without the inner states). Do I need to find the corresponding shapefile for each one of them, or can it be automated (similar to the coastilines, which uses the Natural Earth dataset) ? I tried doing

```julia
worldCountries = GeoJSON.read(read(Downloads.download("https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json"), String))
poly!(ga, worldCountries; color= :grey)

```

…but it didn’t ended up as desired:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/4/14488372874dabfae3e71ea3ee619b08562e0a6a.jpeg)

The style I am aiming to achieve is something similar to the following but for both France and Germany (ignore the overlaid graph).

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/3/83346d53fd7258479ffd5a184b6c59c323883549.png)

Thanks a lot in advance !

> **Reproducibility**
>
> Julia v1.8.5 and GeoMakie 0.5.0

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [April 26, 2023, 8:24pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/2 "2023-04-26T20:24:05Z")

</div>

If you want to try GMT, you can:  
Note image is a bit ugly due to another ghostscript bug in version 10 (versions 9.xx work fine). Using `pdf` as output workaround the issue. `png` file size ~500 KB.  
(EDIT: high quality pdf = 263 KB)

```julia
using GMT

julia> ger_states = gmtread("https://raw.githubusercontent.com/isellsoap/deutschlandGeoJSON/main/2_bundeslaender/4_niedrig.geo.json");
        This file has islands (holes in polygons).
        Use `gmtread(..., no_islands=true)` to ignore them.

julia> fra_states = gmtread("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/regions.geojson");
        This file has islands (holes in polygons).
        Use `gmtread(..., no_islands=true)` to ignore them.

julia> coast(proj="+proj=lcc +lon_0=2 +lat_1=10 +lat_2=20", region=(-5,15,41,55), coast=0.5, water=:lightgreen)
julia> plot!(ger_states, lc=:black, fill=:blue)
julia> plot!(fra_states, lc=:black, fill=:lightblue, show=1)

```

 ![GMTjl_j](https://global.discourse-cdn.com/julialang/original/3X/3/e/3e6f8d06d8b869d4ce645ebb8e742a4a38f10398.png)

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [April 26, 2023, 10:53pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/3 "2023-04-26T22:53:51Z")

</div>

Yeah, GMT’s land-sea mask probably has a lot of the details you’re aiming for.

From a GeoMakie perspective, it’s going through a major refactor right now, so things should change in a couple of weeks or so.

1. To get the file size to be smaller, set the `rasterize` attribute in your `poly` plots. `rasterize = 5` or so should be pretty smooth, and will basically render the polygons to an image and then plot that image instead of plotting the polygons directly. This is theoretically not “true vector” but is good for most usecases, since printers can’t get that level of accuracy anyway.

2. To get smoother coastlines, you can use [natural-earth-vector/ne\_10m\_coastline.geojson at master · nvkelso/natural-earth-vector · GitHub](https://github.com/nvkelso/natural-earth-vector/blob/master/geojson/ne_10m_coastline.geojson) from Natural Earth. You would have to plot this yourself though. I am working on getting more natural earth data into GeoMakie but that will take some time, see e.g. [https://github.com/NaturalEarth.jl](https://github.com/NaturalEarth.jl)

3. You could use the land-sea-river mask from [GitHub - JuliaGeo/GeoDatasets.jl: Common geographic data sets](https://github.com/JuliaGeo/GeoDatasets.jl) to paint the sea.

4. In general the tick label spacing was always a bit buggy. We came up with a nice method to figure out tick label spacing at MakieCon, so I will try and get a patch out which uses that soonish.

5. For lakes, you can use [natural-earth-vector/ne\_10m\_lakes\_europe.geojson at master · nvkelso/natural-earth-vector · GitHub](https://github.com/nvkelso/natural-earth-vector/blob/master/geojson/ne_10m_lakes_europe.geojson). For neighbouring countries, your current approach works. However, when plotting the country outlines, set `xautolimits=false, yautolimits=false`. This will make sure that those plots aren’t taken into account when checking the limits!

Hope these help. I will try to get a patch out for the tick labels soonish.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [April 26, 2023, 11:03pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/4 "2023-04-26T23:03:02Z")

</div>

> [@asinghvi17](#):
>
> GMT’s land-sea mask probably has a lot of the details

Just to clarify this, it’s not a mask. It’s a pure vector operation (polygon painting in postscript). That is why the PDF version is so small ~260 KB)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [April 27, 2023, 5:52am UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/5 "2023-04-27T05:52:52Z")

</div>

Are the polygons rendering as meshes again in this example? Otherwise Makie should also just export them as plain polys in pdf files, keeping the size small. Some types revert to mesh drawing though, maybe this is happening here. That blows up the filesize and can be fixed in cairomakie.

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [April 28, 2023, 1:06pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/6 "2023-04-28T13:06:29Z")

</div>

Definitely possible…@filchristou, which version of CairoMakie are you using? You can find out by:

```julia
using Pkg
Pkg.status("CairoMakie")

```

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 28, 2023, 3:37pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/7 "2023-04-28T15:37:26Z")

</div>

Thanks for the answers. I will work my way through them and I will update you!

I am using CairoMakie 0.10.4

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 28, 2023, 6:50pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/8 "2023-04-28T18:50:34Z")

</div>

@asinghvi17

1. `rasterize=5` appears to work okey; Now I am not sure how to check what @jules is saying.

2. I tried it but I am getting some errors with `axisautolimits=false` similar to this issue I made [{x,y}autolimits=false breaks example · Issue #166 · MakieOrg/GeoMakie.jl · GitHub](https://github.com/MakieOrg/GeoMakie.jl/issues/166) . Also plotting is quite slow. Can I somehow filter only the region I am interested in, so that I don’t wait for the plotting of the whole earth ?

3. The following appears to work, but again quite slow for high quality.  
Also I would prefer a solution with `poly!` as it’s messy handling it as a field.

4. ok. I will completely remove this information. However, I couldn’t remove the grid and I made an issue [make grid invisible · Issue #167 · MakieOrg/GeoMakie.jl · GitHub](https://github.com/MakieOrg/GeoMakie.jl/issues/167)

5. Lakes appears to be located wrong. I made an issue [wrong coordinate transformation ? German lakes · Issue #168 · MakieOrg/GeoMakie.jl · GitHub](https://github.com/MakieOrg/GeoMakie.jl/issues/168)

So what I have now is the following:

```julia
begin
	allcountries = GeoJSON.read(read(Downloads.download("https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_10m_admin_0_countries.geojson"), String))

	geoger = GeoJSON.read(read(Downloads.download("https://raw.githubusercontent.com/isellsoap/deutschlandGeoJSON/main/2_bundeslaender/4_niedrig.geo.json"), String))
	
	geofra = GeoJSON.read(read(Downloads.download("https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/regions.geojson"), String))

	lakes = GeoJSON.read(read(Downloads.download("https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_10m_lakes_europe.geojson"), String))

	lontemp,lantemp,dattmep = GeoDatasets.landseamask(;resolution='l',grid=5)
	clamp!(dattmep, 0x00, 0x01)
end

mymapfig = let
	fig = Figure()
	
	ga = GeoAxis(fig[1, 1]; dest = "+proj=merc", lonlims=(12, 13), latlims = (30, 44), title="Simulation topology", xgridvisible=false, ygridvisible=false, xticklabelsvisible=false, yticklabelsvisible=false, xticksvisible=false, yticksvisible=false)

	contourf!(ga, lontemp, lantemp, dattmep; colormap=ColorScheme(range(colorant"lightblue", colorant"lightgrey", length=2)), xautolimits=false, yautolimits=false)
	poly!(ga, allcountries; color= :grey, xautolimits=false, yautolimits=false, rasterize=5)
	poly!(ga, geoger; strokewidth = 1, color=:gold, rasterize=5)
	poly!(ga, geofra; strokewidth = 1, color=:peru, rasterize=5)
	poly!(ga, lakes; strokewidth = 1, color=:blue, rasterize = 5, xautolimits=false, yautolimits=false)
	
	datalims!(ga)
	
	fig
end

```

it produces this 2.7MB fig:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/a/2a6783a59a42b15890b8e3d9a8a5fd3b7bd5fb58.jpeg)

Remarks:  
i) lakes are positioned wrongly  
ii) grind lines are visible  
iii) there is still some white between the gray countries and the blue see. I guess this is due to using different datasets.  
iv) I still need land boundaries. I didn’t find a geojson file in the natural earth repo. However there are many boundaries [here](https://github.com/nvkelso/natural-earth-vector/tree/master/10m_cultural) with formats like \*.cpg, \*.dbf, \*.prj, \*.shp, \*.shx. Is there a way to read any of them and use them with GeoMakie ?  
v) generation is slow. I think there are some low-hanging fruits by filtering the coordinates only to the frame we are interested into (?)

@joa-quim thanks for the solution. GMT looks powerful and mature, but I need GeoMakie here because on top I intend to use some GraphMakie recipes.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [April 28, 2023, 7:01pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/9 "2023-04-28T19:01:35Z")

</div>

Sure, it’s your choice. But I can’t understand how the above even works because this

> [@filchristou](#):
>
> `"+proj=merc", lonlims=(12, 13), latlims = (30, 44),`

is completely wrong (and I don’t think the figure is in Mercator projection).

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 29, 2023, 7:55am UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/10 "2023-04-29T07:55:42Z")

</div>

I think because I `{x,y}autolimits` are automatically set to true, GeoMakie adapts the axis for both german and french topology. However I need to supploy something like `lonlims=(12, 13), latlims = (30, 44)` in the signature because it’s a required argument.

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [May 17, 2023, 8:14pm UTC](https://discourse.julialang.org/t/plotting-countries-with-geomakie-reduce-size-and-more/97966/11 "2023-05-17T20:14:56Z")

</div>

Hmm…I got this kinda working, it looks like the huge file size is a result of a wrong dispatch in CairoMakie

 ![Screenshot 2023-05-17 at 4.11.50 PM](https://global.discourse-cdn.com/julialang/original/3X/b/8/b8df152cf8b44ee042b1e183fe5a1b1d0cdceeab.png)

The generated PDF is 430 KB, so not bad. This is on an experimental branch and has quite a few other issues as well, but I just wanted to check that the aspect ratio seems correct? If so I can actually try and update the master version of geoaxis with this.
