Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow passing axis kwargs to plot #4020

Merged
merged 34 commits into from Jul 2, 2020
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0d4d29a
fix facecolor plot
raphaeldussin May 2, 2020
04a48c4
temp version
raphaeldussin May 15, 2020
2577ddd
finish fix facecolor + solves #3169
raphaeldussin May 16, 2020
c5c7732
black formatting
raphaeldussin May 16, 2020
9d259e2
add testing
raphaeldussin May 16, 2020
2d7cf27
allow cartopy projection to be a kwarg
raphaeldussin May 16, 2020
19b59a3
fix PEP8 comment
raphaeldussin May 16, 2020
d439f6b
black formatting
raphaeldussin May 16, 2020
2d5b599
fix testing, plt not in parameterize
raphaeldussin May 16, 2020
4d00aeb
fix testing, allows for no matplotlib
raphaeldussin May 16, 2020
7c80566
Merge branch 'fix_facecolor_plot' of https://github.com/raphaeldussin…
raphaeldussin May 16, 2020
ba36f83
black formating
raphaeldussin May 16, 2020
f7c48be
fix tests without matplotlib
raphaeldussin May 16, 2020
180d451
fix some mistakes
raphaeldussin May 16, 2020
e8abe18
isort, mypy
raphaeldussin May 16, 2020
7c46b01
fix mypy
raphaeldussin May 16, 2020
2739599
Merge remote-tracking branch 'xarray/master' into fix_facecolor_plot
raphaeldussin Jun 12, 2020
5f30e7c
remove empty line
raphaeldussin Jun 23, 2020
aebb441
correction from review
raphaeldussin Jun 23, 2020
38fbfde
correction from 2nd review
raphaeldussin Jun 24, 2020
66e07df
updated tests
raphaeldussin Jun 24, 2020
3a12e86
updated tests
raphaeldussin Jun 24, 2020
cdeea2f
Merge branch 'fix_facecolor_plot' of https://github.com/raphaeldussin…
raphaeldussin Jun 25, 2020
ee25c00
black formatting
raphaeldussin Jun 25, 2020
7ae74fe
follow up correction from review
raphaeldussin Jun 25, 2020
a049209
fix tests
raphaeldussin Jun 25, 2020
98264bd
fix tests again
raphaeldussin Jun 25, 2020
79b08db
fix bug in tests
raphaeldussin Jun 25, 2020
f54d585
fix pb in tests
raphaeldussin Jun 25, 2020
1cec6cd
remove useless line
raphaeldussin Jun 25, 2020
073c64b
clean up tests
dcherian Jun 29, 2020
a652843
fix
dcherian Jun 29, 2020
d65416a
Add whats-new
dcherian Jul 1, 2020
b1c15ad
Merge remote-tracking branch 'upstream/master' into fix_facecolor_plot
dcherian Jul 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions doc/plotting.rst
Expand Up @@ -743,12 +743,13 @@ This script will plot the air temperature on a map.

air = xr.tutorial.open_dataset("air_temperature").air

ax = plt.axes(projection=ccrs.Orthographic(-80, 35))
air.isel(time=0).plot.contourf(ax=ax, transform=ccrs.PlateCarree())
ax.set_global()
p = air.isel(time=0).plot(
subplot_kws=dict(projection=ccrs.Orthographic(-80, 35), facecolor="gray"),
transform=ccrs.PlateCarree())
p.axes.set_global()

@savefig plotting_maps_cartopy.png width=100%
ax.coastlines()
p.axes.coastlines()

