Skip to content

Switch AxisArtist to use standard tick directions. #19102

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 37 additions & 22 deletions lib/mpl_toolkits/axisartist/axis_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@

The following attributes can be customized (use the ``set_xxx`` methods):

* `Ticks`: ticksize, tick_out
* `Ticks`: ticksize, tickdir
* `TickLabels`: pad
* `AxisLabel`: pad
"""
Expand Down Expand Up @@ -123,12 +123,12 @@ class Ticks(AttributeCopier, Line2D):
Ticks are derived from Line2D, and note that ticks themselves
are markers. Thus, you should use set_mec, set_mew, etc.

To change the tick size (length), you need to use
set_ticksize. To change the direction of the ticks (ticks are
in opposite direction of ticklabels by default), use
set_tick_out(False).
To change the tick size (length), use set_ticksize. To change the
direction of the ticks, use set_tickdir ("out" corresponds to the side of
the label, "in" to the opposite side).
"""

# tick_out is mostly deprecated in favor of tickdir.
def __init__(self, ticksize, tick_out=False, *, axis=None, **kwargs):
self._ticksize = ticksize
self.locs_angles_labels = []
Expand Down Expand Up @@ -158,13 +158,24 @@ def get_markeredgecolor(self):
def get_markeredgewidth(self):
return self.get_attribute_from_ref_artist("markeredgewidth")

def set_tickdir(self, tickdir):
_api.check_in_list(self._tick_paths, tickdir=tickdir)
self._tickdir = tickdir

def get_tickdir(self):
return self._tickdir

def set_tick_out(self, b):
"""Set whether ticks are drawn inside or outside the axes."""
self._tick_out = b
self.set_tickdir({True: "out", False: "in"}[bool(b)])

def get_tick_out(self):
"""Return whether ticks are drawn inside or outside the axes."""
return self._tick_out
if self._tickdir == "out":
return True
elif self._tickdir == "in":
return False
raise ValueError(f"tickdir is {self._tickdir}")

def set_ticksize(self, ticksize):
"""Set length of the ticks in points."""
Expand All @@ -177,7 +188,11 @@ def get_ticksize(self):
def set_locs_angles(self, locs_angles):
self.locs_angles = locs_angles

_tickvert_path = Path([[0., 0.], [1., 0.]])
_tick_paths = {
"out": Path([[0, 0], [-1, 0]]),
"in": Path([[0, 0], [1, 0]]),
"inout": Path([[-1/2, 0], [1/2, 0]]),
}

def draw(self, renderer):
if not self.get_visible():
Expand All @@ -191,15 +206,14 @@ def draw(self, renderer):
path_trans = self.get_transform()
marker_transform = (Affine2D()
.scale(renderer.points_to_pixels(self._ticksize)))
if self.get_tick_out():
marker_transform.rotate_deg(180)
tick_path = self._tick_paths[self._tickdir]

for loc, angle in self.locs_angles:
locs = path_trans.transform_non_affine(np.array([loc]))
if self.axes and not self.axes.viewLim.contains(*locs[0]):
continue
renderer.draw_markers(
gc, self._tickvert_path,
gc, tick_path,
marker_transform + Affine2D().rotate_deg(angle),
Path(locs), path_trans.get_affine())

Expand Down Expand Up @@ -844,11 +858,13 @@ def _init_ticks(self, **kwargs):
self.major_ticks = Ticks(
kwargs.get(
"major_tick_size", rcParams[f"{axis_name}tick.major.size"]),
axis=self.axis, transform=trans)
axis=self.axis, transform=trans,
tickdir=rcParams[f"{axis_name}tick.direction"])
self.minor_ticks = Ticks(
kwargs.get(
"minor_tick_size", rcParams[f"{axis_name}tick.minor.size"]),
axis=self.axis, transform=trans)
axis=self.axis, transform=trans,
tickdir=rcParams[f"{axis_name}tick.direction"])

