Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3690cb

Browse files
authored
Merge pull request #10193 from efiring/gridline_properties
Handle Tick gridline properties like other Tick properties
2 parents 0bcc13f + ee35e58 commit e3690cb

File tree

5 files changed

+111
-62
lines changed

5 files changed

+111
-62
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
`Axes.tick_params` can set gridline properties
2+
----------------------------------------------
3+
4+
`Tick` objects hold gridlines as well as the tick mark and its label.
5+
`Axis.set_tick_params`, `Axes.tick_params` and `pyplot.tick_params`
6+
now have keyword arguments 'grid_color', 'grid_alpha', 'grid_linewidth',
7+
and 'grid_linestyle' for overriding the defaults in `rcParams`:
8+
'grid.color', etc.

lib/matplotlib/axes/_base.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2790,7 +2790,7 @@ def locator_params(self, axis='both', tight=None, **kwargs):
27902790
self.autoscale_view(tight=tight, scalex=_x, scaley=_y)
27912791

27922792
def tick_params(self, axis='both', **kwargs):
2793-
"""Change the appearance of ticks and tick labels.
2793+
"""Change the appearance of ticks, tick labels, and gridlines.
27942794
27952795
Parameters
27962796
----------
@@ -2848,16 +2848,29 @@ def tick_params(self, axis='both', **kwargs):
28482848
labelrotation : float
28492849
Tick label rotation
28502850
2851+
grid_color : color
2852+
Changes the gridline color to the given mpl color spec.
2853+
2854+
grid_alpha : float
2855+
Transparency of gridlines: 0 (transparent) to 1 (opaque).
2856+
2857+
grid_linewidth : float
2858+
Width of gridlines in points.
2859+
2860+
grid_linestyle : string
2861+
Any valid :class:`~matplotlib.lines.Line2D` line style spec.
2862+
28512863
Examples
28522864
--------
28532865
28542866
Usage ::
28552867
2856-
ax.tick_params(direction='out', length=6, width=2, colors='r')
2868+
ax.tick_params(direction='out', length=6, width=2, colors='r',
2869+
grid_color='r', grid_alpha=0.5)
28572870
28582871
This will make all major ticks be red, pointing out of the box,
28592872
and with dimensions 6 points by 2 points. Tick labels will
2860-
also be red.
2873+
also be red. Gridlines will be red and translucent.
28612874
28622875
"""
28632876
if axis in ['x', 'both']:

lib/matplotlib/axis.py

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828

2929
GRIDLINE_INTERPOLATION_STEPS = 180
3030

31+
# This list is being used for compatibility with Axes.grid, which
32+
# allows all Line2D kwargs.
33+
_line_AI = artist.ArtistInspector(mlines.Line2D)
34+
_line_param_names = _line_AI.get_setters()
35+
_line_param_aliases = [list(d.keys())[0] for d in _line_AI.aliasd.values()]
36+
_gridline_param_names = ['grid_' + name
37+
for name in _line_param_names + _line_param_aliases]
38+
3139

3240
class Tick(artist.Artist):
3341
"""
@@ -86,6 +94,11 @@ def __init__(self, axes, loc, label,
8694
label2On=False,
8795
major=True,
8896
labelrotation=0,
97+
grid_color=None,
98+
grid_linestyle=None,
99+
grid_linewidth=None,
100+
grid_alpha=None,
101+
**kw # Other Line2D kwargs applied to gridlines.
89102
):
90103
"""
91104
bbox is the Bound2D bounding box in display coords of the Axes
@@ -153,6 +166,17 @@ def __init__(self, axes, loc, label,
153166
zorder = mlines.Line2D.zorder
154167
self._zorder = zorder
155168

169+
self._grid_color = (rcParams['grid.color']
170+
if grid_color is None else grid_color)
171+
self._grid_linestyle = (rcParams['grid.linestyle']
172+
if grid_linestyle is None else grid_linestyle)
173+
self._grid_linewidth = (rcParams['grid.linewidth']
174+
if grid_linewidth is None else grid_linewidth)
175+
self._grid_alpha = (rcParams['grid.alpha']
176+
if grid_alpha is None else grid_alpha)
177+
178+
self._grid_kw = {k[5:]: v for k, v in kw.items()}
179+
156180
self.apply_tickdir(tickdir)
157181

158182
self.tick1line = self._get_tick1line()
@@ -368,6 +392,14 @@ def _apply_params(self, **kw):
368392
v = getattr(self.label1, 'get_' + k)()
369393
setattr(self, '_label' + k, v)
370394

395+
grid_list = [k for k in six.iteritems(kw)
396+
if k[0] in _gridline_param_names]
397+
if grid_list:
398+
grid_kw = {k[5:]: v for k, v in grid_list}
399+
self.gridline.set(**grid_kw)
400+
for k, v in six.iteritems(grid_kw):
401+
setattr(self, '_grid_' + k, v)
402+
371403
def update_position(self, loc):
372404
'Set the location of tick in data coords with scalar *loc*'
373405
raise NotImplementedError('Derived must override')
@@ -469,11 +501,12 @@ def _get_gridline(self):
469501
'Get the default line2D instance'
470502
# x in data coords, y in axes coords
471503
l = mlines.Line2D(xdata=(0.0, 0.0), ydata=(0, 1.0),
472-
color=rcParams['grid.color'],
473-
linestyle=rcParams['grid.linestyle'],
474-
linewidth=rcParams['grid.linewidth'],
475-
alpha=rcParams['grid.alpha'],
476-
markersize=0)
504+
color=self._grid_color,
505+
linestyle=self._grid_linestyle,
506+
linewidth=self._grid_linewidth,
507+
alpha=self._grid_alpha,
508+
markersize=0,
509+
**self._grid_kw)
477510
l.set_transform(self.axes.get_xaxis_transform(which='grid'))
478511
l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
479512
self._set_artist_props(l)
@@ -592,12 +625,12 @@ def _get_gridline(self):
592625
'Get the default line2D instance'
593626
# x in axes coords, y in data coords
594627
l = mlines.Line2D(xdata=(0, 1), ydata=(0, 0),
595-
color=rcParams['grid.color'],
596-
linestyle=rcParams['grid.linestyle'],
597-
linewidth=rcParams['grid.linewidth'],
598-
alpha=rcParams['grid.alpha'],
599-
markersize=0)
600-
628+
color=self._grid_color,
629+
linestyle=self._grid_linestyle,
630+
linewidth=self._grid_linewidth,
631+
alpha=self._grid_alpha,
632+
markersize=0,
633+
**self._grid_kw)
601634
l.set_transform(self.axes.get_yaxis_transform(which='grid'))
602635
l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
603636
self._set_artist_props(l)
@@ -650,13 +683,6 @@ def __init__(self, axes, pickradius=15):
650683
artist.Artist.__init__(self)
651684
self.set_figure(axes.figure)
652685

653-
# Keep track of setting to the default value, this allows use to know
654-
# if any of the following values is explicitly set by the user, so as
655-
# to not overwrite their settings with any of our 'auto' settings.
656-
self.isDefault_majloc = True
657-
self.isDefault_minloc = True
658-
self.isDefault_majfmt = True
659-
self.isDefault_minfmt = True
660686
self.isDefault_label = True
661687

662688
self.axes = axes
@@ -745,22 +771,10 @@ def get_children(self):
745771

746772
def cla(self):
747773
'clear the current axis'
748-
self.set_major_locator(mticker.AutoLocator())
749-
self.set_major_formatter(mticker.ScalarFormatter())
750-
self.set_minor_locator(mticker.NullLocator())
751-
self.set_minor_formatter(mticker.NullFormatter())
752774

753-
self.set_label_text('')
754-
self._set_artist_props(self.label)
775+
self.label.set_text('') # self.set_label_text would change isDefault_
755776

756-
# Keep track of setting to the default value, this allows use to know
757-
# if any of the following values is explicitly set by the user, so as
758-
# to not overwrite their settings with any of our 'auto' settings.
759-
self.isDefault_majloc = True
760-
self.isDefault_minloc = True
761-
self.isDefault_majfmt = True
762-
self.isDefault_minfmt = True
763-
self.isDefault_label = True
777+
self._set_scale('linear')
764778

765779
# Clear the callback registry for this axis, or it may "leak"
766780
self.callbacks = cbook.CallbackRegistry()
@@ -771,9 +785,6 @@ def cla(self):
771785
self._gridOnMinor = (rcParams['axes.grid'] and
772786
rcParams['axes.grid.which'] in ('both', 'minor'))
773787

774-
self.label.set_text('')
775-
self._set_artist_props(self.label)
776-
777788
self.reset_ticks()
778789

779790
self.converter = None
@@ -782,9 +793,11 @@ def cla(self):
782793
self.stale = True
783794

784795
def reset_ticks(self):
785-
# build a few default ticks; grow as necessary later; only
786-
# define 1 so properties set on ticks will be copied as they
787-
# grow
796+
"""
797+
Re-initialize the major and minor Tick lists.
798+
799+
Each list starts with a single fresh Tick.
800+
"""
788801
del self.majorTicks[:]
789802
del self.minorTicks[:]
790803

@@ -793,9 +806,14 @@ def reset_ticks(self):
793806
self._lastNumMajorTicks = 1
794807
self._lastNumMinorTicks = 1
795808

809+
try:
810+
self.set_clip_path(self.axes.patch)
811+
except AttributeError:
812+
pass
813+
796814
def set_tick_params(self, which='major', reset=False, **kw):
797815
"""
798-
Set appearance parameters for ticks and ticklabels.
816+
Set appearance parameters for ticks, ticklabels, and gridlines.
799817
800818
For documentation of keyword arguments, see
801819
:meth:`matplotlib.axes.Axes.tick_params`.
@@ -810,6 +828,7 @@ def set_tick_params(self, which='major', reset=False, **kw):
810828
if reset:
811829
d.clear()
812830
d.update(kwtrans)
831+
813832
if reset:
814833
self.reset_ticks()
815834
else:
@@ -833,7 +852,8 @@ def _translate_tick_kw(kw, to_init_kw=True):
833852
kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top',
834853
'labelleft', 'labelbottom', 'labelright', 'labeltop',
835854
'labelrotation']
836-
kwkeys = kwkeys0 + kwkeys1
855+
kwkeys2 = _gridline_param_names
856+
kwkeys = kwkeys0 + kwkeys1 + kwkeys2
837857
kwtrans = dict()
838858
if to_init_kw:
839859
if 'length' in kw:
@@ -975,7 +995,7 @@ def _update_ticks(self, renderer):
975995
"""
976996

977997
interval = self.get_view_interval()
978-
tick_tups = list(self.iter_ticks())
998+
tick_tups = list(self.iter_ticks()) # iter_ticks calls the locator
979999
if self._smart_bounds and tick_tups:
9801000
# handle inverted limits
9811001
view_low, view_high = sorted(interval)
@@ -1401,30 +1421,21 @@ def grid(self, b=None, which='major', **kwargs):
14011421
if len(kwargs):
14021422
b = True
14031423
which = which.lower()
1424+
gridkw = {'grid_' + item[0]: item[1] for item in kwargs.items()}
14041425
if which in ['minor', 'both']:
14051426
if b is None:
14061427
self._gridOnMinor = not self._gridOnMinor
14071428
else:
14081429
self._gridOnMinor = b
1409-
for tick in self.minorTicks: # don't use get_ticks here!
1410-
if tick is None:
1411-
continue
1412-
tick.gridOn = self._gridOnMinor
1413-
if len(kwargs):
1414-
tick.gridline.update(kwargs)
1415-
self._minor_tick_kw['gridOn'] = self._gridOnMinor
1430+
self.set_tick_params(which='minor', gridOn=self._gridOnMinor,
1431+
**gridkw)
14161432
if which in ['major', 'both']:
14171433
if b is None:
14181434
self._gridOnMajor = not self._gridOnMajor
14191435
else:
14201436
self._gridOnMajor = b
1421-
for tick in self.majorTicks: # don't use get_ticks here!
1422-
if tick is None:
1423-
continue
1424-
tick.gridOn = self._gridOnMajor
1425-
if len(kwargs):
1426-
tick.gridline.update(kwargs)
1427-
self._major_tick_kw['gridOn'] = self._gridOnMajor
1437+
self.set_tick_params(which='major', gridOn=self._gridOnMajor,
1438+
**gridkw)
14281439
self.stale = True
14291440

14301441
def update_units(self, data):
@@ -1454,11 +1465,11 @@ def _update_axisinfo(self):
14541465
check the axis converter for the stored units to see if the
14551466
axis info needs to be updated
14561467
"""
1457-
14581468
if self.converter is None:
14591469
return
14601470