When faceting on maps, the projection can be transferred to the ``plot``
function using the ``subplot_kws`` keyword. The axes for the subplots created
Expand Down
14 changes: 8 additions & 6 deletions xarray/plot/plot.py
Expand Up @@ -155,8 +155,7 @@ def plot(
Relative tolerance used to determine if the indexes
are uniformly spaced. Usually a small positive number.
subplot_kws : dict, optional
Dictionary of keyword arguments for matplotlib subplots. Only applies
to FacetGrid plotting.
Dictionary of keyword arguments for matplotlib subplots.
**kwargs : optional
Additional keyword arguments to matplotlib

Expand All @@ -177,10 +176,10 @@ def plot(

raphaeldussin marked this conversation as resolved.
Show resolved Hide resolved
if ndims in [1, 2]:
if row or col:
kwargs["subplot_kws"] = subplot_kws
raphaeldussin marked this conversation as resolved.
Show resolved Hide resolved
kwargs["row"] = row
kwargs["col"] = col
kwargs["col_wrap"] = col_wrap
kwargs["subplot_kws"] = subplot_kws
if ndims == 1:
plotfunc = line
kwargs["hue"] = hue
Expand All @@ -190,6 +189,7 @@ def plot(
kwargs["hue"] = hue
else:
plotfunc = pcolormesh
kwargs["subplot_kws"] = subplot_kws
raphaeldussin marked this conversation as resolved.
Show resolved Hide resolved
else:
if row or col or hue:
raise ValueError(error_msg)
Expand Down Expand Up @@ -548,8 +548,7 @@ def _plot2d(plotfunc):
always infer intervals, unless the mesh is irregular and plotted on
a map projection.
subplot_kws : dict, optional
Dictionary of keyword arguments for matplotlib subplots. Only applies
to FacetGrid plotting.
Dictionary of keyword arguments for matplotlib subplots.
dcherian marked this conversation as resolved.
Show resolved Hide resolved
cbar_ax : matplotlib Axes, optional
Axes in which to draw the colorbar.
cbar_kwargs : dict, optional
Expand Down Expand Up @@ -719,7 +718,10 @@ def newplotfunc(
"plt.imshow's `aspect` kwarg is not available " "in xarray"
)

ax = get_axis(figsize, size, aspect, ax)
if subplot_kws is None:
subplot_kws = dict()
ax = get_axis(figsize, size, aspect, ax, **subplot_kws)
raphaeldussin marked this conversation as resolved.
Show resolved Hide resolved

primitive = plotfunc(
xplt,
yplt,
Expand Down
14 changes: 10 additions & 4 deletions xarray/plot/utils.py
Expand Up @@ -406,9 +406,12 @@ def _assert_valid_xy(darray, xy, name):
raise ValueError(f"{name} must be one of None, '{valid_xy_str}'")


def get_axis(figsize, size, aspect, ax):
import matplotlib as mpl
import matplotlib.pyplot as plt
def get_axis(figsize=None, size=None, aspect=None, ax=None, **kwargs):
try:
import matplotlib as mpl
import matplotlib.pyplot as plt
except ImportError:
raise ImportError("matplotlib is required for plot.utils.get_axis")

if figsize is not None:
if ax is not None:
Expand All @@ -427,8 +430,11 @@ def get_axis(figsize, size, aspect, ax):
elif aspect is not None:
raise ValueError("cannot provide `aspect` argument without `size`")

if kwargs and ax is not None:
raise ValueError("cannot use subplot_kws with existing ax")

if ax is None:
ax = plt.gca()
ax = plt.gca(**kwargs)

return ax

Expand Down
48 changes: 48 additions & 0 deletions xarray/tests/test_plot.py
Expand Up @@ -15,6 +15,7 @@
_build_discrete_cmap,
_color_palette,
_determine_cmap_params,
get_axis,
label_from_attrs,
)

Expand Down Expand Up @@ -2381,3 +2382,50 @@ def test_facetgrid_single_contour():
ds["time"] = [0, 1]

ds.plot.contour(col="time", levels=[4], colors=["k"])


dcherian marked this conversation as resolved.
Show resolved Hide resolved
@requires_matplotlib
@pytest.mark.parametrize("figsize", [[4, 4], None])
@pytest.mark.parametrize("aspect", [4 / 3, None])
@pytest.mark.parametrize("size", [200, None])
def test_get_axis(figsize, aspect, size):
# test get_axis works with different args combinations
# and return the right type

ax = "something"
if figsize is not None:
dcherian marked this conversation as resolved.
Show resolved Hide resolved
# cannot provide both ax and figsize
with pytest.raises(ValueError, match="both `figsize` and `ax`"):
ax = get_axis(figsize, size, aspect, ax)
if figsize is None and size is not None:
# cannot provide both ax and size
with pytest.raises(ValueError, match="both `size` and `ax`"):
ax = get_axis(figsize, size, aspect, ax)

ax = None
if figsize is not None and size is not None:
# cannot provide both size and figsize
with pytest.raises(ValueError, match="both `figsize` and " "`size`"):
ax = get_axis(figsize, size, aspect, ax)

if figsize is None and aspect is not None and size is None:
# cannot provide aspect and size
with pytest.raises(ValueError, match="`aspect` argument without `size`"):
ax = get_axis(figsize, size, aspect, ax)

ax = plt.axes()
axtype = type(ax)
ax = get_axis(ax=ax)
assert isinstance(ax, axtype)
dcherian marked this conversation as resolved.
Show resolved Hide resolved
ax = get_axis()
assert isinstance(ax, axtype)

try:
dcherian marked this conversation as resolved.
Show resolved Hide resolved
import cartopy as ctpy # type: ignore
raphaeldussin marked this conversation as resolved.
Show resolved Hide resolved

kwargs = {"projection": ctpy.crs.PlateCarree()}
ax = get_axis(**kwargs)
assert isinstance(ax, ctpy.mpl.geoaxes.GeoAxesSubplot)
except ImportError:
# not testing cartopy
pass