|
From: <ef...@us...> - 2010-06-21 08:51:37
|
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.
|