Revision: 8448
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8448&view=rev
Author:   efiring
Date:     2010-06-21 08:51:30 +0000 (Mon, 21 Jun 2010)

Log Message:
-----------
Add Axes.tick_params and pyplot.tick_params to control tick and tick label 
appearance.
This allows interactive modification of tick and tick label color, size, etc.

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/boilerplate.py
    trunk/matplotlib/lib/matplotlib/axes.py
    trunk/matplotlib/lib/matplotlib/axis.py
    trunk/matplotlib/lib/matplotlib/pyplot.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2010-06-20 23:31:49 UTC (rev 8447)
+++ trunk/matplotlib/CHANGELOG  2010-06-21 08:51:30 UTC (rev 8448)
@@ -1,3 +1,7 @@
+2010-06-20 Added Axes.tick_params and corresponding pyplot function
+           to control tick and tick label appearance after an Axes
+           has been created. - EF
+
 2010-06-09 Allow Axes.grid to control minor gridlines; allow
            Axes.grid and Axis.grid to control major and minor
            gridlines in the same method call. - EF

Modified: trunk/matplotlib/boilerplate.py
===================================================================
--- trunk/matplotlib/boilerplate.py     2010-06-20 23:31:49 UTC (rev 8447)
+++ trunk/matplotlib/boilerplate.py     2010-06-21 08:51:30 UTC (rev 8448)
@@ -107,6 +107,7 @@
     'annotate',
     'ticklabel_format',
     'locator_params',
+    'tick_params',
     'margins',
     )
 

Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py     2010-06-20 23:31:49 UTC (rev 
8447)
+++ trunk/matplotlib/lib/matplotlib/axes.py     2010-06-21 08:51:30 UTC (rev 
8448)
@@ -2101,7 +2101,82 @@
             self.yaxis.get_major_locator().set_params(**kwargs)
         self.autoscale_view(tight=tight, scalex=_x, scaley=_y)
 
+    def tick_params(self, axis='both', **kwargs):
+        """
+        Convenience method for changing the appearance of ticks and
+        tick labels.
 
+        Keyword arguments:
+
+        *axis*
+            ['x' | 'y' | 'both']  Axis on which to operate;
+            default is 'both'.
+
+        *reset*
+            [True | False] If *True*, set all parameters to defaults
+            before processing other keyword arguments.  Default is
+            *False*.
+
+        *which*
+            ['major' | 'minor' | 'both'] Default is 'major': apply
+            arguments to major ticks only.
+
+        *direction*
+            ['in' | 'out'] Puts ticks inside or outside the axes.
+
+        *length*
+            Tick length in points.
+
+        *width*
+            Tick width in points.
+
+        *color*
+            Tick color; accepts any mpl color spec.
+
+        *pad*
+            Distance in points between tick and label.
+
+        *labelsize*
+            Tick label font size in points or as a string (e.g. 'large').
+
+        *labelcolor*
+            Tick label color; mpl color spec.
+
+        *colors*
+            Changes the tick color and the label color to the same value:
+            mpl color spec.
+
+        *zorder*
+            Tick and label zorder.
+
+        *bottom*, *top*, *left*, *right*
+            Boolean or ['on' | 'off'], controls whether to draw the
+            respective ticks.
+
+        *labelbottom*, *labeltop*, *labelleft*, *labelright*
+            Boolean or ['on' | 'off'], controls whether to draw the
+            respective tick labels.
+
+        Example::
+
+            ax.tick_params(direction='out', length=6, width=2, colors='r')
+
+        This will make all major ticks be red, pointing out of the box,
+        and with dimensions 6 points by 2 points.  Tick labels will
+        also be red.
+
+        """
+        if axis in ['x', 'both']:
+            xkw = dict(kwargs)
+            xkw.pop('top', None)
+            xkw.pop('bottom', None)
+            self.xaxis.set_tick_params(**xkw)
+        if axis in ['y', 'both']:
+            ykw = dict(kwargs)
+            ykw.pop('left', None)
+            ykw.pop('right', None)
+            self.yaxis.set_tick_params(**ykw)
+
     def set_axis_off(self):
         """turn off the axis"""
         self.axison = False

