Customized xticklabels with GeoMakie?

I’d like to plot some maps using GeoMakie.jl, but I would like to modify the default xticks.
I tried several approaches : via a formatter xtickformat or via manually annotating the figure. None of those works… The attribute seems to be completely ignored and with the second option the text get clipped (even though I used the ax.scene strategy that would in theory solve this…).

Do you have any idea of a possible solution that could be implemented in the scritp (if no, I still have the possibility to edit the figure on Inkscape) ?

MWE
using GeoMakie, CairoMakie
using LaTeXStrings

lon_formatter(x) = x < 0 ? L"%$(-x)^\circ\mathrm{W}" : L"%$(x)^\circ\mathrm{E}"
lat_formatter(y) = y < 0 ? L"%$(-y)^\circ\mathrm{S}" : L"%$(y)^\circ\mathrm{N}"

# Function to create a single PC plot
function plot_single_map(fig, position; kwargs...)
	# Normalized PC data
	data = randn(96, 73) # fake data for testing

	# Create GeoAxis
	ax = GeoAxis(fig[position...],
		source = "+proj=latlong",
		# dest = "+proj=wintri",
		xticks = collect(-180.0:90.0:180.0),
		yticks = collect(-90.0:45.0:90.0),
		xgridcolor = (:black, 0.5),
		ygridcolor = (:black, 0.5);
		kwargs...,
	)

	lon = range(-180, 180, length = size(data, 1))
	lat = range(-90, 90, length = size(data, 2))

	sdata = reshape(data, :, 1) |> vec
	mask = isfinite.(sdata) .& (.!ismissing.(sdata))
	slon = reshape(repeat(lon, outer = length(lat)), :, 1) |> vec
	slat = reshape(repeat(lat, inner = length(lon)), :, 1) |> vec
	scatter!(ax, slon[mask], slat[mask],
		color = sdata[mask],
		colormap = :balance,
		colorrange = (-5, 5),
		marker = :rect,
		markersize = 5,
	)

	return ax
end

fig = let
	fig = Figure(
		size = (800, 800),
		figure_padding = (0, 0, -50, -50),
		# backgroundcolor = :transparent,
	)
	ga = fig[1, 1] = GridLayout()

	axes = []
	positions = [(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2)]
	for i in 1:6
		ax = plot_single_map(
			ga,
			positions[i];
			xtickformat = xvals -> [lon_formatter(x) for x in xvals],
			# xticklabelsvisible = false,
			# yticklabelsvisible = false,
		)
		# Usin ax.scene, that should avoid the clipping:
		text!(ax.scene, Point2f(0.5, 0.15), text = "Test", align = (:center, :top),
			fontsize = 40, space = :relative)
		push!(axes, ax)
	end
	rowgap!(ga, -150) # reduce white space between rows
	colgap!(ga, -10) # reduce white space between columns
	resize_to_layout!(fig) # probably useless
	fig
end
# save("GeoMakie.png", fig) # or pdf for paper
Resulting image

pkg> st GeoMakie CairoMakie
Status `[...]/Project.toml`
  [13f3f980] CairoMakie v0.15.6
  [db073c08] GeoMakie v0.7.15

Hey, thanks for the additional report. I think xtick handling broke at some point, will try to restore that this weekend!

1 Like

Great, thanks !

On the other hand, I was still puzzled by the fact that using text!(ax.scene, ...) was cropped and I finally understood that the reason is just because of the scene size.
Could this size be increased while keeping the rest of the plot identical ?

If not, I managed to get a working solution, that involves adding

    # Create overlay for text
	overlay_ax = Axis(fig[1, 1],
		backgroundcolor = :transparent,
		limits = (0, 1, 0, 1),
		xgridvisible = false, ygridvisible = false,
		topspinevisible = false, bottomspinevisible = false,
		leftspinevisible = false, rightspinevisible = false,
		xticksvisible = false, yticksvisible = false,
		xticklabelsvisible = false, yticklabelsvisible = false,
	)

	# Add text using relative coordinates
	text_positions = [ax.scene.viewport[].origin for ax in axes]

	for (i, pos) in enumerate(text_positions)
		@show pos
		text!(overlay_ax, pos...,
			text = "Test $i",
			fontsize = 40,
			color = :red,
			align = (:center, :center),
			space = :pixel,
		)
	end

However, this is not ideal. Indeed, if I want to add a text at a given lon lat, I have to find myself the needed pixel translation from the bottom left corner of the scene. Given that annotation! support entering the lon lat value, I guess there must be a way to extract the pixel position ?