Update NCI thredds URL #383
363 tests run, 350 passed, 0 skipped, 13 failed.
Annotations
Check failure on line 24 in tests/cli/test_utils.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_utils.test_nice_console_errors_os_error
assert 0 == 1
+ where 0 = len([])
+ where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb41c3110>.messages
Raw output
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fccb41c3110>
def test_nice_console_errors_os_error(caplog: pytest.LogCaptureFixture) -> None:
with pytest.raises(SystemExit) as exc_info:
with utils.nice_console_errors():
raise FileNotFoundError("'./foo.txt' does not exist")
> assert len(caplog.messages) == 1
E assert 0 == 1
E + where 0 = len([])
E + where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb41c3110>.messages
tests/cli/test_utils.py:24: AssertionError
Check failure on line 38 in tests/cli/test_utils.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_utils.test_nice_console_errors_command_exception
assert 0 == 1
+ where 0 = len([])
+ where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb4167ad0>.messages
Raw output
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fccb4167ad0>
def test_nice_console_errors_command_exception(caplog: pytest.LogCaptureFixture) -> None:
with pytest.raises(SystemExit) as exc_info:
with utils.nice_console_errors():
raise CommandException("Could not frobnicate the splines", code=5)
> assert len(caplog.messages) == 1
E assert 0 == 1
E + where 0 = len([])
E + where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb4167ad0>.messages
tests/cli/test_utils.py:38: AssertionError
Check failure on line 52 in tests/cli/test_utils.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_utils.test_nice_console_errors_uncaught_exception
assert 0 == 1
+ where 0 = len([])
+ where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb414f310>.messages
Raw output
caplog = <_pytest.logging.LogCaptureFixture object at 0x7fccb414f310>
def test_nice_console_errors_uncaught_exception(caplog: pytest.LogCaptureFixture) -> None:
with pytest.raises(SystemExit) as exc_info:
with utils.nice_console_errors():
1 / 0
> assert len(caplog.messages) == 1
E assert 0 == 1
E + where 0 = len([])
E + where [] = <_pytest.logging.LogCaptureFixture object at 0x7fccb414f310>.messages
tests/cli/test_utils.py:52: AssertionError
Check failure on line 454 in tests/conventions/test_base.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_base.test_plot
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
@pytest.mark.matplotlib
def test_plot():
dataset = xarray.Dataset({
'temp': (['t', 'z', 'y', 'x'], numpy.random.standard_normal((5, 5, 10, 20))),
'botz': (['y', 'x'], numpy.random.standard_normal((10, 20)) - 10),
})
convention = SimpleConvention(dataset)
convention.bind()
# Naming a simple variable should work fine
> convention.plot('botz')
tests/conventions/test_base.py:454:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:958: in plot
self.plot_on_figure(pyplot.figure(), *args, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fcca6ff6450>
axes = <GeoAxes: title={'center': 'botz'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fccb414ca10>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fccb41a26d0>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning
Check failure on line 377 in tests/conventions/test_cfgrid1d.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_cfgrid1d.test_plot_on_figure
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
@pytest.mark.matplotlib
def test_plot_on_figure():
# Not much to test here, mostly that it doesn't throw an error
dataset = make_dataset(width=3, height=5)
surface_temp = dataset.data_vars["temp"].isel(depth=-1, time=0)
figure = Figure()
> dataset.ems.plot_on_figure(figure, surface_temp)
tests/conventions/test_cfgrid1d.py:377:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fcca4cab650>
axes = <GeoAxes: title={'center': 'Temperature\n2021-11-11'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fcca4db26d0>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fcca4d96850>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning
Check failure on line 449 in tests/conventions/test_cfgrid2d.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_cfgrid2d.test_plot_on_figure
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
@pytest.mark.matplotlib
def test_plot_on_figure():
# Not much to test here, mostly that it doesn't throw an error
dataset = make_dataset(j_size=10, i_size=20)
surface_temp = dataset.data_vars["temp"].isel(k=-1, time=0)
figure = Figure()
> dataset.ems.plot_on_figure(figure, surface_temp)
tests/conventions/test_cfgrid2d.py:449:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fccb41e3b90>
axes = <GeoAxes: title={'center': 'Temperature\n2021-11-11'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fccb62dfb10>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fccb8150110>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning
Check failure on line 454 in tests/conventions/test_shoc_standard.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_shoc_standard.test_plot_on_figure
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
@pytest.mark.matplotlib
def test_plot_on_figure():
# Not much to test here, mostly that it doesn't throw an error
dataset = make_dataset(j_size=10, i_size=20)
surface_temp = dataset.data_vars["temp"].isel(k_centre=-1, record=0)
figure = Figure()
> dataset.ems.plot_on_figure(figure, surface_temp)
tests/conventions/test_shoc_standard.py:454:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fcca4c82f10>
axes = <GeoAxes: title={'center': 'Temperature'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fcca4adfb10>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fcca4b87750>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning
Check failure on line 605 in tests/conventions/test_ugrid.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_ugrid.test_plot_on_figure
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
@pytest.mark.matplotlib
def test_plot_on_figure():
# Not much to test here, mostly that it doesn't throw an error
dataset = make_dataset(width=3)
surface_temp = dataset.data_vars["temp"].isel(Mesh2_layers=-1, record=0)
figure = Figure()
> dataset.ems.plot_on_figure(figure, surface_temp)
tests/conventions/test_ugrid.py:605:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fcca4cc3a50>
axes = <GeoAxes: title={'center': 'Temperature'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fccb41c4390>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fcca4b0a6d0>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning
Check failure on line 749 in tests/conventions/test_ugrid.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_ugrid.test_make_and_apply_clip_mask
OverflowError: Not possible to cast encoded times from dtype('int64') to dtype('int16') without overflow. Consider removing the dtype encoding, at which point xarray will make an appropriate choice, or explicitly switching to a larger integer dtype.
Raw output
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_make_and_apply_clip_mask0')
def test_make_and_apply_clip_mask(tmp_path):
dataset = make_dataset(width=5)
# When saving a dataset to disk, xarray.coding.times.cast_to_int_if_safe
# will check if it is possible to encode a timedelta64 using integer values
# by casting the values and checking for equality.
# Recent versions of numpy will emit warnings
# when casting a data array with dtype timedelta64 to int
# if it contains NaT (not a time) values.
# xarray will fix this eventually, but for now...
# See https://github.com/pydata/xarray/issues/7942
with filter_warning(
'ignore', category=RuntimeWarning,
message='invalid value encountered in cast',
module=r'xarray\.coding\.times',
):
> dataset.ems.to_netcdf(tmp_path / "original.nc")
tests/conventions/test_ugrid.py:749:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:1695: in to_netcdf
utils.to_netcdf_with_fixes(
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/utils.py:149: in to_netcdf_with_fixes
dataset.to_netcdf(path, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/core/dataset.py:2327: in to_netcdf
return to_netcdf( # type: ignore # mypy cannot resolve the overloads:(
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/backends/api.py:1337: in to_netcdf
dump_to_store(
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/backends/api.py:1384: in dump_to_store
store.store(variables, attrs, check_encoding, writer, unlimited_dims=unlimited_dims)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/backends/common.py:363: in store
variables, attributes = self.encode(variables, attributes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/backends/common.py:452: in encode
variables, attributes = cf_encoder(variables, attributes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/conventions.py:795: in cf_encoder
new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/conventions.py:795: in <dictcomp>
new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/conventions.py:196: in encode_cf_variable
var = coder.encode(var, name=name)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/coding/times.py:1006: in encode
data, units = encode_cf_timedelta(
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/coding/times.py:865: in encode_cf_timedelta
return _eagerly_encode_cf_timedelta(timedeltas, units, dtype)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/coding/times.py:915: in _eagerly_encode_cf_timedelta
num = _cast_to_dtype_if_safe(num, dtype)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
num = array([ 0, 1, 2,
3, ..., 70, 71,
72, -9223372036854775808, -9223372036854775808])
dtype = dtype('int16')
def _cast_to_dtype_if_safe(num: np.ndarray, dtype: np.dtype) -> np.ndarray:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="overflow")
cast_num = np.asarray(num, dtype=dtype)
if np.issubdtype(dtype, np.integer):
if not (num == cast_num).all():
if np.issubdtype(num.dtype, np.floating):
raise ValueError(
f"Not possible to cast all encoded times from "
f"{num.dtype!r} to {dtype!r} without losing precision. "
f"Consider modifying the units such that integer values "
f"can be used, or removing the units and dtype encoding, "
f"at which point xarray will make an appropriate choice."
)
else:
> raise OverflowError(
f"Not possible to cast encoded times from "
f"{num.dtype!r} to {dtype!r} without overflow. Consider "
f"removing the dtype encoding, at which point xarray will "
f"make an appropriate choice, or explicitly switching to "
"a larger integer dtype."
)
E OverflowError: Not possible to cast encoded times from dtype('int64') to dtype('int16') without overflow. Consider removing the dtype encoding, at which point xarray will make an appropriate choice, or explicitly switching to a larger integer dtype.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/xarray/coding/times.py:681: OverflowError
Check failure on line 66 in tests/cli/test_utils.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_utils.test_find_fill_value_masked_and_scaled_float
AssertionError: assert dtype('float64') == dtype('float32')
+ where dtype('float64') = array([[ 1., 2.],\n [nan, 4.]]).dtype
+ and dtype('float32') = array([[ 1., 2.],\n [nan, 4.]], dtype=float32).dtype
Raw output
datasets = PosixPath('/home/runner/work/emsarray/emsarray/tests/datasets')
def test_find_fill_value_masked_and_scaled_float(datasets):
dataset_path = datasets / 'masking/find_fill_value/float_with_fill_value_and_offset.nc'
assert_raw_values(
dataset_path, 'var',
numpy.array([[-4.5, -4.0], [-999., -3.0]], dtype=numpy.float32))
# When opened with mask_and_scale=True (the default) xarray uses numpy.nan
# to indicate masked values.
with xarray.open_dataarray(dataset_path, mask_and_scale=True) as data_array:
> assert_dtype_equal(
data_array.values,
numpy.array([[1.0, 2.0], [numpy.nan, 4.0]], dtype=numpy.float32))
E AssertionError: assert dtype('float64') == dtype('float32')
E + where dtype('float64') = array([[ 1., 2.],\n [nan, 4.]]).dtype
E + and dtype('float32') = array([[ 1., 2.],\n [nan, 4.]], dtype=float32).dtype
tests/masking/test_utils.py:66: AssertionError
Check failure on line 90 in tests/cli/test_utils.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_utils.test_find_fill_value_masked_and_scaled_int
AssertionError: assert dtype('float64') == dtype('float32')
+ where dtype('float64') = array([[ 1., 2.],\n [nan, 4.]]).dtype
+ and dtype('float32') = array([[ 1., 2.],\n [nan, 4.]], dtype=float32).dtype
Raw output
datasets = PosixPath('/home/runner/work/emsarray/emsarray/tests/datasets')
def test_find_fill_value_masked_and_scaled_int(datasets):
dataset_path = datasets / 'masking/find_fill_value/int_with_fill_value_and_offset.nc'
assert_raw_values(
dataset_path, 'var',
numpy.array([[22, 24], [-1, 28]], dtype=numpy.int8))
# When opened with mask_and_scale=True (the default) xarray uses numpy.nan
# to indicate masked values.
with xarray.open_dataarray(dataset_path, mask_and_scale=True) as data_array:
> assert_dtype_equal(
data_array.values,
numpy.array([[1.0, 2.0], [numpy.nan, 4.0]], dtype=numpy.float32))
E AssertionError: assert dtype('float64') == dtype('float32')
E + where dtype('float64') = array([[ 1., 2.],\n [nan, 4.]]).dtype
E + and dtype('float32') = array([[ 1., 2.],\n [nan, 4.]], dtype=float32).dtype
tests/masking/test_utils.py:90: AssertionError
Check failure on line 1 in tests/cli/commands/test_plot.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_plot
pluggy.PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown.
Plugin: 140517270421456, Hook: pytest_runtest_call
MatplotlibDeprecationWarning: Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will be removed in 3.10. To suppress this warning, explicitly call plt.close('all') first.
For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning
Raw output
self = <pytest_mpl.plugin.ImageComparison object at 0x7fccb9fcffd0>
item = <Function test_plot>
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(self, item): # noqa
compare = get_compare(item)
if compare is None:
yield
return
import matplotlib.pyplot as plt
try:
from matplotlib.testing.decorators import remove_ticks_and_titles
except ImportError:
from matplotlib.testing.decorators import ImageComparisonTest as MplImageComparisonTest
remove_ticks_and_titles = MplImageComparisonTest.remove_text
style = compare.kwargs.get('style', self.default_style)
remove_text = compare.kwargs.get('remove_text', False)
backend = compare.kwargs.get('backend', self.default_backend)
ext = self._file_extension(item)
> with plt.style.context(style, after_reset=True), switch_backend(backend):
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/pytest_mpl/plugin.py:840:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/contextlib.py:144: in __exit__
next(self.gen)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/pytest_mpl/plugin.py:322: in switch_backend
plt.switch_backend(prev_backend)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/matplotlib/pyplot.py:509: in switch_backend
_api.warn_deprecated("3.8", message=(
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/matplotlib/_api/deprecation.py:99: in warn_deprecated
warn_external(warning, category=MatplotlibDeprecationWarning)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
message = MatplotlibDeprecationWarning("Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will be removed in 3.10. To suppress this warning, explicitly call plt.close('all') first.")
category = <class 'matplotlib._api.deprecation.MatplotlibDeprecationWarning'>
def warn_external(message, category=None):
"""
`warnings.warn` wrapper that sets *stacklevel* to "outside Matplotlib".
The original emitter of the warning can be obtained by patching this
function back to `warnings.warn`, i.e. ``_api.warn_external =
warnings.warn`` (or ``functools.partial(warnings.warn, stacklevel=2)``,
etc.).
"""
frame = sys._getframe()
for stacklevel in itertools.count(1):
if frame is None:
# when called in embedded context may hit frame is None
break
if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.(?!tests\.))",
# Work around sphinx-gallery not setting __name__.
frame.f_globals.get("__name__", "")):
break
frame = frame.f_back
# preemptively break reference cycle between locals and the frame
del frame
> warnings.warn(message, category, stacklevel)
E matplotlib._api.deprecation.MatplotlibDeprecationWarning: Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will be removed in 3.10. To suppress this warning, explicitly call plt.close('all') first.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/matplotlib/_api/__init__.py:381: MatplotlibDeprecationWarning
During handling of the above exception, another exception occurred:
cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7fcca4b9b9c0>
when = 'call'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
@classmethod
def from_call(
cls,
func: Callable[[], TResult],
when: Literal["collect", "setup", "call", "teardown"],
reraise: Optional[
Union[Type[BaseException], Tuple[Type[BaseException], ...]]
] = None,
) -> "CallInfo[TResult]":
"""Call func, wrapping the result in a CallInfo.
:param func:
The function to call. Called without arguments.
:param when:
The phase in which the function is called.
:param reraise:
Exception or exceptions that shall propagate if raised by the
function, instead of being wrapped in the CallInfo.
"""
excinfo = None
start = timing.time()
precise_start = timing.perf_counter()
try:
> result: Optional[TResult] = func()
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/_pytest/runner.py:341:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/_pytest/runner.py:241: in <lambda>
lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
hook_name = 'pytest_runtest_call'
hook_impl = <HookImpl plugin_name='140517270421456', plugin=<pytest_mpl.plugin.ImageComparison object at 0x7fccb9fcffd0>>
e = MatplotlibDeprecationWarning("Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will be removed in 3.10. To suppress this warning, explicitly call plt.close('all') first.")
def _warn_teardown_exception(
hook_name: str, hook_impl: HookImpl, e: BaseException
) -> None:
msg = "A plugin raised an exception during an old-style hookwrapper teardown.\n"
msg += f"Plugin: {hook_impl.plugin_name}, Hook: {hook_name}\n"
msg += f"{type(e).__name__}: {e}\n"
msg += "For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning" # noqa: E501
> warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=5)
E pluggy.PluggyTeardownRaisedWarning: A plugin raised an exception during an old-style hookwrapper teardown.
E Plugin: 140517270421456, Hook: pytest_runtest_call
E MatplotlibDeprecationWarning: Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will be removed in 3.10. To suppress this warning, explicitly call plt.close('all') first.
E For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/pluggy/_callers.py:50: PluggyTeardownRaisedWarning
Check failure on line 90 in tests/cli/commands/test_plot.py
github-actions / JUnit Test Report - python 3.11, latest dependencies
test_plot.test_plot_no_long_name
DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
Raw output
datasets = PosixPath('/home/runner/work/emsarray/emsarray/tests/datasets')
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_plot_no_long_name0')
@pytest.mark.matplotlib(mock_coast=True)
@pytest.mark.tutorial
def test_plot_no_long_name(
datasets: pathlib.Path,
tmp_path: pathlib.Path,
):
"""
Test plotting a variable with no long_name attribute works.
Regression test for https://github.com/csiro-coasts/emsarray/issues/105
"""
dataset = emsarray.tutorial.open_dataset('fraser')
temp = dataset['temp'].copy()
temp = temp.isel(time=0, k=-1)
del temp.attrs['long_name']
> dataset.ems.plot(temp)
tests/test_plot.py:90:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:958: in plot
self.plot_on_figure(pyplot.figure(), *args, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/conventions/_base.py:940: in plot_on_figure
plot_on_figure(figure, self, **kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:339: in plot_on_figure
add_gridlines(axes)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/emsarray/plot.py:77: in add_gridlines
return axes.gridlines(**kwargs)
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1504: in gridlines
gl = Gridliner(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <cartopy.mpl.gridliner.Gridliner object at 0x7fcc9ff6b190>
axes = <GeoAxes: title={'center': 'temp\n2022-05-11T14:00'}>
crs = <Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]...thod: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
draw_labels = ['left', 'bottom'], xlocator = None, ylocator = None
collection_kwargs = {}
xformatter = <cartopy.mpl.ticker.LongitudeFormatter object at 0x7fcca4709490>
yformatter = <cartopy.mpl.ticker.LatitudeFormatter object at 0x7fcc9ff1c610>
dms = False, x_inline = None, y_inline = None, auto_inline = True, xlim = None
ylim = None, rotate_labels = False, xlabel_style = None, ylabel_style = None
labels_bbox_style = None, xpadding = 5, ypadding = 5, offset_angle = 25
auto_update = True, formatter_kwargs = {'dms': False}
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,
xlim=None, ylim=None, rotate_labels=None,
xlabel_style=None, ylabel_style=None, labels_bbox_style=None,
xpadding=5, ypadding=5, offset_angle=25,
auto_update=None, formatter_kwargs=None):
"""
Artist used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines`
to add gridlines and tick labels to a map.
Parameters
----------
axes
The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on.
crs
The :class:`cartopy.crs.CRS` defining the coordinate system that
the gridlines are drawn in.
draw_labels: optional
Toggle whether to draw labels. For finer control, attributes of
:class:`Gridliner` may be modified individually. Defaults to False.
- string: "x" or "y" to only draw labels of the respective
coordinate in the CRS.
- list: Can contain the side identifiers and/or coordinate
types to select which ones to draw.
For all labels one would use
`["x", "y", "top", "bottom", "left", "right", "geo"]`.
- dict: The keys are the side identifiers
("top", "bottom", "left", "right") and the values are the
coordinates ("x", "y"); this way you can precisely
decide what kind of label to draw and where.
For x labels on the bottom and y labels on the right you
could pass in `{"bottom": "x", "left": "y"}`.
Note that, by default, x and y labels are not drawn on left/right
and top/bottom edges respectively, unless explicitly requested.
xlocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the x-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
ylocator: optional
A :class:`matplotlib.ticker.Locator` instance which will be used
to determine the locations of the gridlines in the y-coordinate of
the given CRS. Defaults to None, which implies automatic locating
of the gridlines.
xformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for x-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
yformatter: optional
A :class:`matplotlib.ticker.Formatter` instance to format labels
for y-coordinate gridlines. It defaults to None, which implies the
use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated
with the ``dms`` argument, if the crs is of
:class:`~cartopy.crs.PlateCarree` type.
collection_kwargs: optional
Dictionary controlling line properties, passed to
:class:`matplotlib.collections.Collection`. Defaults to None.
dms: bool
When default locators and formatters are used,
ticks are able to stop on minutes and seconds if minutes
is set to True, and not fraction of degrees.
x_inline: optional
Toggle whether the x labels drawn should be inline.
y_inline: optional
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).
rotate_labels: optional, bool, str
Allow the rotation of non-inline labels.
- False: Do not rotate the labels.
- True: Rotate the labels parallel to the gridlines.
- None: no rotation except for some projections (default).
- A float: Rotate labels by this value in degrees.
xlabel_style: dict
A dictionary passed through to ``ax.text`` on x label creation
for styling of the text labels.
ylabel_style: dict
A dictionary passed through to ``ax.text`` on y label creation
for styling of the text labels.
labels_bbox_style: dict
bbox style for all text labels
xpadding: float
Padding for x labels. If negative, the labels are
drawn inside the map.
ypadding: float
Padding for y labels. If negative, the labels are
drawn inside the map.
offset_angle: float
Difference of angle in degrees from 90 to define when
a label must be flipped to be more readable.
For example, a value of 10 makes a vertical top label to be
flipped only at 100 degrees.
auto_update: bool, default=True
Whether to redraw the gridlines and labels when the figure is
updated.
.. deprecated:: 0.23
In future the gridlines and labels will always be redrawn.
formatter_kwargs: dict, optional
Options passed to the default formatters.
See :class:`~cartopy.mpl.ticker.LongitudeFormatter` and
:class:`~cartopy.mpl.ticker.LatitudeFormatter`
Notes
-----
The "x" and "y" labels for locators and formatters do not necessarily
correspond to X and Y, but to the first and second coordinates of the
specified CRS. For the common case of PlateCarree gridlines, these
correspond to longitudes and latitudes. Depending on the projection
used for the map, meridians and parallels can cross both the X axis and
the Y axis.
"""
super().__init__()
# We do not want the labels clipped to axes.
self.set_clip_on(False)
# Backcompat: the LineCollection was previously added directly to the
# axes, having a default zorder of 2.
self.set_zorder(2)
#: The :class:`~matplotlib.ticker.Locator` to use for the x
#: gridlines and labels.
if xlocator is not None:
if not isinstance(xlocator, mticker.Locator):
xlocator = mticker.FixedLocator(xlocator)
self.xlocator = xlocator
elif isinstance(crs, PlateCarree):
self.xlocator = LongitudeLocator(dms=dms)
else:
self.xlocator = classic_locator
#: The :class:`~matplotlib.ticker.Locator` to use for the y
#: gridlines and labels.
if ylocator is not None:
if not isinstance(ylocator, mticker.Locator):
ylocator = mticker.FixedLocator(ylocator)
self.ylocator = ylocator
elif isinstance(crs, PlateCarree):
self.ylocator = LatitudeLocator(dms=dms)
else:
self.ylocator = classic_locator
formatter_kwargs = {
**(formatter_kwargs or {}),
"dms": dms,
}
if xformatter is None:
if isinstance(crs, PlateCarree):
xformatter = LongitudeFormatter(**formatter_kwargs)
else:
xformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels.
self.xformatter = xformatter
if yformatter is None:
if isinstance(crs, PlateCarree):
yformatter = LatitudeFormatter(**formatter_kwargs)
else:
yformatter = classic_formatter()
#: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels.
self.yformatter = yformatter
# Draw label argument
if isinstance(draw_labels, list):
# Select to which coordinate it is applied
if 'x' not in draw_labels and 'y' not in draw_labels:
value = True
elif 'x' in draw_labels and 'y' in draw_labels:
value = ['x', 'y']
elif 'x' in draw_labels:
value = 'x'
else:
value = 'y'
#: Whether to draw labels on the top of the map.
self.top_labels = value if 'top' in draw_labels else False
#: Whether to draw labels on the bottom of the map.
self.bottom_labels = value if 'bottom' in draw_labels else False
#: Whether to draw labels on the left hand side of the map.
self.left_labels = value if 'left' in draw_labels else False
#: Whether to draw labels on the right hand side of the map.
self.right_labels = value if 'right' in draw_labels else False
#: Whether to draw labels near the geographic limits of the map.
self.geo_labels = value if 'geo' in draw_labels else False
elif isinstance(draw_labels, dict):
self.top_labels = draw_labels.get('top', False)
self.bottom_labels = draw_labels.get('bottom', False)
self.left_labels = draw_labels.get('left', False)
self.right_labels = draw_labels.get('right', False)
self.geo_labels = draw_labels.get('geo', False)
else:
self.top_labels = draw_labels
self.bottom_labels = draw_labels
self.left_labels = draw_labels
self.right_labels = draw_labels
self.geo_labels = draw_labels
for loc in 'top', 'bottom', 'left', 'right', 'geo':
value = getattr(self, f'{loc}_labels')
if isinstance(value, str):
value = value.lower()
if (not isinstance(value, (list, bool)) and
value not in ('x', 'y')):
raise ValueError(f"Invalid draw_labels argument: {value}")
if auto_inline:
if isinstance(axes.projection, _X_INLINE_PROJS):
self.x_inline = True
self.y_inline = False
elif isinstance(axes.projection, _POLAR_PROJS):
self.x_inline = False
self.y_inline = True
else:
self.x_inline = False
self.y_inline = False
# overwrite auto_inline if necessary
if x_inline is not None:
#: Whether to draw x labels inline
self.x_inline = x_inline
elif not auto_inline:
self.x_inline = False
if y_inline is not None:
#: Whether to draw y labels inline
self.y_inline = y_inline
elif not auto_inline:
self.y_inline = False
# Apply inline args
if not draw_labels:
self.inline_labels = False
elif self.x_inline and self.y_inline:
self.inline_labels = True
elif self.x_inline:
self.inline_labels = "x"
elif self.y_inline:
self.inline_labels = "y"
else:
self.inline_labels = 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
#: Whether to draw the y gridlines.
self.ylines = True
#: A dictionary passed through to ``ax.text`` on x label creation
#: for styling of the text labels.
self.xlabel_style = xlabel_style or {}
#: A dictionary passed through to ``ax.text`` on y label creation
#: for styling of the text labels.
self.ylabel_style = ylabel_style or {}
#: bbox style for grid labels
self.labels_bbox_style = (
labels_bbox_style or {'pad': 0, 'visible': False})
#: The padding from the map edge to the x labels in points.
self.xpadding = xpadding
#: The padding from the map edge to the y labels in points.
self.ypadding = ypadding
#: Control the rotation of labels.
if rotate_labels is None:
rotate_labels = (
axes.projection.__class__ in _ROTATE_LABEL_PROJS)
if not isinstance(rotate_labels, (bool, float, int)):
raise ValueError("Invalid rotate_labels argument")
self.rotate_labels = rotate_labels
self.offset_angle = offset_angle
# Current transform
self.crs = crs
# if the user specifies tick labels at this point, check if they can
# be drawn. The same check will take place at draw time in case
# public attributes are changed after instantiation.
if draw_labels and not (x_inline or y_inline or auto_inline):
self._assert_can_draw_ticks()
#: The number of interpolation points which are used to draw the
#: gridlines.
self.n_steps = 100
#: A dictionary passed through to
#: ``matplotlib.collections.LineCollection`` on grid line creation.
self.collection_kwargs = collection_kwargs
#: The x gridlines which were created at draw time.
self.xline_artists = []
#: The y gridlines which were created at draw time.
self.yline_artists = []
# List of all labels (Label objects)
self._all_labels = []
# List of active labels (used in current draw)
self._labels = []
# Draw status
self._drawn = False
if auto_update is None:
auto_update = True
else:
> warnings.warn(
"The auto_update parameter was deprecated at Cartopy 0.23. In future "
"the gridlines and labels will always be updated.",
DeprecationWarning)
E DeprecationWarning: The auto_update parameter was deprecated at Cartopy 0.23. In future the gridlines and labels will always be updated.
/usr/share/miniconda/envs/test/lib/python3.11/site-packages/cartopy/mpl/gridliner.py:450: DeprecationWarning