Skip to content

Add degrees and decimal minutes tick formatting mode - #2740

Open
DavidVadnais wants to merge 1 commit into
SciTools:mainfrom
DavidVadnais:fix-issue#944
Open

DavidVadnais wants to merge 1 commit into
SciTools:mainfrom
DavidVadnais:fix-issue#944

Conversation

@DavidVadnais

Copy link
Copy Markdown
Contributor

Rationale

Fixes: #944

Example code

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter

fig, axes = plt.subplots(1, 3, subplot_kw={'projection': ccrs.PlateCarree()},
                         figsize=(18, 5))

ax = axes[0]
ax.set_extent([-161, -154, 18, 23], crs=ccrs.PlateCarree())
ax.coastlines()
ax.set_xticks([-161, -159.51, -158, -156.3, -155, -154], crs=ccrs.PlateCarree())
ax.set_yticks([18, 19.51, 21, 22.3, 23], crs=ccrs.PlateCarree())
ax.xaxis.set_major_formatter(LongitudeFormatter(dms='dm'))
ax.yaxis.set_major_formatter(LatitudeFormatter(dms='dm'))
ax.set_title("dms='dm' (default format)")

ax = axes[1]
ax.set_extent([-161, -154, 18, 23], crs=ccrs.PlateCarree())
ax.coastlines()
ax.set_xticks([-161, -159.51, -158, -156.3, -155, -154], crs=ccrs.PlateCarree())
ax.set_yticks([18, 19.51, 21, 22.3, 23], crs=ccrs.PlateCarree())
ax.xaxis.set_major_formatter(LongitudeFormatter(dms='dm', minutes_number_format='.1f'))
ax.yaxis.set_major_formatter(LatitudeFormatter(dms='dm', minutes_number_format='.1f'))
ax.set_title("dms='dm' (minutes as .1f)")

ax = axes[2]
ax.set_extent([-161, -154, 18, 23], crs=ccrs.PlateCarree())
ax.coastlines()
ax.set_xticks([-161, -159.51, -158, -156.3, -155, -154], crs=ccrs.PlateCarree())
ax.set_yticks([18, 19.51, 21, 22.3, 23], crs=ccrs.PlateCarree())
ax.xaxis.set_major_formatter(LongitudeFormatter(dms=True))
ax.yaxis.set_major_formatter(LatitudeFormatter(dms=True))
ax.set_title("dms=True (degrees-minutes-seconds)")

plt.tight_layout()
plt.show()

Example output

image

Implications

I think the worst part of this PR is the change from dms: bool, optional to dms: bool or str, optional I'm interested in doing this differently but I'm not sure what you'd suggest? This implementation is backwards compatible which is good.

@greglucas greglucas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of extra code here, I think we should try to work this into what we already have instead if possible. We should also accept a dms="d", "dm", "dms" for any of the versions if someone wants degrees alone we don't want to have to write a bunch of new helpers.

I think this can be done within the formatting checks. We should always just use the value, deg, mn, sec = self._get_dms(abs(value)) Maybe we could add the checks into that function and return sec=0 if self._dms = "dm" which would then skip the seconds formatting. Similar to the minutes and degrees section.

@DavidVadnais
DavidVadnais marked this pull request as draft September 15, 2026 00:16
@DavidVadnais

Copy link
Copy Markdown
Contributor Author

Ive got the capability now but I haven't tackled the extra code fully. My next goal is to tighten this up.

image

Comment thread lib/cartopy/mpl/ticker.py
@@ -120,8 +133,13 @@ def _get_dms(self, x):
"""
self._precision = 6

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should just be deleted since it overwrites the default 5 for seemingly no reason.

@DavidVadnais
DavidVadnais marked this pull request as ready for review September 17, 2026 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LAT/LONGITUDE_FORMATTER with different formats (minutes, seconds)

2 participants