Skip to content

[Feature request] Adding ticks to geographic plots #125

Closed

Description

@664787022

Thanks, @cvanelteren , for your continued development of Proplot into Ultraplot

Adding ticks to geographic plots is a practical feature in geoscience studies.

Although this feature was requested in Proplot, it was not merged into the codebase, see Support adding tick marks to geographic plots

Hopefully, @cvanelteren can add this feature to Ultraplot !

Activity

  1. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    I believe this is already possible:

    Image

    import ultraplot as uplt, numpy as np
    
    fig, axs = uplt.subplots(proj="cyl")
    axs.format(
        land=True,
        labels=True,
        lonlines=20,
        latlines=20,
        gridminor=False,
        lonlim=(-140, 60),
        latlim=(-10, 50),
    )
    uplt.show(block=1)
    
  2. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    Or more succinctly:

    Image

    import ultraplot as uplt, numpy as np
    from itertools import product
    
    fig, axs = uplt.subplots(ncols=2, nrows=2, proj="cyl")
    
    settings = dict(
        land=True,
        labels=True,
        lonlines=20,
        latlines=20,
        lonlim=(-140, 60),
        latlim=(-10, 50),
    )
    for idx, (gridminor, gridmajor) in enumerate(product([True, False], [True, False])):
        settings["gridminor"] = gridminor
        settings["grid"] = gridmajor
        axs[idx].format(**settings)
    uplt.show(block=1)
  3. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    But perhaps I am missing something (not a geoscientist ;-)).

  4. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    Ah wait I read this wrong, you want the ticklens not the grid to change.

  5. 664787022 commented on Mar 16, 2025

    @664787022
    Author

    Ah wait I read this wrong, you want the ticklens not the grid to change.

    Yes, ticks in geographic plots are used more frequently than gridlines, at least in my field. They help keep the map clean and visually appealing by avoiding clutter from multiple gridlines.

    In some cases, we need to overlap contours. If we use gridlines simultaneously, there will be toooo many lines in the map.

    Image

  6. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    Image working on it ;-)

  7. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    Is the attached img in #126 what you had in mind?

  8. 664787022 commented on Mar 16, 2025

    @664787022
    Author

    Is the attached img in #126 what you had in mind?

    Yes! It looks great! but im not sure if it goes well when using polar axes. For example uplot.subplot(proj="aeqd")

  9. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    Do you have an example of how that would look like for polar axes? The ticks won't be equally spaced I am assuming.

  10. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    TypeError: Cannot label AzimuthalEquidistant gridlines. Only PlateCarree gridlines are currently supported.

    I think the labelling is non-trivial. This error is produced by cartopy when I attempt to force labeling on non PlateCarree projections. Will do some more digging to see if this can be achieved.

  11. cvanelteren commented on Mar 16, 2025

    @cvanelteren
    Collaborator

    I'm super confused how the tickers are handled by matplotlib. The issue seems that for the projection above that the range is so big that it attempts to parse it evenly which generates too many ticks for matplotlib too handle. I attempted to limit these by overriding the ticker, but most function internally to matplotlib revert this conversion by making its own ticker which prevent passing parameters that could limit the tick locations and hence the error.

    I am not too familiar with the internals of cartopy and how they divide these ranges. Luke also ran into this issue judging from the link above.

    Input is appreciated on the PR.

  12. 664787022 commented on Mar 17, 2025

    @664787022
    Author

    TypeError: Cannot label AzimuthalEquidistant gridlines. Only PlateCarree gridlines are currently supported.

    I think the labelling is non-trivial. This error is produced by cartopy when I attempt to force labeling on non PlateCarree projections. Will do some more digging to see if this can be achieved.

    Cartopy does not seem to support adding ticks for non-rectangular projections. I'm not sure whether it's possible to add ticks in a polar projection. However, we can now use ax.format(lontick=True, lattick=True) with ccrs.PlateCarree(), which I believe meets the needs of most use cases :-)

  13. cvanelteren commented on Mar 17, 2025

    @cvanelteren
    Collaborator

    Are there any flat projections missing from the PR? See the function _is_flat_projection. Currently I have these:

        flat_names = [
            "PlateCarree",
            "Mercator",
            "LambertCylindrical",
            "Miller",
            "Robinson",
            "Mollweide",
            "EqualEarth",
        ]
        flat_names_basemap = [
            "basemap",
            "merc",
            "cyl",
            "rectilinear",
            "rect",
            "tmerc",
            "mill",
            "unknown",  # not sure why this is created on basemap but assume it is flat
        ]
  14. 664787022 commented on Mar 17, 2025

    @664787022
    Author

    Are there any flat projections missing from the PR? See the function _is_flat_projection. Currently I have these:

    flat_names = [
        "PlateCarree",
        "Mercator",
        "LambertCylindrical",
        "Miller",
        "Robinson",
        "Mollweide",
        "EqualEarth",
    ]
    flat_names_basemap = [
        "basemap",
        "merc",
        "cyl",
        "rectilinear",
        "rect",
        "tmerc",
        "mill",
        "unknown",  # not sure why this is created on basemap but assume it is flat
    ]
    

    I am not sure what "flat projection" refers to, but similar to Robinson, there are Hammer, Aitoff. You can find more in this cartopy projection list

  15. 664787022 commented on Mar 17, 2025

    @664787022
    Author
        # For cartopy
        if hasattr(proj, "name"):
            name = proj.name.lower()
        # For basemap:
        else:
            name = proj.projection.lower()
        return any(
            name == flat_name.lower() for flat_name in flat_names + flat_names_basemap
        )
    

    I am a bit confused about this paragraph. proj.name.lower() always seems to return "unknown" in my case.

    name = proj.__class__.__name__ 
    

    works

  16. beckermr commented on Mar 17, 2025

    @beckermr
    Collaborator

    I think "flat" here is not a geometric statement. Instead what is meant is "a projection that you plot on a rectangle"?

    If so we should find the proper term and use it in the code.

  17. cvanelteren commented on Mar 17, 2025

    @cvanelteren
    Collaborator

    I used rectilinear now and modified the checks that should be name independent.

  18. cvanelteren commented on Mar 18, 2025

    @cvanelteren
    Collaborator

    @664787022 with flat I referred to rectilinear, does my previous remark make sense now?

  19. cvanelteren commented on Mar 20, 2025

    @cvanelteren
    Collaborator

    Feature is added in main. Will draft a release tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions