Tuesday, August 18, 2026

Customizing the Grid/Graticle Labels in QGIS

 To customize your grid/graticle coordinate labels to display with custom text and a unit suffix, you need to use a custom expression in the QGIS Print Layout.

For example, to achieve label format like this “10,000mE”, you will make use of this expression:

format_number(@grid_number, 0) || 'm' || if(@grid_axis = 'x', 'E', 'N')

How This Formula Works

a)    format_number(@grid_number, 0): Automatically adds thousands-separator commas to your coordinate number and removes decimal places.

b)    || 'm': Appends the letter "m" for meters directly to the number.

c)    if(@grid_axis = 'x', 'E', 'N'): Checks if the label belongs to the X-axis (Easting) or Y-axis (Northing) and dynamically attaches the correct E or N directional suffix.


Steps to Use a Custom Expression

a)    Open your Print Layout and select your map frame.

b)    Go to the Item Properties panel on the right.

c)    Scroll down to Grids, select your UTM grid, and click Modify Grid...

d)    Scroll down to Draw Coordinates and ensure the box is checked.

e)    Change the Format dropdown menu from Decimal to Custom.

f)     Click the Expression button (ε) right next to the format dropdown.

 Enter the Custom Formatting Formula

Delete any existing text in the expression box and paste the following formula: format_number(@grid_number, 0) || 'm' || if(@grid_axis = 'x', 'E', 'N')


Common Custom Label Formats

Here are the most common custom label formats used for map grids in QGIS, along with the exact expressions you can paste into the expression editor (ε).

 1. Stripped UTM Grid (Standard Topographic Format)

This format drops the last three trailing zeros (thousands) to keep the map border clean and uncluttered (e.g., 450 instead of 450,000).

  • Example Output: 450
  • Expression: 
substr(to_string(@grid_number), 1, length(to_string(@grid_number)) - 3)

2. Full Kilometers with Suffix

This format converts meter values into kilometers and adds a directional suffix (e.g., 450 km E).

  • Example Output: 450 km E
  • Expression:
(@grid_number / 1000) || ' km ' || if(@grid_axis = 'x', 'E', 'N')

3. Abbreviated Geographic Degrees (Decimal Degrees)

This format rounds standard decimal degrees to a clean precision and adds traditional cardinal directions instead of negative numbers.

  • Example Output: 12.35° N or 74.10° W
  • Expression:
format_number(abs(@grid_number), 2) || '° ' || 
if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))

4. Hybrid Meter/Kilometer Topo Style

This mimics military or official survey maps by showing the full value but making the key thousands digits stand out (e.g., showing just the km value with the remainder as a superscript, formatted here as text).

  • Example Output: 450km (000)
  • Expression:
floor(@grid_number / 1000) || 'km (' || right(to_string(@grid_number), 3) || ')'

5. Clear Text Hemispheres for Lat/Long

This provides a highly readable, non-abbreviated text layout for geographic coordinates.

  • Example Output: Latitude 45.5° North
  • Expression:
if(@grid_axis = 'x', 'Longitude ', 'Latitude ') || 
format_number(abs(@grid_number), 1) || '° ' || 
if(@grid_axis = 'x', if(@grid_number < 0, 'West', 'East'), if(@grid_number < 0, 'South', 'North'))



6. Padding Leading Zeros

Useful for local grid systems where all labels must match a fixed character length for visual alignment.

  • Example Output: 004500
  • Expression:
lpad(to_string(@grid_number), 6, '0')

7. Standard DMS with Directional Suffix (available by default)

This clean, universal format splits the coordinate into degrees (°), minutes ('), and seconds ("), adding a cardinal direction indicator instead of negative math symbols. This format is available by default as "Degree, Minute, Second with Suffix" when you set 'Coordinate Precision' to one decimal place.

  • Example Output: 45° 30' 15" N or 122° 15' 45" W
  • Expression:
with_variable('abs_val', abs(@grid_number),
  floor(@abs_val) || '° ' || 
  floor((@abs_val - floor(@abs_val)) * 60) || char(39) || ' ' || 
  format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 1) || '" ' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)



8. Compact DMS (No Spaces)

Ideal for tight margins or crowded map borders, this removes inner spaces and rounds seconds to the nearest whole integer.

  • Example Output: 45°30'15"N
  • Expression:
with_variable('abs_val', abs(@grid_number),
  floor(@abs_val) || '°' || 
  floor((@abs_val - floor(@abs_val)) * 60) || char(39) || 
  format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 0) || '"' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)




9. Padded DMS (Consistent Character Width)

This expression adds a leading zero to single-digit minutes and seconds. It ensures all labels are exactly the same physical width, preventing jagged alignments along your map frame.

  • Example Output: 05°09'02" S
  • Expression:
with_variable('abs_val', abs(@grid_number),
  lpad(to_string(floor(@abs_val)), 2, '0') || '°' || 
  lpad(to_string(floor((@abs_val - floor(@abs_val)) * 60)), 2, '0') || char(39) || 
  lpad(to_string(format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 0)), 2, '0') || '" ' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)



Happy Mapping

No comments:

Post a Comment