size = rcParams[f"{axis_name}tick.labelsize"]
self.major_ticklabels = TickLabels(
Expand Down Expand Up @@ -897,14 +913,13 @@ def _update_ticks(self, renderer):
# majorticks even for minor ticks. not clear what is best.

dpi_cor = renderer.points_to_pixels(1.)
if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
self.major_ticklabels._set_external_pad(
self.major_ticks._ticksize * dpi_cor)
self.minor_ticklabels._set_external_pad(
self.major_ticks._ticksize * dpi_cor)
else:
self.major_ticklabels._set_external_pad(0)
self.minor_ticklabels._set_external_pad(0)
multiplier = (
self.major_ticks.get_visible()
* {"out": 1, "inout": .5, "in": 0}[self.major_ticks._tickdir])
self.major_ticklabels._set_external_pad(
multiplier * self.major_ticks._ticksize * dpi_cor)
self.minor_ticklabels._set_external_pad(
multiplier * self.major_ticks._ticksize * dpi_cor)

majortick_iter, minortick_iter = \
self._axis_artist_helper.get_tick_iterators(self.axes)
Expand Down Expand Up @@ -979,7 +994,7 @@ def _update_label(self, renderer):
return

if self._ticklabel_add_angle != self._axislabel_add_angle:
if ((self.major_ticks.get_visible()
if ((self.major_ticks.get_visible() # ???
and not self.major_ticks.get_tick_out())
or (self.minor_ticks.get_visible()
and not self.major_ticks.get_tick_out())):
Expand Down
3 changes: 2 additions & 1 deletion lib/mpl_toolkits/tests/test_axisartist_axis_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ def test_ticklabels():

@image_comparison(['axis_artist.png'], style='default')
def test_axis_artist():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig, ax = plt.subplots()

Expand Down
9 changes: 6 additions & 3 deletions lib/mpl_toolkits/tests/test_axisartist_axislines.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

@image_comparison(['SubplotZero.png'], style='default')
def test_SubplotZero():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure()

Expand All @@ -34,8 +35,9 @@ def test_SubplotZero():

@image_comparison(['Subplot.png'], style='default')
def test_Subplot():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure()

Expand Down Expand Up @@ -65,8 +67,9 @@ def test_Axes():
@image_comparison(['ParasiteAxesAuxTrans_meshplot.png'],
remove_text=True, style='default', tol=0.075)
def test_ParasiteAxesAuxTrans(parasite_cls):
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

data = np.ones((6, 6))
data[2, 2] = 2
Expand Down
6 changes: 5 additions & 1 deletion lib/mpl_toolkits/tests/test_axisartist_floating_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def test_subplot():

@image_comparison(['curvelinear3.png'], style='default', tol=0.01)
def test_curvelinear3():
# Remove this lines when this test image is regenerated.
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure(figsize=(5, 5))

tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) +
Expand Down Expand Up @@ -74,8 +77,9 @@ def test_curvelinear3():

@image_comparison(['curvelinear4.png'], style='default', tol=0.015)
def test_curvelinear4():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure(figsize=(5, 5))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
@image_comparison(['custom_transform.png'], style='default',
tol=0.03 if platform.machine() == 'x86_64' else 0.034)
def test_custom_transform():
# Remove this line when this test image is regenerated.
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

class MyTransform(Transform):
input_dims = output_dims = 2

Expand Down Expand Up @@ -82,8 +85,9 @@ def inverted(self):
@image_comparison(['polar_box.png'], style='default',
tol={'aarch64': 0.04}.get(platform.machine(), 0.03))
def test_polar_box():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure(figsize=(5, 5))

Expand Down Expand Up @@ -145,8 +149,9 @@ def test_polar_box():

@image_comparison(['axis_direction.png'], style='default', tol=0.03)
def test_axis_direction():
# Remove this line when this test image is regenerated.
# Remove these lines when this test image is regenerated.
plt.rcParams['text.kerning_factor'] = 6
plt.rcParams.update({"xtick.direction": "in", "ytick.direction": "in"})

fig = plt.figure(figsize=(5, 5))

Expand Down