Modified: trunk/matplotlib/lib/matplotlib/axis.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axis.py     2010-06-20 23:31:49 UTC (rev 
8447)
+++ trunk/matplotlib/lib/matplotlib/axis.py     2010-06-21 08:51:30 UTC (rev 
8448)
@@ -60,7 +60,16 @@
 
     """
     def __init__(self, axes, loc, label,
-                 size   = None,  # points
+
+                 size = None,  # points
+                 width = None,
+                 color = None,
+                 tickdir = None,
+                 pad = None,
+                 labelsize = None,
+                 labelcolor = None,
+                 zorder = None,
+
                  gridOn = None, # defaults to axes.grid
                  tick1On = True,
                  tick2On = True,
@@ -71,7 +80,7 @@
         """
         bbox is the Bound2D bounding box in display coords of the Axes
         loc is the tick location in data coords
-        size is the tick size in relative, axes coords
+        size is the tick size in points
         """
         artist.Artist.__init__(self)
 
@@ -81,27 +90,47 @@
         self.axes = axes
 
         name = self.__name__.lower()
+        self._name = name
+
+        self._loc = loc
+
         if size is None:
             if major:
                 size = rcParams['%s.major.size'%name]
+            else:
+                size = rcParams['%s.minor.size'%name]
+        self._size = size
+
+        self._width = width # can be None for marker default
+
+        if color is None:
+            color = rcParams['%s.color' % name]
+        self._color = color
+
+        if pad is None:
+            if major:
                 pad = rcParams['%s.major.pad'%name]
             else:
-                size = rcParams['%s.minor.size'%name]
                 pad = rcParams['%s.minor.pad'%name]
+        self._base_pad = pad
 
-        self._tickdir = rcParams['%s.direction'%name]
-        if self._tickdir == 'in':
-            self._xtickmarkers = (mlines.TICKUP, mlines.TICKDOWN)
-            self._ytickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT)
-            self._pad = pad
-        else:
-            self._xtickmarkers = (mlines.TICKDOWN, mlines.TICKUP)
-            self._ytickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT)
-            self._pad = pad + size
+        if labelcolor is None:
+            labelcolor = rcParams['%s.color' % name]
+        self._labelcolor = labelcolor
 
-        self._loc = loc
-        self._size = size
+        if labelsize is None:
+            labelsize = rcParams['%s.labelsize' % name]
+        self._labelsize = labelsize
 
+        if zorder is None:
+            if major:
+                zorder = mlines.Line2D.zorder + 0.01
+            else:
+                zorder = mlines.Line2D.zorder
+        self._zorder = zorder
+
+        self.apply_tickdir(tickdir)
+
         self.tick1line = self._get_tick1line()
         self.tick2line = self._get_tick2line()
         self.gridline = self._get_gridline()
@@ -118,6 +147,20 @@
 
         self.update_position(loc)
 
+    def apply_tickdir(self, tickdir):
+        if tickdir is None:
+            tickdir = rcParams['%s.direction' % self._name]
+        self._tickdir = tickdir
+
+        if self._tickdir == 'in':
+            self._xtickmarkers = (mlines.TICKUP, mlines.TICKDOWN)
+            self._ytickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT)
+            self._pad = self._base_pad
+        else:
+            self._xtickmarkers = (mlines.TICKDOWN, mlines.TICKUP)
+            self._ytickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT)
+            self._pad = self._base_pad + self._size
+
     def get_children(self):
         children = [self.tick1line, self.tick2line, self.gridline, 
self.label1, self.label2]
         return children
@@ -242,15 +285,13 @@
         # x in data coords, y in axes coords
         #t =  mtext.Text(
         trans, vert, horiz = self.axes.get_xaxis_text1_transform(self._pad)
-        size = rcParams['xtick.labelsize']
         t = mtext.Text(
             x=0, y=0,
-            fontproperties=font_manager.FontProperties(size=size),
-            color=rcParams['xtick.color'],
+            fontproperties=font_manager.FontProperties(size=self._labelsize),
+            color=self._labelcolor,
             verticalalignment=vert,
             horizontalalignment=horiz,
             )
-
         t.set_transform(trans)
         self._set_artist_props(t)
         return t
@@ -262,11 +303,10 @@
         # x in data coords, y in axes coords
         #t =  mtext.Text(
         trans, vert, horiz = self.axes.get_xaxis_text2_transform(self._pad)
-
         t = mtext.Text(
             x=0, y=1,
-            
fontproperties=font_manager.FontProperties(size=rcParams['xtick.labelsize']),
-            color=rcParams['xtick.color'],
+            fontproperties=font_manager.FontProperties(size=self._labelsize),
+            color=self._labelcolor,
             verticalalignment=vert,
             horizontalalignment=horiz,
             )
@@ -278,10 +318,12 @@
         'Get the default line2D instance'
         # x in data coords, y in axes coords
         l = mlines.Line2D(xdata=(0,), ydata=(0,),
-                   color='k',
+                   color=self._color,
                    linestyle = 'None',
                    marker = self._xtickmarkers[0],
                    markersize=self._size,
+                   markeredgewidth=self._width,
+                   zorder=self._zorder,
                    )
         l.set_transform(self.axes.get_xaxis_transform(which='tick1'))
         self._set_artist_props(l)
@@ -291,10 +333,12 @@
         'Get the default line2D instance'
         # x in data coords, y in axes coords
         l = mlines.Line2D( xdata=(0,), ydata=(1,),
-                       color='k',
+                       color=self._color,
                        linestyle = 'None',
                        marker = self._xtickmarkers[1],
                        markersize=self._size,
+                       markeredgewidth=self._width,
+                       zorder=self._zorder,
                        )
 
         l.set_transform(self.axes.get_xaxis_transform(which='tick2'))
@@ -372,13 +416,11 @@
     def _get_text1(self):
         'Get the default Text instance'
         # x in axes coords, y in data coords
-        #t =  mtext.Text(
         trans, vert, horiz = self.axes.get_yaxis_text1_transform(self._pad)
-
         t = mtext.Text(
             x=0, y=0,
-            
fontproperties=font_manager.FontProperties(size=rcParams['ytick.labelsize']),
-            color=rcParams['ytick.color'],
+            fontproperties=font_manager.FontProperties(size=self._labelsize),
+            color=self._labelcolor,
             verticalalignment=vert,
             horizontalalignment=horiz,
             )
@@ -390,13 +432,11 @@
     def _get_text2(self):
         'Get the default Text instance'
         # x in axes coords, y in data coords
-        #t =  mtext.Text(
         trans, vert, horiz = self.axes.get_yaxis_text2_transform(self._pad)
-
         t = mtext.Text(
             x=1, y=0,
-            
fontproperties=font_manager.FontProperties(size=rcParams['ytick.labelsize']),
-            color=rcParams['ytick.color'],
+            fontproperties=font_manager.FontProperties(size=self._labelsize),
+            color=self._labelcolor,
             verticalalignment=vert,
             horizontalalignment=horiz,
             )
@@ -408,11 +448,14 @@
         'Get the default line2D instance'
         # x in axes coords, y in data coords
 
-        l = mlines.Line2D( (0,), (0,), color='k',
+        l = mlines.Line2D( (0,), (0,),
+                    color=self._color,
                     marker = self._ytickmarkers[0],
                     linestyle = 'None',
                     markersize=self._size,
-                       )
+                    markeredgewidth=self._width,
+                    zorder=self._zorder,
+                    )
         l.set_transform(self.axes.get_yaxis_transform(which='tick1'))
         self._set_artist_props(l)
         return l
@@ -420,12 +463,14 @@
     def _get_tick2line(self):
         'Get the default line2D instance'
         # x in axes coords, y in data coords
-        l = mlines.Line2D( (1,), (0,), color='k',
+        l = mlines.Line2D( (1,), (0,),
+                    color=self._color,
                     marker = self._ytickmarkers[1],
                     linestyle = 'None',
                     markersize=self._size,
+                    markeredgewidth=self._width,
+                    zorder=self._zorder,
                     )
-
         l.set_transform(self.axes.get_yaxis_transform(which='tick2'))
         self._set_artist_props(l)
         return l
@@ -549,6 +594,10 @@
         self.minorTicks = []
         self.pickradius = pickradius
 
+        # Initialize here for testing; later add API
+        self._major_tick_kw = dict()
+        self._minor_tick_kw = dict()
+
         self.cla()
         self.set_scale('linear')
 
@@ -631,10 +680,16 @@
         self.label.set_text('')
         self._set_artist_props(self.label)
 
+        self.reset_ticks()
+
+        self.converter = None
+        self.units = None
+        self.set_units(None)
+
+    def reset_ticks(self):
         # build a few default ticks; grow as necessary later; only
         # define 1 so properties set on ticks will be copied as they
         # grow
-
         cbook.popall(self.majorTicks)
         cbook.popall(self.minorTicks)
 
@@ -643,10 +698,84 @@
         self._lastNumMajorTicks = 1
         self._lastNumMinorTicks = 1
 
-        self.converter = None
-        self.units = None
-        self.set_units(None)
+    def set_tick_params(self, which='major', reset=False, **kw):
+        """
+        Set appearance parameters for ticks and ticklabels.
 