14611471
info = self.converter.axisinfo(self.units, self)
1472+
14621473
if info is None:
14631474
return
14641475
if info.majloc is not None and \

lib/matplotlib/scale.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import numpy as np
77
from numpy import ma
88

9-
from matplotlib import cbook, docstring
9+
from matplotlib import cbook, docstring, rcParams
1010
from matplotlib.ticker import (
1111
NullFormatter, ScalarFormatter, LogFormatterSciNotation, LogitFormatter,
12-
NullLocator, LogLocator, AutoLocator, SymmetricalLogLocator, LogitLocator)
12+
NullLocator, LogLocator, AutoLocator, AutoMinorLocator,
13+
SymmetricalLogLocator, LogitLocator)
1314
from matplotlib.transforms import Transform, IdentityTransform
1415

1516

@@ -71,8 +72,12 @@ def set_default_locators_and_formatters(self, axis):
7172
"""
7273
axis.set_major_locator(AutoLocator())
7374
axis.set_major_formatter(ScalarFormatter())
74-
axis.set_minor_locator(NullLocator())
7575
axis.set_minor_formatter(NullFormatter())
76+
# update the minor locator for x and y axis based on rcParams
77+
if rcParams['xtick.minor.visible']:
78+
axis.set_minor_locator(AutoMinorLocator())
79+
else:
80+
axis.set_minor_locator(NullLocator())
7681

7782
def get_transform(self):
7883
"""

lib/matplotlib/tests/test_axes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5152,6 +5152,18 @@ def test_axis_set_tick_params_labelsize_labelcolor():
51525152
assert axis_1.yaxis.majorTicks[0]._labelcolor == 'red'
51535153

51545154

5155+
def test_axes_tick_params_gridlines():
5156+
# Now treating grid params like other Tick params
5157+
ax = plt.subplot()
5158+
ax.tick_params(grid_color='b', grid_linewidth=5, grid_alpha=0.5,
5159+
grid_linestyle='dashdot')
5160+
for axis in ax.xaxis, ax.yaxis:
5161+
assert axis.majorTicks[0]._grid_color == 'b'
5162+
assert axis.majorTicks[0]._grid_linewidth == 5
5163+
assert axis.majorTicks[0]._grid_alpha == 0.5
5164+
assert axis.majorTicks[0]._grid_linestyle == 'dashdot'
5165+
5166+
51555167
def test_none_kwargs():
51565168
fig, ax = plt.subplots()
51575169
ln, = ax.plot(range(32), linestyle=None)

0 commit comments

Comments
 (0)