Repository: SciTools/cartopy

Issue:
Longitude gridlines no longer contrained to the latitude gridline range (and vice versa) in cartopy 0.18
### Description
<!-- Please provide a general introduction to the issue/proposal. -->

In cartopy 0.17, longitude gridlines were constrained within the region of the minumum and maximum latitude gridlines, and latitude gridlines were constrained within the region of the minimum and maximum longitude gridlines.

This was very useful for "pole" centered projections, as it let people mimic the ["latmax" feature used in polar basemap projections](https://matplotlib.org/basemap/users/pstere.html). Generally it's nice to have a "hole" around the North and South poles rather than having all the gridlines converge to a single point.

In cartopy v0.18, this gridlining behavior seems to have disappeared -- putting a "hole" around the North and South poles is no longer possible.

<!--
If you are reporting a bug, attach the *entire* traceback from Python.

If you are proposing an enhancement/new feature, provide links to related articles, reference examples, etc.

If you are asking a question, please ask on StackOverflow and use the cartopy tag. All cartopy
questions on StackOverflow can be found at https://stackoverflow.com/questions/tagged/cartopy
-->

#### Code to reproduce

```python
import cartopy
import cartopy.crs as ccrs
import numpy as np
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import matplotlib.ticker as mticker
lats = mticker.FixedLocator(np.arange(-80, 81, 5))
lons = mticker.MultipleLocator(60)
fig = plt.figure(figsize=(6, 3))

ax = fig.add_subplot(121, projection=ccrs.NorthPolarStereo())
ax.set_extent([-180, 180, 70, 90], crs=ccrs.PlateCarree())
ax.gridlines(xlocs=lons, ylocs=lats)
ax.add_feature(cfeature.COASTLINE)

ax = fig.add_subplot(122, projection=ccrs.SouthPolarStereo())
ax.set_extent([-180, 180, -90, -70], crs=ccrs.PlateCarree())
ax.gridlines(xlocs=lons, ylocs=lats)
ax.add_feature(cfeature.COASTLINE)

fig.suptitle(f'Gridlines over polar projections in cartopy v{cartopy.__version__}')
```

Results in the following for cartopy 0.17:

![tmp](https://user-images.githubusercontent.com/19657652/82508771-4ed36b00-9ac3-11ea-811b-d66feef94b96.png)


And the following for cartopy 0.18:

![tmp](https://user-images.githubusercontent.com/19657652/82508544-9f969400-9ac2-11ea-94fe-525a6c8105dc.png)


<details>
 <summary>Full environment definition</summary>

<!-- fill in the following information as appropriate -->

### Cartopy version

v0.17 and v0.18

### conda list

```
# packages in environment at /Users/ldavis/miniconda3:
#
# Name                    Version                   Build  Channel
alabaster                 0.7.12                   pypi_0    pypi
appdirs                   1.4.4                    pypi_0    pypi
appnope                   0.1.0           py38h32f6830_1001    conda-forge
asttokens                 2.0.4                    pypi_0    pypi
attrs                     19.3.0                     py_0    conda-forge
autopep8                  1.5.2                    pypi_0    pypi
babel                     2.8.0                    pypi_0    pypi
backcall                  0.1.0                      py_0    conda-forge
basemap                   1.3.0            py38h9bcff04_2    conda-forge
basemap-data-hires        1.2.1                         0    conda-forge
beautifulsoup4            4.9.0                    pypi_0    pypi
black                     19.10b0                  pypi_0    pypi
bleach                    3.1.5              pyh9f0ad1d_0    conda-forge
boost-cpp                 1.72.0               hdf9ef73_0    conda-forge
brotlipy                  0.7.0           py38h64e0658_1000    conda-forge
bs4                       0.0.1                    pypi_0    pypi
bzip2                     1.0.8                h0b31af3_2    conda-forge
ca-certificates           2020.4.5.1           hecc5488_0    conda-forge
cairo                     1.16.0            hec6a9b0_1003    conda-forge
cartopy                   0.17.0          py38h9bcff04_1015    conda-forge
certifi                   2020.4.5.1       py38h32f6830_0    conda-forge
cffi                      1.14.0           py38h356ff06_0    conda-forge
cfgv                      3.1.0                    pypi_0    pypi
cfitsio                   3.470                hddc9c06_5    conda-forge
cftime                    1.1.2            py38h65ad66c_0    conda-forge
chardet                   3.0.4           py38h32f6830_1006    conda-forge
click                     7.1.2                    pypi_0    pypi
climpy                    0.0.3.post56+dirty           dev_0    <develop>
colorama                  0.4.3                    pypi_0    pypi
conda                     4.8.3            py38h32f6830_1    conda-forge
conda-package-handling    1.6.0            py38h64e0658_2    conda-forge
cryptography              2.9.2            py38hb761dab_0    conda-forge
ctags                     5.8               h1de35cc_1000    conda-forge
curl                      7.69.1               h2d98d24_0    conda-forge
cycler                    0.10.0                     py_2    conda-forge
dbus                      1.13.6               h2f22bb5_0    conda-forge
decorator                 4.4.2                      py_0    conda-forge
defusedxml                0.6.0                      py_0    conda-forge
discogs-client            2.2.2                    pypi_0    pypi
distlib                   0.3.0                    pypi_0    pypi
docopt                    0.6.2                    pypi_0    pypi
docutils                  0.16                     pypi_0    pypi
entrypoints               0.3             py38h32f6830_1001    conda-forge
executing                 0.4.3                    pypi_0    pypi
expat                     2.2.9                h4a8c4bd_2    conda-forge
ffmpeg-normalize          1.19.0                   pypi_0    pypi
filelock                  3.0.12                   pypi_0    pypi
flake8                    3.8.1                    pypi_0    pypi
flake8-unused-arguments   0.0.3                    pypi_0    pypi
fontconfig                2.13.1            h6b1039f_1001    conda-forge
freetype                  2.10.1               h8da9a1a_0    conda-forge
freexl                    1.0.5             h1de35cc_1002    conda-forge
gdal                      3.0.4           py38h9f7df5a_10    conda-forge
geos                      3.8.1                h4a8c4bd_0    conda-forge
geotiff                   1.6.0                hd8796ba_0    conda-forge
gettext                   0.19.8.1          h46ab8bc_1002    conda-forge
giflib                    5.2.1                h0b31af3_2    conda-forge
glib                      2.64.2               h577aef8_0    conda-forge
greenlet                  0.4.15                   pypi_0    pypi
hdf4                      4.2.13            h84186c3_1003    conda-forge
hdf5                      1.10.6          nompi_h3e39495_100    conda-forge
icecream                  2.0.0                    pypi_0    pypi
icu                       64.2                 h6de7cb9_1    conda-forge
identify                  1.4.15                   pypi_0    pypi
idna                      2.9                        py_1    conda-forge
imagesize                 1.2.0                    pypi_0    pypi
importlib-metadata        1.6.0            py38h32f6830_0    conda-forge
importlib_metadata        1.6.0                         0    conda-forge
ipykernel                 5.2.1            py38h23f93f0_0    conda-forge
ipython                   7.14.0           py38h32f6830_0    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                7.5.1                      py_0    conda-forge
jedi                      0.17.0           py38h32f6830_0    conda-forge
jinja2                    2.11.2             pyh9f0ad1d_0    conda-forge
jpeg                      9c                h1de35cc_1001    conda-forge
json-c                    0.13.1            h1de35cc_1001    conda-forge
jsonschema                3.2.0            py38h32f6830_1    conda-forge
jupyter                   1.0.0                      py_2    conda-forge
jupyter-contrib-core      0.3.3                    pypi_0    pypi
jupyter-nbextensions-configurator 0.4.1                    pypi_0    pypi
jupyter_client            6.1.3                      py_0    conda-forge
jupyter_console           6.1.0                      py_1    conda-forge
jupyter_core              4.6.3            py38h32f6830_1    conda-forge
jupyterthemes             0.20.0                   pypi_0    pypi
jupytext                  1.4.2                    pypi_0    pypi
kealib                    1.4.13               h40102fb_1    conda-forge
keyring                   21.2.1                   pypi_0    pypi
kiwisolver                1.2.0            py38ha0d09dd_0    conda-forge
krb5                      1.17.1               h1752a42_0    conda-forge
lesscpy                   0.14.0                   pypi_0    pypi
libblas                   3.8.0               16_openblas    conda-forge
libcblas                  3.8.0               16_openblas    conda-forge
libclang                  9.0.1           default_hf57f61e_0    conda-forge
libcurl                   7.69.1               hc0b9707_0    conda-forge
libcxx                    10.0.0               h1af66ff_2    conda-forge
libdap4                   3.20.6               h8c15375_0    conda-forge
libedit                   3.1.20170329      hcfe32e1_1001    conda-forge
libffi                    3.2.1             h4a8c4bd_1007    conda-forge
libgdal                   3.0.4               h242383b_10    conda-forge
libgfortran               4.0.0                         2    conda-forge
libiconv                  1.15              h0b31af3_1006    conda-forge
libkml                    1.3.0             h169b8f9_1011    conda-forge
liblapack                 3.8.0               16_openblas    conda-forge
libllvm9                  9.0.1                h7475705_1    conda-forge
libnetcdf                 4.7.4           nompi_ha11d67f_104    conda-forge
libopenblas               0.3.9                h3d69b6c_0    conda-forge
libpng                    1.6.37               hbbe82c9_1    conda-forge
libpq                     12.2                 h489d428_1    conda-forge
libsodium                 1.0.17               h01d97ff_0    conda-forge
libspatialite             4.3.0a            h658e6c1_1038    conda-forge
libssh2                   1.8.2                hcdc9a53_2    conda-forge
libtiff                   4.1.0                h2ae36a8_6    conda-forge
libwebp-base              1.1.0                h0b31af3_3    conda-forge
libxml2                   2.9.10               h53d96d6_0    conda-forge
llvm-openmp               10.0.0               h28b9765_0    conda-forge
lz4-c                     1.9.2                h4a8c4bd_1    conda-forge
markupsafe                1.1.1            py38h64e0658_1    conda-forge
matplotlib                3.2.0                    pypi_0    pypi
matplotlib-base           3.2.1            py38h1300a51_0    conda-forge
mccabe                    0.6.1                    pypi_0    pypi
mistune                   0.8.4           py38h64e0658_1001    conda-forge
msgpack                   1.0.0                    pypi_0    pypi
musicbrainzngs            0.7.1                    pypi_0    pypi
mutagen                   1.44.0                   pypi_0    pypi
nbconvert                 5.6.1            py38h32f6830_1    conda-forge
nbformat                  5.0.6                      py_0    conda-forge
nbsphinx                  0.6.1                    pypi_0    pypi
ncurses                   6.1               h0a44026_1002    conda-forge
neovim                    0.3.1                    pypi_0    pypi
netcdf4                   1.5.3           nompi_py38h4c5c689_105    conda-forge
nodeenv                   1.3.5                    pypi_0    pypi
notebook                  6.0.3            py38h32f6830_0    conda-forge
nspr                      4.20              h0a44026_1000    conda-forge
nss                       3.47                 hc0980d9_0    conda-forge
numpy                     1.18.4           py38h1f821a2_0    conda-forge
oauthlib                  3.1.0                    pypi_0    pypi
olefile                   0.46                       py_0    conda-forge
openjpeg                  2.3.1                h254dc36_3    conda-forge
openssl                   1.1.1g               h0b31af3_0    conda-forge
owslib                    0.19.2                     py_1    conda-forge
packaging                 20.1                       py_0    conda-forge
pandas                    1.0.3            py38h5fc983b_1    conda-forge
pandoc                    1.0.2                    pypi_0    pypi
pandocfilters             1.4.2                    pypi_0    pypi
parso                     0.7.0              pyh9f0ad1d_0    conda-forge
pathspec                  0.8.0                    pypi_0    pypi
pcre                      8.44                 h4a8c4bd_0    conda-forge
pexpect                   4.8.0            py38h32f6830_1    conda-forge
pickleshare               0.7.5           py38h32f6830_1001    conda-forge
pillow                    7.1.2            py38h83dc5e5_0    conda-forge
pip                       20.1               pyh9f0ad1d_0    conda-forge
pixman                    0.38.0            h01d97ff_1003    conda-forge
pkginfo                   1.5.0.1                  pypi_0    pypi
ply                       3.11                     pypi_0    pypi
poppler                   0.87.0               h3232a60_1    conda-forge
poppler-data              0.4.9                         1    conda-forge
postgresql                12.2                 h62ab893_1    conda-forge
pre-commit                2.3.0                    pypi_0    pypi
proj                      7.0.0                hbce2d5c_3    conda-forge
prometheus_client         0.7.1                      py_0    conda-forge
prompt-toolkit            3.0.5                      py_0    conda-forge
prompt_toolkit            3.0.5                         0    conda-forge
proplot                   0.6.0                     dev_0    <develop>
ptyprocess                0.6.0                   py_1001    conda-forge
pycodestyle               2.6.0                    pypi_0    pypi
pycosat                   0.6.3           py38h64e0658_1004    conda-forge
pycparser                 2.20                       py_0    conda-forge
pyepsg                    0.4.0                      py_0    conda-forge
pyflakes                  2.2.0                    pypi_0    pypi
pygments                  2.6.1                      py_0    conda-forge
pykdtree                  1.3.1           py38h65ad66c_1003    conda-forge
pynvim                    0.4.1                    pypi_0    pypi
pyopenssl                 19.1.0                     py_1    conda-forge
pyparsing                 2.4.7              pyh9f0ad1d_0    conda-forge
pyproj                    2.6.1.post1      py38h7d7e87d_0    conda-forge
pyqt                      5.12.3           py38hf180056_3    conda-forge
pyqt5                     5.14.2                   pypi_0    pypi
pyqt5-sip                 4.19.18                  pypi_0    pypi
pyqtchart                 5.12                     pypi_0    pypi
pyqtwebengine             5.12.1                   pypi_0    pypi
pyrsistent                0.16.0           py38h64e0658_0    conda-forge
pyshp                     2.1.0                      py_0    conda-forge
pysocks                   1.7.1            py38h32f6830_1    conda-forge
python                    3.8.2           hd5f0129_7_cpython    conda-forge
python-dateutil           2.8.1                      py_0    conda-forge
python.app                2                       py38_10    defaults
python_abi                3.8                      1_cp38    conda-forge
pytz                      2020.1             pyh9f0ad1d_0    conda-forge
pyyaml                    5.3.1                    pypi_0    pypi
pyzmq                     19.0.1           py38h1fcdcd6_0    conda-forge
qt                        5.12.5               h514805e_3    conda-forge
qtconsole                 4.7.3              pyh9f0ad1d_0    conda-forge
qtpy                      1.9.0                      py_0    conda-forge
readline                  8.0                  hcfe32e1_0    conda-forge
readme-renderer           26.0                     pypi_0    pypi
regex                     2020.4.4                 pypi_0    pypi
requests                  2.23.0             pyh8c360ce_2    conda-forge
requests-toolbelt         0.9.1                    pypi_0    pypi
ruamel_yaml               0.15.80         py38h64e0658_1001    conda-forge
scipy                     1.4.1            py38h38b60c6_3    conda-forge
send2trash                1.5.0                      py_0    conda-forge
setuptools                46.1.3           py38h32f6830_0    conda-forge
shapely                   1.7.0            py38h5b1fbde_3    conda-forge
six                       1.14.0                     py_1    conda-forge
snowballstemmer           2.0.0                    pypi_0    pypi
soupsieve                 2.0                      pypi_0    pypi
sphinx                    3.0.3                    pypi_0    pypi
sphinx-automodapi         0.6.proplot-mods           dev_0    <develop>
sphinx-copybutton         0.2.11                   pypi_0    pypi
sphinx-rtd-theme          0.4.3                    pypi_0    pypi
sphinxcontrib-applehelp   1.0.2                    pypi_0    pypi
sphinxcontrib-devhelp     1.0.2                    pypi_0    pypi
sphinxcontrib-htmlhelp    1.0.3                    pypi_0    pypi
sphinxcontrib-jsmath      1.0.1                    pypi_0    pypi
sphinxcontrib-qthelp      1.0.3                    pypi_0    pypi
sphinxcontrib-serializinghtml 1.1.4                    pypi_0    pypi
sqlite                    3.30.1               h93121df_0    conda-forge
tbb                       2018.0.5             h2d50403_0    conda-forge
terminado                 0.8.3            py38h32f6830_1    conda-forge
testpath                  0.4.4                      py_0    conda-forge
tiledb                    1.7.7                h84aa2a7_1    conda-forge
tk                        8.6.10               hbbe82c9_0    conda-forge
toml                      0.10.0                   pypi_0    pypi
tornado                   6.0.4            py38h64e0658_1    conda-forge
tqdm                      4.46.0             pyh9f0ad1d_0    conda-forge
traitlets                 4.3.3            py38h32f6830_1    conda-forge
twine                     3.1.1                    pypi_0    pypi
typed-ast                 1.4.1                    pypi_0    pypi
tzcode                    2020a                h0b31af3_0    conda-forge
unidecode                 1.1.1                    pypi_0    pypi
urllib3                   1.25.9                     py_0    conda-forge
vim                       8.2.0694         py38h2782e99_0    conda-forge
vint                      0.1.5                    pypi_0    pypi
virtualenv                20.0.20                  pypi_0    pypi
wcwidth                   0.1.9              pyh9f0ad1d_0    conda-forge
webencodings              0.5.1                    pypi_0    pypi
wheel                     0.34.2                     py_1    conda-forge
widgetsnbextension        3.5.1                    py38_0    conda-forge
xarray                    0.15.1                     py_0    conda-forge
xerces-c                  3.2.2             h8f8adb3_1004    conda-forge
xz                        5.2.5                h0b31af3_0    conda-forge
yaml                      0.2.4                h0b31af3_0    conda-forge
youtube-dl                2020.5.8                 pypi_0    pypi
zeromq                    4.3.2                h6de7cb9_2    conda-forge
zipp                      3.1.0                      py_0    conda-forge
zlib                      1.2.11            h0b31af3_1006    conda-forge
zstd                      1.4.4                h4b3e974_3    conda-forge
```

### pip list

```
Package                           Version             Location
--------------------------------- ------------------- -------------------------------
alabaster                         0.7.12
appdirs                           1.4.4
appnope                           0.1.0
asttokens                         2.0.4
attrs                             19.3.0
autopep8                          1.5.2
Babel                             2.8.0
backcall                          0.1.0
basemap                           1.2.1
beautifulsoup4                    4.9.0
black                             19.10b0
bleach                            3.1.5
brotlipy                          0.7.0
bs4                               0.0.1
Cartopy                           0.17.0
certifi                           2020.4.5.1
cffi                              1.14.0
cfgv                              3.1.0
cftime                            1.1.2
chardet                           3.0.4
click                             7.1.2
climpy                            0.0.3.post56+dirty  /Users/ldavis/climpy
colorama                          0.4.3
conda                             4.8.3
conda-package-handling            1.6.0
cryptography                      2.9.2
cycler                            0.10.0
decorator                         4.4.2
defusedxml                        0.6.0
discogs-client                    2.2.2
distlib                           0.3.0
docopt                            0.6.2
docutils                          0.16
entrypoints                       0.3
executing                         0.4.3
ffmpeg-normalize                  1.19.0
filelock                          3.0.12
flake8                            3.8.1
flake8-unused-arguments           0.0.3
GDAL                              3.0.4
greenlet                          0.4.15
icecream                          2.0.0
identify                          1.4.15
idna                              2.9
imagesize                         1.2.0
importlib-metadata                1.6.0
ipykernel                         5.2.1
ipython                           7.14.0
ipython-genutils                  0.2.0
ipywidgets                        7.5.1
jedi                              0.17.0
Jinja2                            2.11.2
jsonschema                        3.2.0
jupyter-client                    6.1.3
jupyter-console                   6.1.0
jupyter-contrib-core              0.3.3
jupyter-core                      4.6.3
jupyter-nbextensions-configurator 0.4.1
jupyterthemes                     0.20.0
jupytext                          1.4.2
keyring                           21.2.1
kiwisolver                        1.2.0
lesscpy                           0.14.0
MarkupSafe                        1.1.1
matplotlib                        3.2.1
mccabe                            0.6.1
mistune                           0.8.4
msgpack                           1.0.0
musicbrainzngs                    0.7.1
mutagen                           1.44.0
nbconvert                         5.6.1
nbformat                          5.0.6
nbsphinx                          0.6.1
neovim                            0.3.1
netCDF4                           1.5.3
nodeenv                           1.3.5
notebook                          6.0.3
numpy                             1.18.4
oauthlib                          3.1.0
olefile                           0.46
OWSLib                            0.19.2
packaging                         20.1
pandas                            1.0.3
pandoc                            1.0.2
pandocfilters                     1.4.2
parso                             0.7.0
pathspec                          0.8.0
pexpect                           4.8.0
pickleshare                       0.7.5
Pillow                            7.1.2
pip                               20.1
pkginfo                           1.5.0.1
ply                               3.11
pre-commit                        2.3.0
prometheus-client                 0.7.1
prompt-toolkit                    3.0.5
proplot                           0.6.0               /Users/ldavis/proplot
ptyprocess                        0.6.0
pycodestyle                       2.6.0
pycosat                           0.6.3
pycparser                         2.20
pyepsg                            0.4.0
pyflakes                          2.2.0
Pygments                          2.6.1
pykdtree                          1.3.1
pynvim                            0.4.1
pyOpenSSL                         19.1.0
pyparsing                         2.4.7
pyproj                            2.6.1.post1
PyQt5                             5.14.2
PyQt5-sip                         12.7.2
PyQtChart                         5.12
PyQtWebEngine                     5.12.1
pyrsistent                        0.16.0
pyshp                             2.1.0
PySocks                           1.7.1
python-dateutil                   2.8.1
pytz                              2020.1
PyYAML                            5.3.1
pyzmq                             19.0.1
qtconsole                         4.7.3
QtPy                              1.9.0
readme-renderer                   26.0
regex                             2020.4.4
requests                          2.23.0
requests-toolbelt                 0.9.1
ruamel-yaml                       0.15.80
scipy                             1.4.1
Send2Trash                        1.5.0
setuptools                        46.1.3.post20200325
Shapely                           1.7.0
six                               1.14.0
snowballstemmer                   2.0.0
soupsieve                         2.0
Sphinx                            3.0.3
sphinx-automodapi                 0.6.proplot-mods    /Users/ldavis/sphinx-automodapi
sphinx-copybutton                 0.2.11
sphinx-rtd-theme                  0.4.3
sphinxcontrib-applehelp           1.0.2
sphinxcontrib-devhelp             1.0.2
sphinxcontrib-htmlhelp            1.0.3
sphinxcontrib-jsmath              1.0.1
sphinxcontrib-qthelp              1.0.3
sphinxcontrib-serializinghtml     1.1.4
terminado                         0.8.3
testpath                          0.4.4
toml                              0.10.0
tornado                           6.0.4
tqdm                              4.46.0
traitlets                         4.3.3
twine                             3.1.1
typed-ast                         1.4.1
Unidecode                         1.1.1
urllib3                           1.25.9
vint                              0.1.5
virtualenv                        20.0.20
wcwidth                           0.1.9
webencodings                      0.5.1
wheel                             0.34.2
widgetsnbextension                3.5.1
xarray                            0.15.1
youtube-dl                        2020.5.8
zipp                              3.1.0
```

</details>



Discussion:

Resolving patch:
diff --git a/lib/cartopy/mpl/geoaxes.py b/lib/cartopy/mpl/geoaxes.py
--- a/lib/cartopy/mpl/geoaxes.py
+++ b/lib/cartopy/mpl/geoaxes.py
@@ -1315,7 +1315,7 @@ def imshow(self, img, *args, **kwargs):
     def gridlines(self, crs=None, draw_labels=False,
                   xlocs=None, ylocs=None, dms=False,
                   x_inline=None, y_inline=None, auto_inline=True,
-                  xformatter=None, yformatter=None,
+                  xformatter=None, yformatter=None, xlim=None, ylim=None,
                   **kwargs):
         """
         Automatically add gridlines to the axes, in the given coordinate
@@ -1365,6 +1365,16 @@ def gridlines(self, crs=None, draw_labels=False,
             use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
             with the ``dms`` argument, if the crs is of
             :class:`~cartopy.crs.PlateCarree` type.
+        xlim: optional
+            Set a limit for the gridlines so that they do not go all the
+            way to the edge of the boundary. xlim can be a single number or
+            a (min, max) tuple. If a single number, the limits will be
+            (-xlim, +xlim).
+        ylim: optional
+            Set a limit for the gridlines so that they do not go all the
+            way to the edge of the boundary. ylim can be a single number or
+            a (min, max) tuple. If a single number, the limits will be
+            (-ylim, +ylim).
 
         Keyword Parameters
         ------------------
@@ -1393,7 +1403,7 @@ def gridlines(self, crs=None, draw_labels=False,
             self, crs=crs, draw_labels=draw_labels, xlocator=xlocs,
             ylocator=ylocs, collection_kwargs=kwargs, dms=dms,
             x_inline=x_inline, y_inline=y_inline, auto_inline=auto_inline,
-            xformatter=xformatter, yformatter=yformatter)
+            xformatter=xformatter, yformatter=yformatter, xlim=xlim, ylim=ylim)
         self._gridliners.append(gl)
         return gl
 
diff --git a/lib/cartopy/mpl/gridliner.py b/lib/cartopy/mpl/gridliner.py
--- a/lib/cartopy/mpl/gridliner.py
+++ b/lib/cartopy/mpl/gridliner.py
@@ -105,7 +105,8 @@ class Gridliner:
     def __init__(self, axes, crs, draw_labels=False, xlocator=None,
                  ylocator=None, collection_kwargs=None,
                  xformatter=None, yformatter=None, dms=False,
-                 x_inline=None, y_inline=None, auto_inline=True):
+                 x_inline=None, y_inline=None, auto_inline=True,
+                 xlim=None, ylim=None):
         """
         Object used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
         to add gridlines and tick labels to a map.
@@ -155,6 +156,16 @@ def __init__(self, axes, crs, draw_labels=False, xlocator=None,
             Toggle whether the y labels drawn should be inline.
         auto_inline: optional
             Set x_inline and y_inline automatically based on projection.
+        xlim: optional
+            Set a limit for the gridlines so that they do not go all the
+            way to the edge of the boundary. xlim can be a single number or
+            a (min, max) tuple. If a single number, the limits will be
+            (-xlim, +xlim).
+        ylim: optional
+            Set a limit for the gridlines so that they do not go all the
+            way to the edge of the boundary. ylim can be a single number or
+            a (min, max) tuple. If a single number, the limits will be
+            (-ylim, +ylim).
 
         Notes
         -----
@@ -241,6 +252,11 @@ def __init__(self, axes, crs, draw_labels=False, xlocator=None,
         elif not auto_inline:
             self.y_inline = False
 
+        # Gridline limits so that the gridlines don't extend all the way
+        # to the edge of the boundary
+        self.xlim = xlim
+        self.ylim = ylim
+
         #: Whether to draw the x gridlines.
         self.xlines = True
 
@@ -888,4 +904,20 @@ def _axes_domain(self, nx=None, ny=None):
             if prct > 0.9:
                 lon_range = crs.x_limits
 
+        if self.xlim is not None:
+            if np.iterable(self.xlim):
+                # tuple, list or ndarray was passed in: (-140, 160)
+                lon_range = self.xlim
+            else:
+                # A single int/float was passed in: 140
+                lon_range = (-self.xlim, self.xlim)
+
+        if self.ylim is not None:
+            if np.iterable(self.ylim):
+                # tuple, list or ndarray was passed in: (-140, 160)
+                lat_range = self.ylim
+            else:
+                # A single int/float was passed in: 140
+                lat_range = (-self.ylim, self.ylim)
+
         return lon_range, lat_range


Test patch:
diff --git a/lib/cartopy/tests/mpl/test_gridliner.py b/lib/cartopy/tests/mpl/test_gridliner.py
--- a/lib/cartopy/tests/mpl/test_gridliner.py
+++ b/lib/cartopy/tests/mpl/test_gridliner.py
@@ -6,6 +6,7 @@
 
 import matplotlib.pyplot as plt
 import matplotlib.ticker as mticker
+import numpy as np
 import pytest
 
 import cartopy.crs as ccrs
@@ -319,3 +320,29 @@ def test_gridliner_default_fmtloc(
     plt.close()
     assert isinstance(gl.xlocator, xloc_expected)
     assert isinstance(gl.xformatter, xfmt_expected)
+
+
+def test_gridliner_line_limits():
+    fig = plt.figure()
+    ax = plt.subplot(1, 1, 1, projection=ccrs.NorthPolarStereo())
+    ax.set_global()
+    # Test a single value passed in which represents (-lim, lim)
+    xlim, ylim = 125, 75
+    gl = ax.gridlines(xlim=xlim, ylim=ylim)
+    fig.canvas.draw_idle()
+
+    paths = gl.xline_artists[0].get_paths() + gl.yline_artists[0].get_paths()
+    for path in paths:
+        assert (np.min(path.vertices, axis=0) >= (-xlim, -ylim)).all()
+        assert (np.max(path.vertices, axis=0) <= (xlim, ylim)).all()
+
+    # Test a pair of values passed in which represents the min, max
+    xlim = (-125, 150)
+    ylim = (50, 70)
+    gl = ax.gridlines(xlim=xlim, ylim=ylim)
+    fig.canvas.draw_idle()
+
+    paths = gl.xline_artists[0].get_paths() + gl.yline_artists[0].get_paths()
+    for path in paths:
+        assert (np.min(path.vertices, axis=0) >= (xlim[0], ylim[0])).all()
+        assert (np.max(path.vertices, axis=0) <= (xlim[1], ylim[1])).all()