+        For documentation of keyword arguments, see
+        :meth:`matplotlib.axes.Axes.tick_params`.
+        """
+        dicts = []
+        if which == 'major' or which == 'both':
+            dicts.append(self._major_tick_kw)
+        if which == 'minor' or which == 'both':
+            dicts.append(self._minor_tick_kw)
+        kwtrans = self._translate_tick_kw(kw, to_init_kw=True)
+        for d in dicts:
+            if reset:
+                d.clear()
+            d.update(kwtrans)
+        self.reset_ticks()
+
+    @staticmethod
+    def _translate_tick_kw(kw, to_init_kw=True):
+        # We may want to move the following function to
+        # a more visible location; or maybe there already
+        # is something like this.
+        def _bool(arg):
+            if cbook.is_string_like(arg):
+                if arg.lower() == 'on':
+                    return True
+                if arg.lower() == 'off':
+                    return False
+                raise ValueError('String "%s" should be "on" or "off"' % arg)
+            return bool(arg)
+        # The following lists may be moved to a more
+        # accessible location.
+        kwkeys0 = ['size', 'width', 'color', 'tickdir', 'pad',
+                  'labelsize', 'labelcolor', 'zorder',
+                  'tick1On', 'tick2On', 'label1On', 'label2On']
+        kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top',
+                    'labelleft', 'labelbottom', 'labelright', 'labeltop']
+        kwkeys = kwkeys0 + kwkeys1
+        kwtrans = dict()
+        if to_init_kw:
+            if 'length' in kw:
+                kwtrans['size'] = kw.pop('length')
+            if 'direction' in kw:
+                kwtrans['tickdir'] = kw.pop('direction')
+            if 'left' in kw:
+                kwtrans['tick1On'] = _bool(kw.pop('left'))
+            if 'bottom' in kw:
+                kwtrans['tick1On'] = _bool(kw.pop('bottom'))
+            if 'right' in kw:
+                kwtrans['tick2On'] = _bool(kw.pop('right'))
+            if 'top' in kw:
+                kwtrans['tick2On'] = _bool(kw.pop('top'))
+
+            if 'labelleft' in kw:
+                kwtrans['label1On'] = _bool(kw.pop('labelleft'))
+            if 'labelbottom' in kw:
+                kwtrans['label1On'] = _bool(kw.pop('labelbottom'))
+            if 'labelright' in kw:
+                kwtrans['label2On'] = _bool(kw.pop('labelright'))
+            if 'labeltop' in kw:
+                kwtrans['label2On'] = _bool(kw.pop('labeltop'))
+            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:
+                if key not in kwkeys:
+                    raise ValueError(
+                        "keyword %s is not recognized; valid keywords are %s"
+                        % (key, kwkeys))
+            kwtrans.update(kw)
+        else:
+            raise NotImplementedError("Inverse translation is deferred")
+        return kwtrans
+
     def set_clip_path(self, clippath, transform=None):
         artist.Artist.set_clip_path(self, clippath, transform)
         majorticks = self.get_major_ticks()
@@ -1303,13 +1432,18 @@
         return inaxis, {}
 
     def _get_tick(self, major):
-        return XTick(self.axes, 0, '', major=major)
+        if major:
+            tick_kw = self._major_tick_kw
+        else:
+            tick_kw = self._minor_tick_kw
+        return XTick(self.axes, 0, '', major=major, **tick_kw)
 
     def _get_label(self):
         # x in axes coords, y in display coords (to be updated at draw
         # time by _update_label_positions)
         label = mtext.Text(x=0.5, y=0,
-            fontproperties = 
font_manager.FontProperties(size=rcParams['axes.labelsize']),
+            fontproperties = font_manager.FontProperties(
+                                          size=rcParams['axes.labelsize']),
             color = rcParams['axes.labelcolor'],
             verticalalignment='top',
             horizontalalignment='center',
@@ -1325,7 +1459,8 @@
     def _get_offset_text(self):
         # x in axes coords, y in display coords (to be updated at draw time)
         offsetText = mtext.Text(x=1, y=0,
-            fontproperties = 
font_manager.FontProperties(size=rcParams['xtick.labelsize']),
+            fontproperties = font_manager.FontProperties(
+                                          size=rcParams['xtick.labelsize']),
             color = rcParams['xtick.color'],
             verticalalignment='top',
             horizontalalignment='right',
@@ -1562,7 +1697,11 @@
         return inaxis, {}
 
     def _get_tick(self, major):
-        return YTick(self.axes, 0, '', major=major)
+        if major:
+            tick_kw = self._major_tick_kw
+        else:
+            tick_kw = self._minor_tick_kw
+        return YTick(self.axes, 0, '', major=major, **tick_kw)
 
 
     def _get_label(self):
@@ -1570,7 +1709,8 @@
         # y in axes coords
         label = mtext.Text(x=0, y=0.5,
             # todo: get the label position
-            
fontproperties=font_manager.FontProperties(size=rcParams['axes.labelsize']),
+            fontproperties=font_manager.FontProperties(
+                                        size=rcParams['axes.labelsize']),
             color    = rcParams['axes.labelcolor'],
             verticalalignment='center',
             horizontalalignment='right',
@@ -1586,7 +1726,8 @@
     def _get_offset_text(self):
         # x in display coords, y in axes coords (to be updated at draw time)
         offsetText = mtext.Text(x=0, y=0.5,
-            fontproperties = 
font_manager.FontProperties(size=rcParams['ytick.labelsize']),
+            fontproperties = font_manager.FontProperties(
+                                          size=rcParams['ytick.labelsize']),
             color = rcParams['ytick.color'],
             verticalalignment = 'baseline',
             horizontalalignment = 'left',

Modified: trunk/matplotlib/lib/matplotlib/pyplot.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/pyplot.py   2010-06-20 23:31:49 UTC (rev 
8447)
+++ trunk/matplotlib/lib/matplotlib/pyplot.py   2010-06-21 08:51:30 UTC (rev 
8448)
@@ -1936,8 +1936,7 @@
 # This function was autogenerated by boilerplate.py.  Do not edit as
 # changes will be lost
 @autogen_docstring(Axes.boxplot)
-def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, 
widths=None,
-            hold=None, patch_artist=False):
+def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, 
widths=None, patch_artist=False, bootstrap=None, hold=None):
     ax = gca()
     # allow callers to override the hold state by passing hold=True|False
     washold = ax.ishold()
@@ -1945,8 +1944,7 @@
     if hold is not None:
         ax.hold(hold)
     try:
-        ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths,
-                         patch_artist=patch_artist)
+        ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths, 
patch_artist, bootstrap)
         draw_if_interactive()
     finally:
         ax.hold(washold)
@@ -2136,7 +2134,7 @@
 # This function was autogenerated by boilerplate.py.  Do not edit as
 # changes will be lost
 @autogen_docstring(Axes.hist)
-def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, 
bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, 
log=False, hold=None, **kwargs):
+def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, 
bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, 
log=False, color=None, label=None, hold=None, **kwargs):
     ax = gca()
     # allow callers to override the hold state by passing hold=True|False
     washold = ax.ishold()
@@ -2144,7 +2142,7 @@
     if hold is not None:
         ax.hold(hold)
     try:
-        ret = ax.hist(x, bins, range, normed, weights, cumulative, bottom, 
histtype, align, orientation, rwidth, log, **kwargs)
+        ret = ax.hist(x, bins, range, normed, weights, cumulative, bottom, 
histtype, align, orientation, rwidth, log, color, label, **kwargs)
         draw_if_interactive()
     finally:
         ax.hold(washold)
@@ -2421,7 +2419,6 @@
     sci(ret[-1])
     return ret
 
-
 # This function was autogenerated by boilerplate.py.  Do not edit as
 # changes will be lost
 @autogen_docstring(Axes.stem)
@@ -2643,13 +2640,21 @@
 # This function was autogenerated by boilerplate.py.  Do not edit as
 # changes will be lost
 @docstring.copy_dedent(Axes.locator_params)
-def locator_params(axis='both', tight=False, **kwargs):
+def locator_params(axis='both', tight=None, **kwargs):
     ret =  gca().locator_params(axis, tight, **kwargs)
     draw_if_interactive()
     return ret
 
 # This function was autogenerated by boilerplate.py.  Do not edit as
 # changes will be lost
+...@docstring.copy_dedent(Axes.tick_params)
+def tick_params(axis='both', **kwargs):
+    ret =  gca().tick_params(axis, **kwargs)
+    draw_if_interactive()
+    return ret
+
+# This function was autogenerated by boilerplate.py.  Do not edit as
+# changes will be lost
 @docstring.copy_dedent(Axes.margins)
 def margins(*args, **kw):
     ret =  gca().margins(*args, **kw)
@@ -2879,3 +2884,6 @@
     if im is not None:
         im.set_cmap(cm.spectral)
     draw_if_interactive()
+
+
+


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to