Search code examples
python-3.xmatplotlibcartopy

How to retrieve a gridline axis tick positions?


I am trying to retrieve the yaxis and xaxis tick positions from a cartopy geoaxes.

As far as I understand, a common matplotlib's Axes has the internal method: 'axes.get_xticks' and 'axes.get_yticks'.

Nevertheless, a cartopy's gridline from a geoaxes does not. How could I retrieve them?

Also, when I try to retrieve the ticks from a geoaxes using the common format (i.e.: "axes.get_yticks"), I end up with strange coordinates.

Here is an example.

import pandas as pd
pd.set_option('display.width', 50000)
pd.set_option('display.max_rows', 50000)
pd.set_option('display.max_columns', 5000)


import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature


from matplotlib.offsetbox import AnchoredText

def main(projection = ccrs.Mercator(), drawlicense=True):

    fig = plt.figure(figsize=(9,7))
    ax = plt.axes(projection=projection)


    # Put a background image on for nice sea rendering.
    ax.stock_img()

    # Create a feature for States/Admin 1 regions at 1:50m from Natural Earth
    states_provinces = cfeature.NaturalEarthFeature(
        category='cultural',
        name='admin_1_states_provinces_lines',
        scale='50m',
        facecolor='none')

    SOURCE = 'Natural Earth'
    LICENSE = 'public domain'

    ax.add_feature(cfeature.LAND)
    ax.add_feature(cfeature.COASTLINE)
    ax.add_feature(states_provinces, edgecolor='gray')

    # Add a text annotation for the license information to the
    # the bottom right corner.

    if drawlicense:

        text = AnchoredText(r'$\mathcircled{{c}}$ {}; license: {}'
                            ''.format(SOURCE, LICENSE),
                            loc='right',
                            bbox_transform=ax.transAxes,
                            bbox_to_anchor=(1.01, -0.02), 
                            prop={'size': 8}, 
                            frameon=False)

        ax.add_artist(text)

    plt.show()

    return ax

ax = main()

Gridliner = ax.gridlines(draw_labels=True)

In this above case, if I try to retrieve the yticks from the geoaxes "ax", I end up with an array of strange values as:


In: ax.get_yticks()

Out: array([-20000000., -15000000., -10000000., -5000000., 0., 5000000., 10000000., 15000000., 20000000.])


Notice that the values are not in degrees, though the figure and also the selected cartopy's projection states degree coordinates.

Therefore, what am I doing wrong? How can I get the respective degree coordinates of the map?

Sincerely,


Solution

  • The cartopy axes does not actually show normal matplotlib ticks. Instead you can use ax.gridlines to obtain a set of linecollections that show the grid. The returned cartopy.mpl.gridliner.Gridliner can be used to query the positions of the lines.

    Note that projections are not necessarily separable in x and y, hence the gridlines could potentially be curves.

    In the following we take the first points of those lines.

    # create grid
    gridliner = ax.gridlines(draw_labels=True)
    
    # we need to draw the figure, such that the gridlines are populated
    fig.canvas.draw()   
    
    ysegs = gridliner.yline_artists[0].get_segments()
    yticks = [yseg[0,1] for yseg in ysegs]
    
    xsegs = gridliner.xline_artists[0].get_segments()
    xticks = [xseg[0,0] for xseg in xsegs]
    
    print(xticks)
    print(yticks)
    

    This prints two lists with the first gridline point's coordinates:

    [-180.0, -120.0, -60.0, 0.0, 60.0, 120.0]
    [-80.0, -60.0, -40.0, -20.0, 0.0, 20.0, 40.0, 60.0, 80.0, 100.0]