Skip to content

Commit

Permalink
Add [xy]offsetloc keywords, follow other locs by default
Browse files Browse the repository at this point in the history
  • Loading branch information
lukelbd committed Sep 27, 2021
1 parent 1fa90f8 commit 96a37e5
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions proplot/axes/cartesian.py
Expand Up @@ -52,19 +52,22 @@
``xscale=('cutoff', 100, 2)`` applies a `~proplot.scale.CutoffScale`.
xscale_kw, yscale_kw : dict-like, optional
The x and y axis scale settings. Passed to `~proplot.scale.Scale`.
xspineloc, yspineloc \
: {'bottom', 'top', 'left', 'right', 'both', 'neither', 'center', 'zero'}, optional
xspineloc, yspineloc : {'bottom', 'top', 'left', 'right', \
'both', 'neither', 'none', 'center', 'zero'}, optional
The x and y axis spine locations.
xtickloc, ytickloc \
: {'bottom', 'top', 'left', 'right', 'both', 'neither'}, optional
: {'bottom', 'top', 'left', 'right', 'both', 'neither', 'none'}, optional
Which x and y axis spines should have major and minor tick marks.
xticklabelloc, yticklabelloc \
: {'bottom', 'top', 'left', 'right', 'both', 'neither'}, optional
: {'bottom', 'top', 'left', 'right', 'both', 'neither', 'none'}, optional
Which x and y axis spines should have major tick labels. Default
behavior is to inherit this from `xtickloc` and `ytickloc`.
xlabelloc, ylabelloc : {'bottom', 'top', 'left', 'right'}, optional
Which x and y axis spines should have axis labels. Default
behavior is to inherit this from `xticklabelloc` and `yticklabelloc`.
xoffsetloc, yoffsetloc : {'bottom', 'top', 'left', 'right'}, optional
Which x and y axis spines should have the axis offset indicator. Default
behavior is to inherit this from `xticklabelloc` and `yticklabelloc`.
xtickdir, ytickdir, tickdir : {'out', 'in', 'inout'}
Direction that major and minor tick marks point for the x and y axis.
Use `tickdir` to control both.
Expand Down Expand Up @@ -702,7 +705,9 @@ def _update_spines(self, x, *, loc=None, bounds=None):
if bounds is not None:
spine.set_bounds(*bounds)

def _update_locs(self, x, *, tickloc=None, ticklabelloc=None, labelloc=None):
def _update_locs(
self, x, *, tickloc=None, ticklabelloc=None, labelloc=None, offsetloc=None
):
"""
Update the tick, tick label, and axis label locations.
"""
Expand All @@ -713,12 +718,18 @@ def _update_locs(self, x, *, tickloc=None, ticklabelloc=None, labelloc=None):
sides_dict = {None: None, 'both': sides, 'none': (), 'neither': ()}

# The tick side(s)
# NOTE: Silently forbids adding ticks to sides with invisible spines
ticklocs = sides_dict.get(tickloc, (tickloc,))
if ticklocs is not None:
kw.update({side: side in ticklocs for side in sides})
kw.update({side: False for side in sides if side not in sides_active})
kw.update(
{
side: False for side in sides if side not in sides_active
}
)

# The tick label side(s). Make sure these only appear where ticks are
# NOTE: Silently forbids adding labels to sides with invisible ticks or spines
ticklabellocs = sides_dict.get(ticklabelloc, (ticklabelloc,))
if ticklabellocs is not None:
kw.update({'label' + side: (side in ticklabellocs) for side in sides})
Expand All @@ -731,21 +742,25 @@ def _update_locs(self, x, *, tickloc=None, ticklabelloc=None, labelloc=None):
)

# The axis label side(s)
if labelloc is None:
if ticklocs is not None:
options = tuple(_ for _ in sides if _ in ticklocs and _ in sides_active)
if len(options) == 1:
labelloc = options[0]
# NOTE: Silently forbids adding labels and offsets to sides with missing spines
if ticklocs is not None:
options = tuple(_ for _ in sides if _ in ticklocs and _ in sides_active)
if len(options) == 1:
labelloc = _not_none(labelloc, options[0])
offsetloc = _not_none(offsetloc, options[0])
if labelloc is not None and labelloc not in sides:
raise ValueError(
f'Invalid label location {labelloc!r}. Options are '
+ ', '.join(map(repr, sides)) + '.'
)

# Apply the tick, tick label, and label locations
axis = getattr(self, x + 'axis')
self.tick_params(axis=x, which='both', **kw)
if labelloc is not None:
getattr(self, x + 'axis').set_label_position(labelloc)
axis.set_label_position(labelloc)
if offsetloc is not None:
axis.set_offset_position(offsetloc)

@warnings._rename_kwargs('0.9', xloc='xspineloc', yloc='yspineloc')
@docstring._snippet_manager
Expand All @@ -756,6 +771,7 @@ def format(
xspineloc=None, yspineloc=None,
xtickloc=None, ytickloc=None, fixticks=False,
xlabelloc=None, ylabelloc=None,
xoffsetloc=None, yoffsetloc=None,
xticklabelloc=None, yticklabelloc=None,
xtickdir=None, ytickdir=None,
xgrid=None, ygrid=None,
Expand Down Expand Up @@ -863,10 +879,12 @@ def format(
xticklabelloc = _not_none(xticklabelloc, xtickloc)
if xticklabelloc in ('bottom', 'top'):
xlabelloc = _not_none(xlabelloc, xticklabelloc)
xoffsetloc = _not_none(xoffsetloc, xticklabelloc)
if ytickloc != 'both': # then infer others
yticklabelloc = _not_none(yticklabelloc, ytickloc)
if yticklabelloc in ('left', 'right'):
ylabelloc = _not_none(ylabelloc, yticklabelloc)
ylabelloc = _not_none(yoffsetloc, yticklabelloc)

# Loop over axes
for (
Expand All @@ -877,6 +895,7 @@ def format(
margin, bounds,
tickloc, spineloc,
ticklabelloc, labelloc,
offsetloc,
grid, gridminor,
tickminor, minorlocator,
min_, max_, lim,
Expand All @@ -896,6 +915,7 @@ def format(
(xmargin, ymargin), (xbounds, ybounds),
(xtickloc, ytickloc), (xspineloc, yspineloc),
(xticklabelloc, yticklabelloc), (xlabelloc, ylabelloc),
(xoffsetloc, yoffsetloc),
(xgrid, ygrid), (xgridminor, ygridminor),
(xtickminor, ytickminor), (xminorlocator, yminorlocator),
(xmin, ymin), (xmax, ymax), (xlim, ylim),
Expand Down Expand Up @@ -934,7 +954,8 @@ def format(

# Axis tick settings
self._update_locs(
x, tickloc=tickloc, ticklabelloc=ticklabelloc, labelloc=labelloc
x, tickloc=tickloc, ticklabelloc=ticklabelloc,
labelloc=labelloc, offsetloc=offsetloc,
)
self._update_rotation(
x, rotation=rotation
Expand Down

0 comments on commit 96a37e5

Please sign in to comment.