Skip to content

Add Axes.get_tick_params() method. #23692

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

Merged
merged 14 commits into from
Nov 23, 2022
Merged
1 change: 1 addition & 0 deletions doc/api/axis_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Ticks, tick labels and Offset text
Axis.get_offset_text

Axis.get_tick_padding
Axis.get_tick_params
Axis.get_ticklabels
Axis.get_ticklines
Axis.get_ticklocs
Expand Down
29 changes: 29 additions & 0 deletions doc/users/next_whats_new/view_current_axis_format.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
View current appearance settings for ticks, tick labels, and gridlines
----------------------------------------------------------------------

The new `~matplotlib.axis.Axis.get_tick_params` method can be used to
retrieve the appearance settings that will be applied to any
additional ticks, tick labels, and gridlines added to the plot:

.. code-block:: pycon

>>> import matplotlib.pyplot as plt

>>> fig, ax = plt.subplots()
>>> ax.yaxis.set_tick_params(labelsize=30, labelcolor='red',
... direction='out', which='major')
>>> ax.yaxis.get_tick_params(which='major')
{'direction': 'out',
'left': True,
'right': False,
'labelleft': True,
'labelright': False,
'gridOn': False,
'labelsize': 30,
'labelcolor': 'red'}
>>> ax.yaxis.get_tick_params(which='minor')
{'left': True,
'right': False,
'labelleft': True,
'labelright': False,
'gridOn': False}
3 changes: 2 additions & 1 deletion lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3403,7 +3403,8 @@ def tick_params(self, axis='both', **kwargs):
Change the appearance of ticks, tick labels, and gridlines.

Tick properties that are not explicitly set using the keyword
arguments remain unchanged unless *reset* is True.
arguments remain unchanged unless *reset* is True. For the current
style settings, see `.Axis.get_tick_params`.

Parameters
----------
Expand Down
89 changes: 80 additions & 9 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,12 @@ def set_tick_params(self, which='major', reset=False, **kwargs):

For documentation of keyword arguments, see
:meth:`matplotlib.axes.Axes.tick_params`.

See Also
--------
.Axis.get_tick_params
View the current style settings for ticks, ticklabels, and
gridlines.
"""
_api.check_in_list(['major', 'minor', 'both'], which=which)
kwtrans = self._translate_tick_params(kwargs)
Expand Down Expand Up @@ -949,8 +955,62 @@ def set_tick_params(self, which='major', reset=False, **kwargs):

self.stale = True

def get_tick_params(self, which='major'):
"""
Get appearance parameters for ticks, ticklabels, and gridlines.

.. versionadded:: 3.7

Parameters
----------
which : {'major', 'minor'}, default: 'major'
The group of ticks for which the parameters are retrieved.

Returns
-------
dict
Properties for styling tick elements added to the axis.

Notes
-----
This method returns the appearance parameters for styling *new*
elements added to this axis and may be different from the values
on current elements if they were modified directly by the user
(e.g., via ``set_*`` methods on individual tick objects).

Examples
--------
::

>>> ax.yaxis.set_tick_params(labelsize=30, labelcolor='red',
direction='out', which='major')
>>> ax.yaxis.get_tick_params(which='major')
{'direction': 'out',
'left': True,
'right': False,
'labelleft': True,
'labelright': False,
'gridOn': False,
'labelsize': 30,
'labelcolor': 'red'}
>>> ax.yaxis.get_tick_params(which='minor')
{'left': True,
'right': False,
'labelleft': True,
'labelright': False,
'gridOn': False}


"""
_api.check_in_list(['major', 'minor'], which=which)
if which == 'major':
return self._translate_tick_params(
self._major_tick_kw, reverse=True
)
return self._translate_tick_params(self._minor_tick_kw, reverse=True)

@staticmethod
def _translate_tick_params(kw):
def _translate_tick_params(kw, reverse=False):
"""
Translate the kwargs supported by `.Axis.set_tick_params` to kwargs
supported by `.Tick._apply_params`.
Expand All @@ -961,9 +1021,12 @@ def _translate_tick_params(kw):

Returns a new dict of translated kwargs.

Note: The input *kwargs* are currently modified, but that's ok for
the only caller.
Note: Use reverse=True to translate from those supported by
`.Tick._apply_params` back to those supported by
`.Axis.set_tick_params`.
"""
kw_ = {**kw}

# The following lists may be moved to a more accessible location.
allowed_keys = [
'size', 'width', 'color', 'tickdir', 'pad',
Expand All @@ -988,19 +1051,27 @@ def _translate_tick_params(kw):
'labelright': 'label2On',
'labeltop': 'label2On',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labelleft & labelbottom have the same axis key, the translation will therefore always return labelleft and labelright, also for the x-axis. This is confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please open a new issue with the details of what you are seeing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done, see #28772

}
kwtrans = {newkey: kw.pop(oldkey)
for oldkey, newkey in keymap.items() if oldkey in kw}
if 'colors' in kw:
c = kw.pop('colors')
if reverse:
kwtrans = {
oldkey: kw_.pop(newkey)
for oldkey, newkey in keymap.items() if newkey in kw_
}
else:
kwtrans = {
newkey: kw_.pop(oldkey)
for oldkey, newkey in keymap.items() if oldkey in kw_
}
if 'colors' in kw_:
c = kw_.pop('colors')
kwtrans['color'] = c
kwtrans['labelcolor'] = c
# Maybe move the checking up to the caller of this method.
for key in kw:
for key in kw_:
if key not in allowed_keys:
raise ValueError(
"keyword %s is not recognized; valid keywords are %s"
% (key, allowed_keys))
kwtrans.update(kw)
kwtrans.update(kw_)
return kwtrans

def set_clip_path(self, clippath, transform=None):
Expand Down
27 changes: 27 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6452,6 +6452,33 @@ def test_pandas_bar_align_center(pd):
fig.canvas.draw()


def test_axis_get_tick_params():
axis = plt.subplot().yaxis
initial_major_style_translated = {**axis.get_tick_params(which='major')}
initial_minor_style_translated = {**axis.get_tick_params(which='minor')}

translated_major_kw = axis._translate_tick_params(
axis._major_tick_kw, reverse=True
)
translated_minor_kw = axis._translate_tick_params(
axis._minor_tick_kw, reverse=True
)

assert translated_major_kw == initial_major_style_translated
assert translated_minor_kw == initial_minor_style_translated
axis.set_tick_params(labelsize=30, labelcolor='red',
direction='out', which='both')

new_major_style_translated = {**axis.get_tick_params(which='major')}
new_minor_style_translated = {**axis.get_tick_params(which='minor')}
new_major_style = axis._translate_tick_params(new_major_style_translated)
new_minor_style = axis._translate_tick_params(new_minor_style_translated)
assert initial_major_style_translated != new_major_style_translated
assert axis._major_tick_kw == new_major_style
assert initial_minor_style_translated != new_minor_style_translated
assert axis._minor_tick_kw == new_minor_style


def test_axis_set_tick_params_labelsize_labelcolor():
# Tests fix for issue 4346
axis_1 = plt.subplot()
Expand Down