diff --git a/doc/users/recipes.rst b/doc/users/recipes.rst
index 174241b79e7b..891b9d02beca 100644
--- a/doc/users/recipes.rst
+++ b/doc/users/recipes.rst
@@ -139,7 +139,7 @@ the x locations are formatted the same way the tick labels are, e.g.,
a higher degree of precision, e.g., giving us the exact date out mouse is
hovering over. To fix the first problem, we can use
:func:`matplotlib.figure.Figure.autofmt_xdate` and to fix the second
-problem we can use the ``ax.fmt_xdata`` attribute which can be set to
+problem we can use the ``ax.format_xdata`` attribute which can be set to
any function that takes a scalar and returns a string. matplotlib has
a number of date formatters built in, so we'll use one of those.
@@ -157,7 +157,7 @@ a number of date formatters built in, so we'll use one of those.
# use a more precise date string for the x axis locations in the
# toolbar
import matplotlib.dates as mdates
- ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
+ ax.format_xdata = mdates.DateFormatter('%Y-%m-%d').format_for_cursor
plt.title('fig.autofmt_xdate fixes the labels')
Now when you hover your mouse over the plotted data, you'll see date
diff --git a/examples/api/custom_projection_example.py b/examples/api/custom_projection_example.py
index 32018c534604..d0fba4a7c17f 100644
--- a/examples/api/custom_projection_example.py
+++ b/examples/api/custom_projection_example.py
@@ -291,12 +291,12 @@ class DegreeFormatter(Formatter):
"""
def __init__(self, round_to=1.0):
+ super(HammerAxes.DegreeFormatter, self).__init__()
self._round_to = round_to
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
degrees = np.round(np.degrees(x) / self._round_to) * self._round_to
- # \u00b0 : degree symbol
- return "%d\u00b0" % degrees
+ return "%d\N{DEGREE SIGN}" % degrees
def set_longitude_grid(self, degrees):
"""
diff --git a/examples/api/custom_scale_example.py b/examples/api/custom_scale_example.py
index df8fe46d2737..dfd3aae59a2e 100644
--- a/examples/api/custom_scale_example.py
+++ b/examples/api/custom_scale_example.py
@@ -70,9 +70,8 @@ def set_default_locators_and_formatters(self, axis):
value::
"""
class DegreeFormatter(Formatter):
- def __call__(self, x, pos=None):
- # \u00b0 : degree symbol
- return "%d\u00b0" % (np.degrees(x))
+ def format_for_tick(self, x, pos=None):
+ return "%d\N{DEGREE SIGN}" % (np.degrees(x))
axis.set_major_locator(FixedLocator(
np.radians(np.arange(-90, 90, 10))))
diff --git a/examples/api/date_demo.py b/examples/api/date_demo.py
index 7e419bb9ee44..0f7702ea0b5b 100644
--- a/examples/api/date_demo.py
+++ b/examples/api/date_demo.py
@@ -52,7 +52,7 @@
# format the coords message box
def price(x):
return '$%1.2f' % x
-ax.format_xdata = mdates.DateFormatter('%Y-%m-%d')
+ax.format_xdata = mdates.DateFormatter('%Y-%m-%d').format_for_cursor
ax.format_ydata = price
ax.grid(True)
diff --git a/examples/pylab_examples/contour_label_demo.py b/examples/pylab_examples/contour_label_demo.py
index 42eb8f579406..d12a5508b47b 100644
--- a/examples/pylab_examples/contour_label_demo.py
+++ b/examples/pylab_examples/contour_label_demo.py
@@ -80,8 +80,7 @@ def __repr__(self):
CS = plt.contour(X, Y, 100**Z, locator=plt.LogLocator())
fmt = ticker.LogFormatterMathtext()
-fmt.create_dummy_axis()
-plt.clabel(CS, CS.levels, fmt=fmt)
+plt.clabel(CS, CS.levels, fmt=fmt.format_for_tick)
plt.title("$100^Z$")
plt.show()
diff --git a/examples/pylab_examples/date_demo1.py b/examples/pylab_examples/date_demo1.py
index 45fbf128840e..8e16c7db635e 100644
--- a/examples/pylab_examples/date_demo1.py
+++ b/examples/pylab_examples/date_demo1.py
@@ -45,8 +45,8 @@
# format the coords message box
def price(x):
return '$%1.2f' % x
-ax.fmt_xdata = DateFormatter('%Y-%m-%d')
-ax.fmt_ydata = price
+ax.format_xdata = DateFormatter('%Y-%m-%d').format_for_cursor
+ax.format_ydata = price
ax.grid(True)
fig.autofmt_xdate()
diff --git a/examples/pylab_examples/date_demo_convert.py b/examples/pylab_examples/date_demo_convert.py
index 693a6752a3ca..50b6f9befc9a 100644
--- a/examples/pylab_examples/date_demo_convert.py
+++ b/examples/pylab_examples/date_demo_convert.py
@@ -27,7 +27,7 @@
ax.xaxis.set_minor_locator(HourLocator(arange(0, 25, 6)))
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
-ax.fmt_xdata = DateFormatter('%Y-%m-%d %H:%M:%S')
+ax.format_xdata = DateFormatter('%Y-%m-%d %H:%M:%S').format_for_cursor
fig.autofmt_xdate()
plt.show()
diff --git a/examples/pylab_examples/date_index_formatter.py b/examples/pylab_examples/date_index_formatter.py
index 1234bb5b5850..d66d5c1fc673 100644
--- a/examples/pylab_examples/date_index_formatter.py
+++ b/examples/pylab_examples/date_index_formatter.py
@@ -22,10 +22,11 @@
class MyFormatter(Formatter):
def __init__(self, dates, fmt='%Y-%m-%d'):
+ super(MyFormatter, self).__init__()
self.dates = dates
self.fmt = fmt
- def __call__(self, x, pos=0):
+ def format_for_tick(self, x, pos=0):
'Return the label for time x at position pos'
ind = int(round(x))
if ind >= len(self.dates) or ind < 0:
diff --git a/examples/pylab_examples/finance_work2.py b/examples/pylab_examples/finance_work2.py
index 6fa0f3244e58..162bcad34fab 100644
--- a/examples/pylab_examples/finance_work2.py
+++ b/examples/pylab_examples/finance_work2.py
@@ -186,7 +186,7 @@ def moving_average_convergence(x, nslow=26, nfast=12):
label.set_rotation(30)
label.set_horizontalalignment('right')
- ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
+ ax.format_xdata = mdates.DateFormatter('%Y-%m-%d').format_for_cursor
class MyLocator(mticker.MaxNLocator):
diff --git a/examples/pylab_examples/newscalarformatter_demo.py b/examples/pylab_examples/newscalarformatter_demo.py
index 1e525ad8cb6e..b17c42c63632 100644
--- a/examples/pylab_examples/newscalarformatter_demo.py
+++ b/examples/pylab_examples/newscalarformatter_demo.py
@@ -1,27 +1,6 @@
import matplotlib.pyplot as plt
import numpy as np
-from matplotlib.ticker import OldScalarFormatter, ScalarFormatter
-
-# Example 1
-x = np.arange(0, 1, .01)
-fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2, figsize=(6, 6))
-fig.text(0.5, 0.975, 'The old formatter',
- horizontalalignment='center', verticalalignment='top')
-ax1.plot(x * 1e5 + 1e10, x * 1e-10 + 1e-5)
-ax1.xaxis.set_major_formatter(OldScalarFormatter())
-ax1.yaxis.set_major_formatter(OldScalarFormatter())
-
-ax2.plot(x * 1e5, x * 1e-4)
-ax2.xaxis.set_major_formatter(OldScalarFormatter())
-ax2.yaxis.set_major_formatter(OldScalarFormatter())
-
-ax3.plot(-x * 1e5 - 1e10, -x * 1e-5 - 1e-10)
-ax3.xaxis.set_major_formatter(OldScalarFormatter())
-ax3.yaxis.set_major_formatter(OldScalarFormatter())
-
-ax4.plot(-x * 1e5, -x * 1e-4)
-ax4.xaxis.set_major_formatter(OldScalarFormatter())
-ax4.yaxis.set_major_formatter(OldScalarFormatter())
+from matplotlib.ticker import ScalarFormatter
# Example 2
x = np.arange(0, 1, .01)
diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py
index 6e9cddbd0445..969a598cb674 100644
--- a/lib/matplotlib/axes/_base.py
+++ b/lib/matplotlib/axes/_base.py
@@ -2566,19 +2566,19 @@ def ticklabel_format(self, **kwargs):
self.yaxis.major.formatter.set_scientific(sb)
if scilimits is not None:
if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_powerlimits(scilimits)
+ self.xaxis.major.formatter.powerlimits = scilimits
if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_powerlimits(scilimits)
+ self.yaxis.major.formatter.powerlimits = scilimits
if useOffset is not None:
if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useOffset(useOffset)
+ self.xaxis.major.formatter.use_offset = useOffset
if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useOffset(useOffset)
+ self.yaxis.major.formatter.use_offset = useOffset
if useLocale is not None:
if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useLocale(useLocale)
+ self.xaxis.major.formatter.use_locale = useLocale
if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useLocale(useLocale)
+ self.yaxis.major.formatter.use_locale = useLocale
except AttributeError:
raise AttributeError(
"This method only works with the ScalarFormatter.")
@@ -3268,30 +3268,12 @@ def yaxis_date(self, tz=None):
self.yaxis.axis_date(tz)
def format_xdata(self, x):
- """
- Return *x* string formatted. This function will use the attribute
- self.fmt_xdata if it is callable, else will fall back on the xaxis
- major formatter
- """
- try:
- return self.fmt_xdata(x)
- except TypeError:
- func = self.xaxis.get_major_formatter().format_data_short
- val = func(x)
- return val
+ return (self.fmt_xdata(x) if self.fmt_xdata is not None
+ else self.xaxis.get_major_formatter().format_for_cursor(x))
def format_ydata(self, y):
- """
- Return y string formatted. This function will use the
- :attr:`fmt_ydata` attribute if it is callable, else will fall
- back on the yaxis major formatter
- """
- try:
- return self.fmt_ydata(y)
- except TypeError:
- func = self.yaxis.get_major_formatter().format_data_short
- val = func(y)
- return val
+ return (self.fmt_ydata(y) if self.fmt_ydata is not None
+ else self.yaxis.get_major_formatter().format_for_cursor(y))
def format_coord(self, x, y):
"""Return a format string formatting the *x*, *y* coord"""
diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py
index 8062ebc66e4a..76b2b9100e39 100644
--- a/lib/matplotlib/axis.py
+++ b/lib/matplotlib/axis.py
@@ -901,14 +901,14 @@ def iter_ticks(self):
"""
majorLocs = self.major.locator()
majorTicks = self.get_major_ticks(len(majorLocs))
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
+ self.major.formatter.locs = majorLocs
+ majorLabels = [self.major.formatter.format_for_tick(val, i)
for i, val in enumerate(majorLocs)]
minorLocs = self.minor.locator()
minorTicks = self.get_minor_ticks(len(minorLocs))
- self.minor.formatter.set_locs(minorLocs)
- minorLabels = [self.minor.formatter(val, i)
+ self.minor.formatter.locs = minorLocs
+ minorLabels = [self.minor.formatter.format_for_tick(val, i)
for i, val in enumerate(minorLocs)]
major_minor = [
@@ -1087,7 +1087,7 @@ def get_tightbbox(self, renderer):
self._update_label_position(ticklabelBoxes, ticklabelBoxes2)
self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
+ self.offsetText.set_text(self.major.formatter.offset_text)
bb = []
@@ -1140,7 +1140,7 @@ def draw(self, renderer, *args, **kwargs):
self.label.draw(renderer)
self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
+ self.offsetText.set_text(self.major.formatter.offset_text)
self.offsetText.draw(renderer)
if 0: # draw the bounding boxes around the text for debug
diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py
index ad6a145a9d12..0dd9a3599683 100644
--- a/lib/matplotlib/colorbar.py
+++ b/lib/matplotlib/colorbar.py
@@ -370,16 +370,16 @@ def update_ticks(self):
called whenever the tick locator and/or tick formatter changes.
"""
ax = self.ax
- ticks, ticklabels, offset_string = self._ticker()
+ ticks, ticklabels, offset_text = self._ticker()
if self.orientation == 'vertical':
ax.yaxis.set_ticks(ticks)
ax.set_yticklabels(ticklabels)
- ax.yaxis.get_major_formatter().set_offset_string(offset_string)
+ ax.yaxis.get_major_formatter().offset_text = offset_text
else:
ax.xaxis.set_ticks(ticks)
ax.set_xticklabels(ticklabels)
- ax.xaxis.get_major_formatter().set_offset_string(offset_string)
+ ax.xaxis.get_major_formatter().offset_text = offset_text
def set_ticks(self, ticks, update_ticks=True):
"""
@@ -584,12 +584,12 @@ def _ticker(self):
intv = self._values[0], self._values[-1]
else:
intv = self.vmin, self.vmax
- locator.create_dummy_axis(minpos=intv[0])
- formatter.create_dummy_axis(minpos=intv[0])
- locator.set_view_interval(*intv)
- locator.set_data_interval(*intv)
- formatter.set_view_interval(*intv)
- formatter.set_data_interval(*intv)
+ locator.set_axis({"minpos": intv[0]})
+ formatter.set_axis({"minpos": intv[0]})
+ locator.axis.set_view_interval(*intv)
+ locator.axis.set_data_interval(*intv)
+ formatter.axis.set_view_interval(*intv)
+ formatter.axis.set_data_interval(*intv)
b = np.array(locator())
if isinstance(locator, ticker.LogLocator):
@@ -599,10 +599,9 @@ def _ticker(self):
eps = (intv[1] - intv[0]) * 1e-10
b = b[(b <= intv[1] + eps) & (b >= intv[0] - eps)]
ticks = self._locate(b)
- formatter.set_locs(b)
- ticklabels = [formatter(t, i) for i, t in enumerate(b)]
- offset_string = formatter.get_offset()
- return ticks, ticklabels, offset_string
+ formatter.locs = b
+ ticklabels = [formatter.format_for_tick(t, i) for i, t in enumerate(b)]
+ return ticks, ticklabels, formatter.offset_text
def _process_values(self, b=None):
'''
diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py
index fbd0bf480cda..29e3c9c1e2a9 100755
--- a/lib/matplotlib/dates.py
+++ b/lib/matplotlib/dates.py
@@ -470,12 +470,13 @@ def __init__(self, fmt, tz=None):
*fmt* is a :func:`strftime` format string; *tz* is the
:class:`tzinfo` instance.
"""
+ super(DateFormatter, self).__init__()
if tz is None:
tz = _get_rc_timezone()
self.fmt = fmt
self.tz = tz
- def __call__(self, x, pos=0):
+ def format_for_tick(self, x, pos=0):
if x == 0:
raise ValueError('DateFormatter found a value of x=0, which is '
'an illegal date. This usually occurs because '
@@ -601,13 +602,14 @@ def __init__(self, t, fmt, tz=None):
*t* is a sequence of dates (floating point days). *fmt* is a
:func:`strftime` format string.
"""
+ super(IndexDateFormatter, self).__init__()
if tz is None:
tz = _get_rc_timezone()
self.t = t
self.fmt = fmt
self.tz = tz
- def __call__(self, x, pos=0):
+ def format_for_tick(self, x, pos=0):
'Return the label for time *x* at position *pos*'
ind = int(np.round(x))
if ind >= len(self.t) or ind <= 0:
@@ -681,6 +683,7 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'):
if none of the values in ``self.scaled`` are greater than the unit
returned by ``locator._get_unit()``.
"""
+ super(AutoDateFormatter, self).__init__()
self._locator = locator
self._tz = tz
self.defaultfmt = defaultfmt
@@ -694,7 +697,7 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'):
1. / (SEC_PER_DAY):
rcParams['date.autoformatter.second']}
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
locator_unit_scale = float(self._locator._get_unit())
fmt = self.defaultfmt
@@ -706,7 +709,7 @@ def __call__(self, x, pos=None):
if isinstance(fmt, six.string_types):
self._formatter = DateFormatter(fmt, self._tz)
- result = self._formatter(x, pos)
+ result = self._formatter.format_for_tick(x, pos)
elif six.callable(fmt):
result = fmt(x, pos)
else:
@@ -1130,9 +1133,6 @@ def get_locator(self, dmin, dmax):
locator = MicrosecondLocator(interval, tz=self.tz)
locator.set_axis(self.axis)
-
- locator.set_view_interval(*self.axis.get_view_interval())
- locator.set_data_interval(*self.axis.get_data_interval())
return locator
@@ -1357,14 +1357,6 @@ def set_axis(self, axis):
self._wrapped_locator.set_axis(axis)
return DateLocator.set_axis(self, axis)
- def set_view_interval(self, vmin, vmax):
- self._wrapped_locator.set_view_interval(vmin, vmax)
- return DateLocator.set_view_interval(self, vmin, vmax)
-
- def set_data_interval(self, vmin, vmax):
- self._wrapped_locator.set_data_interval(vmin, vmax)
- return DateLocator.set_data_interval(self, vmin, vmax)
-
def __call__(self):
# if no data have been set, this will tank with a ValueError
try:
diff --git a/lib/matplotlib/projections/geo.py b/lib/matplotlib/projections/geo.py
index 338deec8279d..504a0ebc9d98 100644
--- a/lib/matplotlib/projections/geo.py
+++ b/lib/matplotlib/projections/geo.py
@@ -30,9 +30,10 @@ class ThetaFormatter(Formatter):
unit of radians into degrees and adds a degree symbol.
"""
def __init__(self, round_to=1.0):
+ super(GeoAxes.ThetaFormatter, self).__init__()
self._round_to = round_to
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
degrees = (x / np.pi) * 180.0
degrees = np.round(degrees / self._round_to) * self._round_to
if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
diff --git a/lib/matplotlib/projections/polar.py b/lib/matplotlib/projections/polar.py
index a52e343bb07e..db9a359f5ffa 100644
--- a/lib/matplotlib/projections/polar.py
+++ b/lib/matplotlib/projections/polar.py
@@ -171,7 +171,7 @@ class ThetaFormatter(Formatter):
Used to format the *theta* tick labels. Converts the native
unit of radians into degrees and adds a degree symbol.
"""
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
# \u00b0 : degree symbol
if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
return r"$%0.0f^\circ$" % ((x / np.pi) * 180.0)
diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py
index 23feaf7f57be..c0ec1a8a5c01 100644
--- a/lib/matplotlib/pyplot.py
+++ b/lib/matplotlib/pyplot.py
@@ -59,7 +59,7 @@
from matplotlib.patches import Polygon, Rectangle, Circle, Arrow
from matplotlib.widgets import SubplotTool, Button, Slider, Widget
-from .ticker import TickHelper, Formatter, FixedFormatter, NullFormatter,\
+from .ticker import Formatter, FixedFormatter, NullFormatter,\
FuncFormatter, FormatStrFormatter, ScalarFormatter,\
LogFormatter, LogFormatterExponent, LogFormatterMathtext,\
Locator, IndexLocator, FixedLocator, NullLocator,\
diff --git a/lib/matplotlib/testing/jpl_units/StrConverter.py b/lib/matplotlib/testing/jpl_units/StrConverter.py
index cdf44d903b07..9aa7750e7a2e 100644
--- a/lib/matplotlib/testing/jpl_units/StrConverter.py
+++ b/lib/matplotlib/testing/jpl_units/StrConverter.py
@@ -127,7 +127,6 @@ def convert( value, unit, axis ):
axis.set_ticklabels( labels )
# we have to do the following lines to make ax.autoscale_view work
loc = axis.get_major_locator()
- loc.set_bounds( ticks[0], ticks[-1] )
if ( isXAxis ):
ax.set_xlim( ticks[0], ticks[-1] )
diff --git a/lib/matplotlib/testing/jpl_units/UnitDblConverter.py b/lib/matplotlib/testing/jpl_units/UnitDblConverter.py
index c5e3307e1d66..5fb407766a70 100644
--- a/lib/matplotlib/testing/jpl_units/UnitDblConverter.py
+++ b/lib/matplotlib/testing/jpl_units/UnitDblConverter.py
@@ -89,7 +89,7 @@ def axisinfo( unit, axis ):
# If we want degrees for a polar plot, use the PolarPlotFormatter
majfmt = polar.PolarAxes.ThetaFormatter()
else:
- majfmt = U.UnitDblFormatter( useOffset = False )
+ majfmt = U.UnitDblFormatter()
return units.AxisInfo( majfmt = majfmt, label = label )
diff --git a/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py b/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py
index b4ccb1d21b09..8b186162a4cd 100644
--- a/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py
+++ b/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py
@@ -23,25 +23,9 @@
__all__ = [ 'UnitDblFormatter' ]
#===========================================================================
-class UnitDblFormatter( ticker.ScalarFormatter ):
- """The formatter for UnitDbl data types. This allows for formatting
- with the unit string.
- """
- def __init__( self, *args, **kwargs ):
- 'The arguments are identical to matplotlib.ticker.ScalarFormatter.'
- ticker.ScalarFormatter.__init__( self, *args, **kwargs )
-
- def __call__( self, x, pos = None ):
- 'Return the format for tick val x at position pos'
- if len(self.locs) == 0:
- return ''
- else:
- return str(x)
-
- def format_data_short( self, value ):
- "Return the value formatted in 'short' format."
- return str(value)
-
- def format_data( self, value ):
- "Return the value formatted into a string."
- return str(value)
+class UnitDblFormatter(ticker.Formatter):
+ """The formatter for UnitDbl data types. This allows for formatting
+ with the unit string.
+ """
+ def format_for_tick(self, value, pos=None):
+ return str(value)
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf
index ec3ad7f1ce74..f199a3f75e79 100644
Binary files a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf and b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png
index 457a4cdcbfae..602e54029b6e 100644
Binary files a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png and b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg
index 20b200e11b39..b46dda5771bd 100644
--- a/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg
+++ b/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg
@@ -27,7 +27,7 @@ z
" style="fill:#ffffff;"/>
-
@@ -57,20 +57,20 @@ L 518.400024 43.2
+" id="md6960c55f4" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="me8e5a1c3e0" style="stroke:#000000;stroke-width:0.5;"/>
-
+
@@ -115,22 +115,22 @@ Q 6.59375 54.828125 13.0625 64.515625
Q 19.53125 74.21875 31.78125 74.21875
" id="DejaVuSans-30"/>
-
+
-
-
+
+
-
+
-
+
@@ -160,22 +160,22 @@ Q 44.1875 33.984375 37.640625 27.21875
Q 31.109375 20.453125 19.1875 8.296875
" id="DejaVuSans-32"/>
-
+
-
-
+
+
-
+
-
+
@@ -199,22 +199,22 @@ L 4.890625 26.703125
z
" id="DejaVuSans-34"/>
-
+
-
-
+
+
-
+
-
+
@@ -249,22 +249,22 @@ Q 40.921875 74.21875 44.703125 73.484375
Q 48.484375 72.75 52.59375 71.296875
" id="DejaVuSans-36"/>
-
+
-
-
+
+
-
+
-
+
@@ -307,56 +307,70 @@ Q 25.390625 66.40625 21.84375 63.234375
Q 18.3125 60.0625 18.3125 54.390625
" id="DejaVuSans-38"/>
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -472,152 +495,153 @@ z
+" id="me44b38b30c" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="mda8a1b39f7" style="stroke:#000000;stroke-width:0.5;"/>
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
diff --git a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf
index e871bd270bf2..980ebc1fe854 100644
Binary files a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf and b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf differ
diff --git a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png
index 01d086b738d9..a0867256ee74 100644
Binary files a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png and b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg
index 589c70359f61..c869f0953d3d 100644
--- a/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg
+++ b/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg
@@ -27,7 +27,7 @@ z
" style="fill:#ffffff;"/>
-
+" id="m75a748e1cc" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="m0255bfac70" style="stroke:#000000;stroke-width:0.5;"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -197,20 +197,20 @@ L 0 4
+" id="mb9b80b1413" style="stroke:#000000;stroke-width:0.5;"/>
-
+
+" id="mc0c71078d8" style="stroke:#000000;stroke-width:0.5;"/>
-
+
@@ -236,7 +236,7 @@ Q 6.59375 54.828125 13.0625 64.515625
Q 19.53125 74.21875 31.78125 74.21875
" id="DejaVuSans-30"/>
-
+
@@ -244,12 +244,12 @@ Q 19.53125 74.21875 31.78125 74.21875
-
+
-
+
@@ -269,7 +269,7 @@ L 12.40625 0
z
" id="DejaVuSans-31"/>
-
+
@@ -277,12 +277,12 @@ z
-
+
-
+
@@ -312,7 +312,7 @@ Q 44.1875 33.984375 37.640625 27.21875
Q 31.109375 20.453125 19.1875 8.296875
" id="DejaVuSans-32"/>
-
+
@@ -320,12 +320,12 @@ Q 31.109375 20.453125 19.1875 8.296875
-
+
-
+
@@ -363,7 +363,7 @@ Q 53.90625 49.265625 50.4375 45.09375
Q 46.96875 40.921875 40.578125 39.3125
" id="DejaVuSans-33"/>
-
+
@@ -371,12 +371,12 @@ Q 46.96875 40.921875 40.578125 39.3125
-
+
-
+
@@ -400,7 +400,7 @@ L 4.890625 26.703125
z
" id="DejaVuSans-34"/>
-
+
@@ -408,12 +408,12 @@ z
-
+
-
+
@@ -444,7 +444,7 @@ Q 14.890625 38.140625 10.796875 36.28125
z
" id="DejaVuSans-35"/>
-
+
@@ -452,12 +452,12 @@ z
-
+
-
+
@@ -492,7 +492,7 @@ Q 40.921875 74.21875 44.703125 73.484375
Q 48.484375 72.75 52.59375 71.296875
" id="DejaVuSans-36"/>
-
+
@@ -500,12 +500,12 @@ Q 48.484375 72.75 52.59375 71.296875
-
+
-
+
@@ -521,7 +521,7 @@ L 8.203125 64.59375
z
" id="DejaVuSans-37"/>
-
+
@@ -529,12 +529,12 @@ z
-
+
-
+
@@ -577,7 +577,7 @@ Q 25.390625 66.40625 21.84375 63.234375
Q 18.3125 60.0625 18.3125 54.390625
" id="DejaVuSans-38"/>
-
+
@@ -585,12 +585,12 @@ Q 18.3125 60.0625 18.3125 54.390625
-
+
-
+
@@ -625,14 +625,28 @@ Q 16.21875 41.5 20.09375 36.953125
Q 23.96875 32.421875 30.609375 32.421875
" id="DejaVuSans-39"/>
-
+
-
+
+
-
-
-
-
+
+
+
+
+
@@ -675,7 +690,7 @@ z
" style="fill:#ffffff;"/>
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -833,120 +848,120 @@ L 518.4 43.2
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -962,7 +977,7 @@ z
" style="fill:#ffffff;"/>
-
-
+
-
+
-
+
@@ -1016,17 +1031,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1034,17 +1049,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1052,17 +1067,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1070,17 +1085,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1088,17 +1103,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1106,17 +1121,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1124,17 +1139,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1142,17 +1157,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1160,27 +1175,28 @@ L 274.909091 231.709091
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
+
@@ -1188,17 +1204,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1206,17 +1222,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1224,17 +1240,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1242,17 +1258,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1260,17 +1276,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1278,17 +1294,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1296,17 +1312,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1314,17 +1330,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1332,17 +1348,17 @@ L 274.909091 231.709091
-
+
-
+
-
+
@@ -1350,27 +1366,28 @@ L 274.909091 231.709091
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
+
@@ -1385,7 +1402,7 @@ z
" style="fill:#ffffff;"/>
-
-
+
-
+
-
+
@@ -1439,176 +1456,176 @@ L 518.4 231.709091
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
@@ -1637,120 +1665,120 @@ z
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1758,17 +1786,17 @@ z
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/lib/matplotlib/tests/test_backend_ps.py b/lib/matplotlib/tests/test_backend_ps.py
index ab346a4d0a41..b92479bd49fa 100644
--- a/lib/matplotlib/tests/test_backend_ps.py
+++ b/lib/matplotlib/tests/test_backend_ps.py
@@ -13,6 +13,8 @@
from matplotlib import patheffects
from matplotlib.testing.decorators import cleanup, knownfailureif
+from nose.tools import assert_equal
+
needs_ghostscript = knownfailureif(
matplotlib.checkdep_ghostscript()[0] is None,
@@ -51,8 +53,8 @@ def _test_savefig_to_stringio(format='ps', use_log=False):
# could change from run to run, such as the time.
values = [re.sub(b'%%.*?\n', b'', x) for x in values]
- assert values[0] == values[1]
- assert values[1] == values[2].replace(b'\r\n', b'\n')
+ assert_equal(values[0], values[1])
+ assert_equal(values[1], values[2].replace(b'\r\n', b'\n'))
for buffer in buffers:
buffer.close()
@@ -112,13 +114,13 @@ def test_composite_image():
fig.savefig(ps, format="ps")
ps.seek(0)
buff = ps.read()
- assert buff.count(six.b(' colorimage')) == 1
+ assert_equal(buff.count(six.b(' colorimage')), 1)
plt.rcParams['image.composite_image'] = False
with io.BytesIO() as ps:
fig.savefig(ps, format="ps")
ps.seek(0)
buff = ps.read()
- assert buff.count(six.b(' colorimage')) == 2
+ assert_equal(buff.count(six.b(' colorimage')), 2)
@cleanup
diff --git a/lib/matplotlib/tests/test_dates.py b/lib/matplotlib/tests/test_dates.py
index 54afc633bf7e..c830c488d90c 100644
--- a/lib/matplotlib/tests/test_dates.py
+++ b/lib/matplotlib/tests/test_dates.py
@@ -216,7 +216,7 @@ def test_date_formatter_callable():
formatter = mdates.AutoDateFormatter(locator)
formatter.scaled[-10] = callable_formatting_function
- assert_equal(formatter([datetime.datetime(2014, 12, 25)]),
+ assert_equal(formatter.format_for_tick([datetime.datetime(2014, 12, 25)]),
['25-12//2014'])
@@ -271,9 +271,9 @@ def test_empty_date_with_year_formatter():
def test_auto_date_locator():
def _create_auto_date_locator(date1, date2):
locator = mdates.AutoDateLocator()
- locator.create_dummy_axis()
- locator.set_view_interval(mdates.date2num(date1),
- mdates.date2num(date2))
+ locator.set_axis({})
+ locator.axis.set_view_interval(mdates.date2num(date1),
+ mdates.date2num(date2))
return locator
d1 = datetime.datetime(1990, 1, 1)
diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py
index 438be20aa7ce..557fd3607e09 100644
--- a/lib/matplotlib/tests/test_ticker.py
+++ b/lib/matplotlib/tests/test_ticker.py
@@ -161,7 +161,8 @@ def test_SymmetricalLogLocator_set_params():
def _logfe_helper(formatter, base, locs, i, expected_result):
vals = base**locs
- labels = [formatter(x, pos) for (x, pos) in zip(vals, i)]
+ labels = [formatter.format_for_tick(x, pos).replace("\N{MINUS SIGN}", "-")
+ for (x, pos) in zip(vals, i)]
nose.tools.assert_equal(labels, expected_result)
@@ -182,31 +183,31 @@ def get_view_interval(self):
formatter.axis = FakeAxis(1, base**4)
yield _logfe_helper, formatter, base, i, i, expected_result
- # Should be a blank string for non-integer powers if labelOnlyBase=True
- formatter = mticker.LogFormatterExponent(base=10, labelOnlyBase=True)
+ # Should be a blank string for non-integer powers if label_minor is False.
+ formatter = mticker.LogFormatterExponent(base=10, label_minor=False)
formatter.axis = FakeAxis()
- nose.tools.assert_equal(formatter(10**0.1), '')
+ nose.tools.assert_equal(formatter.format_for_tick(10**0.1), '')
# Otherwise, non-integer powers should be nicely formatted
locs = np.array([0.1, 0.00001, np.pi, 0.2, -0.2, -0.00001])
i = range(len(locs))
expected_result = ['0.1', '1e-05', '3.14', '0.2', '-0.2', '-1e-05']
for base in [2, 5, 10, np.pi, np.e]:
- formatter = mticker.LogFormatterExponent(base, labelOnlyBase=False)
+ formatter = mticker.LogFormatterExponent(base, label_minor=True)
formatter.axis = FakeAxis(1, base**10)
yield _logfe_helper, formatter, base, locs, i, expected_result
expected_result = ['3', '5', '12', '42']
locs = np.array([3, 5, 12, 42], dtype='float')
for base in [2, 5.0, 10.0, np.pi, np.e]:
- formatter = mticker.LogFormatterExponent(base, labelOnlyBase=False)
+ formatter = mticker.LogFormatterExponent(base, label_minor=True)
formatter.axis = FakeAxis(1, base**50)
yield _logfe_helper, formatter, base, locs, i, expected_result
def _pprint_helper(value, domain, expected):
fmt = mticker.LogFormatter()
- label = fmt.pprint_val(value, domain)
+ label = fmt._pprint_val(value, domain)
nose.tools.assert_equal(label, expected)
@@ -354,17 +355,17 @@ def test_use_offset():
for use_offset in [True, False]:
with matplotlib.rc_context({'axes.formatter.useoffset': use_offset}):
tmp_form = mticker.ScalarFormatter()
- nose.tools.assert_equal(use_offset, tmp_form.get_useOffset())
+ nose.tools.assert_equal(use_offset, tmp_form._use_offset)
def test_formatstrformatter():
# test % style formatter
tmp_form = mticker.FormatStrFormatter('%05d')
- nose.tools.assert_equal('00002', tmp_form(2))
+ nose.tools.assert_equal('00002', tmp_form.format_for_tick(2))
# test str.format() style formatter
tmp_form = mticker.StrMethodFormatter('{x:05d}')
- nose.tools.assert_equal('00002', tmp_form(2))
+ nose.tools.assert_equal('00002', tmp_form.format_for_tick(2))
if __name__ == '__main__':
import nose
diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py
index 7455d03365a2..5781e70eb93b 100644
--- a/lib/matplotlib/ticker.py
+++ b/lib/matplotlib/ticker.py
@@ -24,7 +24,7 @@
formatter::
- ax.get_xaxis().get_major_formatter().set_useOffset(False)
+ ax.get_xaxis().get_major_formatter().use_offset = False
set the rcParam ``axes.formatter.useoffset=False`` to turn it off
globally, or set a different formatter.
@@ -157,13 +157,13 @@
import decimal
import locale
import math
+import warnings
+
import numpy as np
from matplotlib import rcParams
from matplotlib import cbook
from matplotlib import transforms as mtransforms
-import warnings
-
if six.PY3:
long = int
@@ -175,10 +175,15 @@ def _mathdefault(s):
math font already matches the default font, so we don't need to do
that anymore.
"""
- if rcParams['_internal.classic_mode']:
- return '\\mathdefault{%s}' % s
+ assert s[0] == s[-1] == "$"
+ if rcParams["_internal.classic_mode"] and not rcParams["text.usetex"]:
+ return r"$\mathdefault{{{}}}$".format(s[1:-1])
else:
- return '{%s}' % s
+ return s
+
+
+def _unicode_minus(s):
+ return s.replace("-", "\N{MINUS SIGN}")
class _DummyAxis(object):
@@ -207,534 +212,398 @@ def get_tick_space(self):
return 9
-class TickHelper(object):
- axis = None
-
- def set_axis(self, axis):
- self.axis = axis
-
- def create_dummy_axis(self, **kwargs):
- if self.axis is None:
- self.axis = _DummyAxis(**kwargs)
-
- def set_view_interval(self, vmin, vmax):
- self.axis.set_view_interval(vmin, vmax)
+class _TickHelper(object):
+ def __init__(self):
+ self.axis = None
- def set_data_interval(self, vmin, vmax):
- self.axis.set_data_interval(vmin, vmax)
+ def set_axis(self, axis_or_kw):
+ if isinstance(axis_or_kw, dict):
+ self.axis = _DummyAxis(**axis_or_kw)
+ else:
+ self.axis = axis_or_kw
- def set_bounds(self, vmin, vmax):
- self.set_view_interval(vmin, vmax)
- self.set_data_interval(vmin, vmax)
+class Formatter(_TickHelper):
+ def __init__(self):
+ super(Formatter, self).__init__()
+ self._locs = []
+ self._offset_text = ""
-class Formatter(TickHelper):
- """
- Convert the tick location to a string
- """
- # some classes want to see all the locs to help format
- # individual ones
- locs = []
+ @property
+ def locs(self):
+ return self._locs
- def __call__(self, x, pos=None):
- """Return the format for tick val x at position pos; pos=None
- indicated unspecified"""
- raise NotImplementedError('Derived must override')
+ @locs.setter
+ def locs(self, locs):
+ self._locs = np.asarray(locs)
- def format_data(self, value):
- return self.__call__(value)
+ @property
+ def offset_text(self):
+ return self._offset_text
- def format_data_short(self, value):
- """return a short string version"""
- return self.format_data(value)
+ @offset_text.setter
+ def offset_text(self, s):
+ self._offset_text = s
- def get_offset(self):
- return ''
+ def format_for_tick(self, value, pos=None):
+ return ""
- def set_locs(self, locs):
- self.locs = locs
-
- def fix_minus(self, s):
- """
- Some classes may want to replace a hyphen for minus with the
- proper unicode symbol (U+2212) for typographical correctness.
- The default is to not replace it.
-
- Note, if you use this method, e.g., in :meth:`format_data` or
- call, you probably don't want to use it for
- :meth:`format_data_short` since the toolbar uses this for
- interactive coord reporting and I doubt we can expect GUIs
- across platforms will handle the unicode correctly. So for
- now the classes that override :meth:`fix_minus` should have an
- explicit :meth:`format_data_short` method
- """
- return s
-
-
-class IndexFormatter(Formatter):
- """
- format the position x to the nearest i-th label where i=int(x+0.5)
- """
- def __init__(self, labels):
- self.labels = labels
- self.n = len(labels)
-
- def __call__(self, x, pos=None):
- """Return the format for tick val x at position pos; pos=None
- indicated unspecified"""
- i = int(x + 0.5)
- if i < 0:
- return ''
- elif i >= self.n:
- return ''
- else:
- return self.labels[i]
+ def format_for_cursor(self, value):
+ return self.format_for_tick(value)
class NullFormatter(Formatter):
- 'Always return the empty string'
-
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- return ''
+ """Always return the empty string.
+ """
class FixedFormatter(Formatter):
- 'Return fixed strings for tick labels'
- def __init__(self, seq):
- """
- *seq* is a sequence of strings. For positions ``i < len(seq)`` return
- *seq[i]* regardless of *x*. Otherwise return ''
- """
- self.seq = seq
- self.offset_string = ''
-
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- if pos is None or pos >= len(self.seq):
- return ''
- else:
- return self.seq[pos]
+ """Return fixed strings for tick labels.
+ """
- def get_offset(self):
- return self.offset_string
+ def __init__(self, seq):
+ super(FixedFormatter, self).__init__()
+ self._seq = seq
- def set_offset_string(self, ofs):
- self.offset_string = ofs
+ def format_for_tick(self, x, pos=None):
+ """Return the format for tick val *x* at position *pos*.
+ """
+ return self._seq[pos] if pos < len(self._seq) else ""
class FuncFormatter(Formatter):
- """
- User defined function for formatting
+ """User defined function for formatting.
The function should take in two inputs (tick value *x* and position *pos*)
- and return a string
+ and return a string.
"""
- def __init__(self, func):
- self.func = func
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- return self.func(x, pos)
+ def __init__(self, func):
+ super(FuncFormatter, self).__init__()
+ self.format_for_tick = func
class FormatStrFormatter(Formatter):
+ """Use an old-style ('%' operator) format string to format the tick.
"""
- Use an old-style ('%' operator) format string to format the tick
- """
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- return self.fmt % x
-
-class StrMethodFormatter(Formatter):
- """
- Use a new-style format string (as used by `str.format()`)
- to format the tick. The field formatting must be labeled `x`.
- """
def __init__(self, fmt):
- self.fmt = fmt
+ super(FormatStrFormatter, self).__init__()
+ self._fmt = fmt
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- return self.fmt.format(x=x)
+ def format_for_tick(self, x, pos=None):
+ return self._fmt % x
-class OldScalarFormatter(Formatter):
- """
- Tick location is a plain old number.
+class StrMethodFormatter(Formatter):
+ """Use a new-style format string (as used by `str.format()`) to
+ format the tick. The field formatting must be labeled `x` and/or
+ `pos`.
"""
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- xmin, xmax = self.axis.get_view_interval()
- d = abs(xmax - xmin)
-
- return self.pprint_val(x, d)
-
- def pprint_val(self, x, d):
- #if the number is not too big and it's an int, format it as an
- #int
- if abs(x) < 1e4 and x == int(x):
- return '%d' % x
+ def __init__(self, fmt):
+ super(StrMethodFormatter, self).__init__()
+ self._fmt = fmt
- if d < 1e-2:
- fmt = '%1.3e'
- elif d < 1e-1:
- fmt = '%1.3f'
- elif d > 1e5:
- fmt = '%1.1e'
- elif d > 10:
- fmt = '%1.1f'
- elif d > 1:
- fmt = '%1.2f'
- else:
- fmt = '%1.3f'
- s = fmt % x
- #print d, x, fmt, s
- tup = s.split('e')
- if len(tup) == 2:
- mantissa = tup[0].rstrip('0').rstrip('.')
- sign = tup[1][0].replace('+', '')
- exponent = tup[1][1:].lstrip('0')
- s = '%se%s%s' % (mantissa, sign, exponent)
- else:
- s = s.rstrip('0').rstrip('.')
- return s
+ def format_for_tick(self, x, pos=None):
+ return self._fmt.format(x=x, pos=pos)
class ScalarFormatter(Formatter):
- """
- Tick location is a plain old number. If useOffset==True and the data range
- is much smaller than the data average, then an offset will be determined
- such that the tick labels are meaningful. Scientific notation is used for
- data < 10^-n or data >= 10^m, where n and m are the power limits set using
+ """Tick location is a plain old number. If use_offset==True
+ and the data range is much smaller than the data average, then
+ an offset will be determined such that the tick labels are
+ meaningful. Scientific notation is used for data < 10^-n or
+ data >= 10^m, where n and m are the power limits set using
set_powerlimits((n,m)). The defaults for these are controlled by the
axes.formatter.limits rc parameter.
-
"""
def __init__(self, useOffset=None, useMathText=None, useLocale=None):
- # useOffset allows plotting small data ranges with large offsets: for
- # example: [1+1e-9,1+2e-9,1+3e-9] useMathText will render the offset
- # and scientific notation in mathtext
-
- if useOffset is None:
- useOffset = rcParams['axes.formatter.useoffset']
- self.set_useOffset(useOffset)
- self._usetex = rcParams['text.usetex']
- if useMathText is None:
- useMathText = rcParams['axes.formatter.use_mathtext']
- self._useMathText = useMathText
- self.orderOfMagnitude = 0
- self.format = ''
+ super(ScalarFormatter, self).__init__()
+ self._use_offset = (useOffset if useOffset is not None
+ else rcParams["axes.formatter.useoffset"])
+ self._usetex = rcParams["text.usetex"]
+ self._use_mathtext = (useMathText if useMathText is not None
+ else rcParams["axes.formatter.use_mathtext"])
+ self._use_locale = (useLocale if useLocale is not None
+ else rcParams["axes.formatter.use_locale"])
self._scientific = True
self._powerlimits = rcParams['axes.formatter.limits']
- if useLocale is None:
- useLocale = rcParams['axes.formatter.use_locale']
- self._useLocale = useLocale
-
- def get_useOffset(self):
- return self._useOffset
-
- def set_useOffset(self, val):
- if val in [True, False]:
- self.offset = 0
- self._useOffset = val
- else:
- self._useOffset = False
- self.offset = val
-
- useOffset = property(fget=get_useOffset, fset=set_useOffset)
-
- def get_useLocale(self):
- return self._useLocale
-
- def set_useLocale(self, val):
- if val is None:
- self._useLocale = rcParams['axes.formatter.use_locale']
- else:
- self._useLocale = val
-
- useLocale = property(fget=get_useLocale, fset=set_useLocale)
-
- def fix_minus(self, s):
- """use a unicode minus rather than hyphen"""
- if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']:
- return s
- else:
- return s.replace('-', '\u2212')
-
- def __call__(self, x, pos=None):
- 'Return the format for tick val *x* at position *pos*'
- if len(self.locs) == 0:
- return ''
- else:
- s = self.pprint_val(x)
- return self.fix_minus(s)
-
- def set_scientific(self, b):
- '''True or False to turn scientific notation on or off
- see also :meth:`set_powerlimits`
- '''
- self._scientific = bool(b)
-
- def set_powerlimits(self, lims):
- '''
- Sets size thresholds for scientific notation.
-
- e.g., ``formatter.set_powerlimits((-3, 4))`` sets the pre-2007 default
- in which scientific notation is used for numbers less than 1e-3 or
- greater than 1e4.
- See also :meth:`set_scientific`.
- '''
- if len(lims) != 2:
- raise ValueError("'lims' must be a sequence of length 2")
+ self._offset = 0
+ self._oom = self._tick_precision = self._cursor_precision = None
+
+ def _format_maybe_locale(self, fmt, *args):
+ return (locale.format_string(fmt, *args) if self._use_locale
+ else fmt % args)
+
+ @property
+ def locs(self):
+ return self._locs
+
+ @locs.setter
+ def locs(self, locs):
+ self._locs = np.asarray(locs)
+ self._update()
+
+ @property
+ def use_offset(self):
+ return self._use_offset
+
+ @use_offset.setter
+ def use_offset(self, b):
+ self._use_offset = b
+ self._update()
+
+ @property
+ def use_locale(self):
+ return self._use_locale
+
+ @use_locale.setter
+ def use_locale(self, b):
+ self._use_locale = b
+ self._update()
+
+ @property
+ def scientific(self):
+ return self._scientific
+
+ @scientific.setter
+ def scientific(self, b):
+ self._scientific = b
+ self._update()
+
+ @property
+ def powerlimits(self):
+ return self._powerlimits
+
+ @powerlimits.setter
+ def powerlimits(self, lims):
self._powerlimits = lims
+ self._update()
- def format_data_short(self, value):
- """return a short formatted string representation of a number"""
- if self._useLocale:
- return locale.format_string('%-12g', (value,))
- else:
- return '%-12g' % value
+ def _update(self):
+ self._set_offset()
+ self._set_oom()
+ self._set_precision()
- def format_data(self, value):
- 'return a formatted string representation of a number'
- if self._useLocale:
- s = locale.format_string('%1.10e', (value,))
- else:
- s = '%1.10e' % value
- s = self._formatSciNotation(s)
- return self.fix_minus(s)
-
- def get_offset(self):
- """Return scientific notation, plus offset"""
- if len(self.locs) == 0:
- return ''
- s = ''
- if self.orderOfMagnitude or self.offset:
- offsetStr = ''
- sciNotStr = ''
- if self.offset:
- offsetStr = self.format_data(self.offset)
- if self.offset > 0:
- offsetStr = '+' + offsetStr
- if self.orderOfMagnitude:
- if self._usetex or self._useMathText:
- sciNotStr = self.format_data(10 ** self.orderOfMagnitude)
+ def _set_offset(self):
+ locs = self.locs
+ if not self._use_offset:
+ self._offset = 0
+ return
+ # Restrict to visible ticks.
+ vmin, vmax = sorted(self.axis.get_view_interval())
+ locs = locs[(vmin <= locs) & (locs <= vmax)]
+ if not len(locs):
+ self._offset = 0
+ return
+ lmin, lmax = locs.min(), locs.max()
+ # min, max comparing absolute values (we want division to round towards
+ # zero so we work on absolute values).
+ abs_min, abs_max = sorted(map(abs, [lmin, lmax]))
+ # Only use offset if there are at least two ticks, every tick has the
+ # same sign, and if the span is small compared to the absolute values.
+ if (lmin == lmax or lmin <= 0 <= lmax or
+ (abs_max - abs_min) / abs_max >= 1e-2):
+ self._offset = 0
+ return
+ sign = math.copysign(1, lmin)
+ # What is the smallest power of ten such that abs_min and abs_max are
+ # equal up to that precision?
+ oom = 10. ** math.ceil(math.log10(abs_max))
+ while True:
+ if abs_min // oom != abs_max // oom:
+ oom *= 10
+ break
+ oom /= 10
+ if (abs_max - abs_min) / oom <= 1e-2:
+ # Handle the case of straddling a multiple of a large power of ten
+ # (relative to the span).
+ # What is the smallest power of ten such that abs_min and abs_max
+ # at most 1 apart?
+ oom = 10. ** math.ceil(math.log10(abs_max))
+ while True:
+ if abs_max // oom - abs_min // oom > 1:
+ oom *= 10
+ break
+ oom /= 10
+ self._offset = sign * (abs_max // oom) * oom
+
+ def _set_oom(self):
+ # If scientific notation is to be used, find the appropriate exponent.
+ # If using an offset, find the exponent after applying the offset.
+ if self._scientific:
+ locs = self.locs
+ vmin, vmax = sorted(self.axis.get_view_interval())
+ # Restrict to visible ticks.
+ locs = locs[(vmin <= locs) & (locs <= vmax)]
+ if len(locs):
+ deltas = np.abs(locs - self._offset)
+ # Don't take tiny, nonzero tick values into account.
+ deltas = deltas[deltas > 1e-10 * deltas.max()]
+ if len(deltas):
+ oom = int(math.floor(math.log10(deltas.min())))
+ self._oom = (oom if (oom <= self._powerlimits[0] or
+ oom >= self._powerlimits[1])
+ else 0)
else:
- sciNotStr = '1e%d' % self.orderOfMagnitude
- if self._useMathText:
- if sciNotStr != '':
- sciNotStr = r'\times%s' % _mathdefault(sciNotStr)
- s = ''.join(('$', sciNotStr, _mathdefault(offsetStr), '$'))
- elif self._usetex:
- if sciNotStr != '':
- sciNotStr = r'\times%s' % sciNotStr
- s = ''.join(('$', sciNotStr, offsetStr, '$'))
+ self._oom = 0
else:
- s = ''.join((sciNotStr, offsetStr))
-
- return self.fix_minus(s)
-
- def set_locs(self, locs):
- 'set the locations of the ticks'
- self.locs = locs
- if len(self.locs) > 0:
- vmin, vmax = self.axis.get_view_interval()
- d = abs(vmax - vmin)
- if self._useOffset:
- self._set_offset(d)
- self._set_orderOfMagnitude(d)
- self._set_format(vmin, vmax)
+ self._oom = 0
+ else:
+ self._oom = 0
- def _set_offset(self, range):
- # offset of 20,001 is 20,000, for example
+ def _set_precision(self):
locs = self.locs
-
- if locs is None or not len(locs) or range == 0:
- self.offset = 0
- return
vmin, vmax = sorted(self.axis.get_view_interval())
- locs = np.asarray(locs)
+ # Restrict to visible ticks.
locs = locs[(vmin <= locs) & (locs <= vmax)]
- ave_loc = np.mean(locs)
- if len(locs) and ave_loc: # dont want to take log10(0)
- ave_oom = math.floor(math.log10(np.mean(np.absolute(locs))))
- range_oom = math.floor(math.log10(range))
-
- if np.absolute(ave_oom - range_oom) >= 3: # four sig-figs
- p10 = 10 ** range_oom
- if ave_loc < 0:
- self.offset = (math.ceil(np.max(locs) / p10) * p10)
- else:
- self.offset = (math.floor(np.min(locs) / p10) * p10)
+ # Tick precision.
+ if len(locs):
+ ticks = np.abs(locs - self._offset) / 10. ** self._oom
+ # Don't take tiny, nonzero tick values into account.
+ ticks = ticks[ticks > 1e-10 * ticks.max()]
+ if len(ticks):
+ thresh = 10. ** (math.floor(math.log10(ticks.min())) - 3)
+ precision = 0
+ while (np.abs(np.round(ticks, precision) - ticks).max() >
+ thresh):
+ precision += 1
+ # Work around rounding errors, e.g. test_formatter_large_small:
+ # increase scale and recompute precision.
+ if (self._oom and
+ np.abs(np.round(ticks, precision)).min() >= 10):
+ self._oom += 1
+ self._set_precision()
+ return
+ self._tick_precision = precision
else:
- self.offset = 0
-
- def _set_orderOfMagnitude(self, range):
- # if scientific notation is to be used, find the appropriate exponent
- # if using an numerical offset, find the exponent after applying the
- # offset
- if not self._scientific:
- self.orderOfMagnitude = 0
- return
- locs = np.absolute(self.locs)
- if self.offset:
- oom = math.floor(math.log10(range))
+ self._tick_precision = 0
else:
- if locs[0] > locs[-1]:
- val = locs[0]
+ self._tick_precision = 0
+ # Cursor precision.
+ self._cursor_precision = (
+ 3 - int(math.floor(math.log10(vmax - vmin)))) if vmax > vmin else 0
+
+ @property
+ def offset_text(self):
+ if self._oom or self._offset:
+ if self._offset:
+ offset_str = self._format_offset()
else:
- val = locs[-1]
- if val == 0:
- oom = 0
+ offset_str = ""
+ if self._oom:
+ if self._use_mathtext or rcParams["text.usetex"]:
+ sci_not_str = "$10^{{{}}}$".format(self._oom)
+ else:
+ sci_not_str = "1e{}".format(self._oom)
else:
- oom = math.floor(math.log10(val))
- if oom <= self._powerlimits[0]:
- self.orderOfMagnitude = oom
- elif oom >= self._powerlimits[1]:
- self.orderOfMagnitude = oom
- else:
- self.orderOfMagnitude = 0
-
- def _set_format(self, vmin, vmax):
- # set the format string to format all the ticklabels
- if len(self.locs) < 2:
- # Temporarily augment the locations with the axis end points.
- _locs = list(self.locs) + [vmin, vmax]
- else:
- _locs = self.locs
- locs = (np.asarray(_locs) - self.offset) / 10. ** self.orderOfMagnitude
- loc_range = np.ptp(locs)
- # Curvilinear coordinates can yield two identical points.
- if loc_range == 0:
- loc_range = np.max(np.abs(locs))
- # Both points might be zero.
- if loc_range == 0:
- loc_range = 1
- if len(self.locs) < 2:
- # We needed the end points only for the loc_range calculation.
- locs = locs[:-2]
- loc_range_oom = int(math.floor(math.log10(loc_range)))
- # first estimate:
- sigfigs = max(0, 3 - loc_range_oom)
- # refined estimate:
- thresh = 1e-3 * 10 ** loc_range_oom
- while sigfigs >= 0:
- if np.abs(locs - np.round(locs, decimals=sigfigs)).max() < thresh:
- sigfigs -= 1
+ sci_not_str = ""
+ if self._use_mathtext or rcParams["text.usetex"]:
+ assert offset_str[0] == offset_str[-1] == "$"
+ if sci_not_str:
+ assert sci_not_str[0] == sci_not_str[-1] == "$"
+ s = r"$\times {} {}$".format(
+ sci_not_str[1:-1], offset_str[1:-1])
+ else:
+ s = offset_str
+ return _mathdefault(s)
else:
- break
- sigfigs += 1
- self.format = '%1.' + str(sigfigs) + 'f'
- if self._usetex:
- self.format = '$%s$' % self.format
- elif self._useMathText:
- self.format = '$%s$' % _mathdefault(self.format)
-
- def pprint_val(self, x):
- xp = (x - self.offset) / (10. ** self.orderOfMagnitude)
- if np.absolute(xp) < 1e-8:
- xp = 0
- if self._useLocale:
- return locale.format_string(self.format, (xp,))
- else:
- return self.format % xp
-
- def _formatSciNotation(self, s):
- # transform 1e+004 into 1e4, for example
- if self._useLocale:
- decimal_point = locale.localeconv()['decimal_point']
- positive_sign = locale.localeconv()['positive_sign']
- else:
- decimal_point = '.'
- positive_sign = '+'
- tup = s.split('e')
- try:
- significand = tup[0].rstrip('0').rstrip(decimal_point)
- sign = tup[1][0].replace(positive_sign, '')
- exponent = tup[1][1:].lstrip('0')
- if self._useMathText or self._usetex:
- if significand == '1' and exponent != '':
- # reformat 1x10^y as 10^y
- significand = ''
- if exponent:
- exponent = '10^{%s%s}' % (sign, exponent)
- if significand and exponent:
- return r'%s{\times}%s' % (significand, exponent)
+ if sci_not_str:
+ s = "\N{MULTIPLICATION SIGN}{}{}".format(
+ sci_not_str, offset_str)
else:
- return r'%s%s' % (significand, exponent)
+ s = offset_str
+ return _unicode_minus(s)
+ else:
+ return ""
+
+ def _format_offset(self):
+ offset = self._offset
+ # How many significant digits are needed to represent offset to
+ # 10 ** (oom - tick_precision)?
+ precision = (
+ (int(math.floor(math.log10(abs(offset)))) if offset else 0) +
+ self._tick_precision - self._oom + 1)
+ if .0001 <= abs(offset) < 10000 or offset == 0:
+ # %g doesn't use scientific notation in this range.
+ s = (self._format_maybe_locale("%#-+.*g", precision, offset).
+ rstrip(locale.localeconv()["decimal_point"]
+ if self._use_locale else "."))
+ if self._use_mathtext or rcParams["text.usetex"]:
+ return "${}$".format(s)
else:
- s = ('%se%s%s' % (significand, sign, exponent)).rstrip('e')
return s
- except IndexError:
- return s
+ exp = int(math.floor(math.log10(abs(offset))))
+ significand = offset / 10. ** exp
+ # 1 digit before decimal point, (precision - 1) after.
+ significand_s = self._format_maybe_locale(
+ "%-+.*f", precision - 1, significand)
+ if self._use_mathtext or rcParams["text.usetex"]:
+ return r"${} \times 10^{{{}}}$".format(significand_s, exp)
+ else:
+ return "{}e{}".format(significand_s, exp)
+
+ def format_for_tick(self, value, pos=None):
+ # Get rid of signed zeros (sic).
+ scaled = round((value - self._offset) / 10. ** self._oom,
+ self._tick_precision)
+ if scaled == 0:
+ scaled = 0
+ s = self._format_maybe_locale("%-.*f", self._tick_precision, scaled)
+ if self._use_mathtext or rcParams["text.usetex"]:
+ return _mathdefault("${}$".format(s))
+ else:
+ return _unicode_minus(s)
+
+ def format_for_cursor(self, value):
+ # How many significant digits needed to represent value to
+ # 10 ** -cursor_precision?
+ precision = (
+ math.floor(math.log10(abs(value))) + self._cursor_precision
+ if value else self._cursor_precision) + 1
+ return _unicode_minus(
+ self._format_maybe_locale("%#-.*g", precision, value))
class LogFormatter(Formatter):
+ """Format values for log axis.
"""
- Format values for log axis;
- """
- def __init__(self, base=10.0, labelOnlyBase=True):
+ def __init__(self, base=10., label_minor=False):
"""
- *base* is used to locate the decade tick,
- which will be the only one to be labeled if *labelOnlyBase*
- is ``False``
+ *base* is used to locate the decade tick, which will be the only
+ one to be labeled if *label_minor* is ``False``.
"""
- self._base = base + 0.0
- self.labelOnlyBase = labelOnlyBase
+ super(LogFormatter, self).__init__()
+ self.base = base
+ self.label_minor = label_minor
- def base(self, base):
- """change the *base* for labeling - warning: should always match the
- base used for :class:`LogLocator`"""
- self._base = base
-
- def label_minor(self, labelOnlyBase):
- 'switch on/off minor ticks labeling'
- self.labelOnlyBase = labelOnlyBase
-
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
"""Return the format for tick val *x* at position *pos*"""
- vmin, vmax = self.axis.get_view_interval()
- d = abs(vmax - vmin)
- b = self._base
+ vmin, vmax = sorted(self.axis.get_view_interval())
+ d = vmax - vmin
+ b = self.base
if x == 0.0:
return '0'
sign = np.sign(x)
# only label the decades
fx = math.log(abs(x)) / math.log(b)
- isDecade = is_close_to_int(fx)
- if not isDecade and self.labelOnlyBase:
- s = ''
+ is_decade = is_close_to_int(fx)
+ if not (is_decade or self.label_minor):
+ s = ""
elif x > 10000:
s = '%1.0e' % x
elif x < 1:
s = '%1.0e' % x
else:
- s = self.pprint_val(x, d)
+ s = self._pprint_val(x, d)
if sign == -1:
s = '-%s' % s
+ return _unicode_minus(s)
- return self.fix_minus(s)
-
- def format_data(self, value):
- b = self.labelOnlyBase
- self.labelOnlyBase = False
- value = cbook.strip_math(self.__call__(value))
- self.labelOnlyBase = b
- return value
-
- def format_data_short(self, value):
- 'return a short formatted string representation of a number'
- return '%-12g' % value
-
- def pprint_val(self, x, d):
+ def _pprint_val(self, x, d):
#if the number is not too big and it's an int, format it as an
#int
if abs(x) < 1e4 and x == int(x):
@@ -766,38 +635,39 @@ def pprint_val(self, x, d):
s = s.rstrip('0').rstrip('.')
return s
+ def format_for_cursor(self, value):
+ 'return a short formatted string representation of a number'
+ return '%-12g' % value
+
class LogFormatterExponent(LogFormatter):
"""
Format values for log axis; using ``exponent = log_base(value)``
"""
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
"""Return the format for tick val *x* at position *pos*"""
vmin, vmax = self.axis.get_view_interval()
vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
d = abs(vmax - vmin)
- b = self._base
+ b = self.base
if x == 0:
return '0'
sign = np.sign(x)
# only label the decades
fx = math.log(abs(x)) / math.log(b)
- isDecade = is_close_to_int(fx)
- if not isDecade and self.labelOnlyBase:
- s = ''
- elif abs(fx) > 10000:
- s = '%1.0g' % fx
- elif abs(fx) < 1:
+ is_decade = is_close_to_int(fx)
+ if not (is_decade or self.label_minor):
+ s = ""
+ elif abs(fx) < 1 or abs(fx) > 10000:
s = '%1.0g' % fx
else:
fd = math.log(abs(d)) / math.log(b)
- s = self.pprint_val(fx, fd)
+ s = self._pprint_val(fx, fd)
if sign == -1:
s = '-%s' % s
-
- return self.fix_minus(s)
+ return _unicode_minus(s)
class LogFormatterMathtext(LogFormatter):
@@ -805,22 +675,18 @@ class LogFormatterMathtext(LogFormatter):
Format values for log axis; using ``exponent = log_base(value)``
"""
- def __call__(self, x, pos=None):
+ def format_for_tick(self, x, pos=None):
'Return the format for tick val *x* at position *pos*'
- b = self._base
- usetex = rcParams['text.usetex']
+ b = self.base
# only label the decades
if x == 0:
- if usetex:
- return '$0$'
- else:
- return '$%s$' % _mathdefault('0')
+ return _mathdefault("$0$")
fx = math.log(abs(x)) / math.log(b)
is_decade = is_close_to_int(fx)
- sign_string = '-' if x < 0 else ''
+ sign_string = '-' if x < 0 else ""
# use string formatting of the base if it is not an integer
if b % 1 == 0.0:
@@ -828,46 +694,35 @@ def __call__(self, x, pos=None):
else:
base = '%s' % b
- if not is_decade and self.labelOnlyBase:
- return ''
+ if not (is_decade or self.label_minor):
+ return ""
elif not is_decade:
- if usetex:
- return (r'$%s%s^{%.2f}$') % \
- (sign_string, base, fx)
- else:
- return ('$%s$' % _mathdefault(
- '%s%s^{%.2f}' %
- (sign_string, base, fx)))
+ return _mathdefault(r"$%s%s^{%.2f}$" %
+ (sign_string, base, fx))
else:
- if usetex:
- return (r'$%s%s^{%d}$') % (sign_string,
- base,
- nearest_long(fx))
- else:
- return ('$%s$' % _mathdefault(
- '%s%s^{%d}' %
- (sign_string, base, nearest_long(fx))))
+ return _mathdefault(r"$%s%s^{%d}$" %
+ (sign_string, base, round(fx)))
class LogitFormatter(Formatter):
- '''Probability formatter (using Math text)'''
- def __call__(self, x, pos=None):
- s = ''
+ ""'Probability formatter (using Math text)""'
+ def format_for_tick(self, x, pos=None):
+ s = ""
if 0.01 <= x <= 0.99:
s = '{:.2f}'.format(x)
elif x < 0.01:
if is_decade(x):
- s = '$10^{{{:.0f}}}$'.format(np.log10(x))
+ s = _mathdefault('$10^{{{:.0f}}}$'.format(np.log10(x)))
else:
- s = '${:.5f}$'.format(x)
+ s = _mathdefault('${:.5f}$'.format(x))
else: # x > 0.99
if is_decade(1-x):
- s = '$1-10^{{{:.0f}}}$'.format(np.log10(1-x))
+ s = _mathdefault('$1-10^{{{:.0f}}}$'.format(np.log10(1-x)))
else:
- s = '$1-{:.5f}$'.format(1-x)
+ s = _mathdefault('$1-{:.5f}$'.format(1-x))
return s
- def format_data_short(self, value):
+ def format_for_cursor(self, value):
'return a short formatted string representation of a number'
return '%-12g' % value
@@ -878,10 +733,6 @@ class EngFormatter(Formatter):
plus a specified unit, e.g., 10 MHz instead of 1e7.
"""
- # the unicode for -6 is the greek letter mu
- # commeted here due to bug in pep8
- # (https://github.com/jcrocholl/pep8/issues/271)
-
# The SI engineering prefixes
ENG_PREFIXES = {
-24: "y",
@@ -890,7 +741,7 @@ class EngFormatter(Formatter):
-15: "f",
-12: "p",
-9: "n",
- -6: "\u03bc",
+ -6: "\N{MICRO SIGN}",
-3: "m",
0: "",
3: "k",
@@ -904,14 +755,18 @@ class EngFormatter(Formatter):
}
def __init__(self, unit="", places=None):
+ super(EngFormatter, self).__init__()
self.unit = unit
self.places = places
- def __call__(self, x, pos=None):
- s = "%s%s" % (self.format_eng(x), self.unit)
- return self.fix_minus(s)
+ def format_for_tick(self, x, pos=None):
+ s = "%s%s" % (self._format_eng(x), self.unit)
+ if rcParams["text.usetex"]:
+ return _mathdefault(s)
+ else:
+ return _unicode_minus(s)
- def format_eng(self, num):
+ def _format_eng(self, num):
""" Formats a number in engineering notation, appending a letter
representing the power of 1000 of the original number. Some examples:
@@ -963,7 +818,7 @@ def format_eng(self, num):
return formatted.strip()
-class Locator(TickHelper):
+class Locator(_TickHelper):
"""
Determine the tick locations;
@@ -1072,6 +927,7 @@ class IndexLocator(Locator):
"""
def __init__(self, base, offset):
'place ticks on the i-th data points where (i-offset)%base==0'
+ super(IndexLocator, self).__init__()
self._base = base
self.offset = offset
@@ -1104,6 +960,7 @@ class FixedLocator(Locator):
"""
def __init__(self, locs, nbins=None):
+ super(FixedLocator, self).__init__()
self.locs = np.asarray(locs)
self.nbins = nbins
if self.nbins is not None:
@@ -1172,6 +1029,7 @@ def __init__(self, numticks=None, presets=None):
"""
Use presets to set locs based on lom. A dict mapping vmin, vmax->locs
"""
+ super(LinearLocator, self).__init__()
self.numticks = numticks
if presets is None:
self.presets = {}
@@ -1286,6 +1144,7 @@ class MultipleLocator(Locator):
"""
def __init__(self, base=1.0):
+ super(MultipleLocator, self).__init__()
self._base = Base(base)
def set_params(self, base):
@@ -1391,6 +1250,7 @@ def __init__(self, *args, **kwargs):
# I left "trim" out; it defaults to True, and it is not
# clear that there is any use case for False, so we may
# want to remove that kwarg. EF 2010/04/18
+ super(MaxNLocator, self).__init__()
if args:
kwargs['nbins'] = args[0]
if len(args) > 1:
@@ -1507,15 +1367,6 @@ def decade_up(x, base=10):
return base ** lx
-def nearest_long(x):
- if x == 0:
- return long(0)
- elif x > 0:
- return long(x + 0.5)
- else:
- return long(x - 0.5)
-
-
def is_decade(x, base=10):
if not np.isfinite(x):
return False
@@ -1528,7 +1379,7 @@ def is_decade(x, base=10):
def is_close_to_int(x):
if not np.isfinite(x):
return False
- return abs(x - nearest_long(x)) < 1e-10
+ return abs(x - round(x)) < 1e-10
class LogLocator(Locator):
@@ -1540,6 +1391,7 @@ def __init__(self, base=10.0, subs=[1.0], numdecs=4, numticks=15):
"""
place ticks on the location= base**i*subs[j]
"""
+ super(LogLocator, self).__init__()
self.base(base)
self.subs(subs)
self.numticks = numticks
@@ -1678,6 +1530,7 @@ def __init__(self, transform, subs=None):
"""
place ticks on the location= base**i*subs[j]
"""
+ super(SymmetricalLogLocator, self).__init__()
self._transform = transform
if subs is None:
self._subs = [1.0]
@@ -1840,6 +1693,7 @@ def __init__(self, minor=False):
"""
place ticks on the logit locations
"""
+ super(LogitLocator, self).__init__()
self.minor = minor
def set_params(self, minor=None):
@@ -1924,7 +1778,7 @@ def __init__(self):
nbins = 9
else:
nbins = 'auto'
- MaxNLocator.__init__(self, nbins=nbins, steps=[1, 2, 5, 10])
+ super(AutoLocator, self).__init__(nbins=nbins, steps=[1, 2, 5, 10])
class AutoMinorLocator(Locator):
@@ -1941,6 +1795,7 @@ def __init__(self, n=None):
If *n* is omitted or None, it will be set to 5 or 4.
"""
+ super(AutoMinorLocator, self).__init__()
self.ndivs = n
def __call__(self):
@@ -1998,6 +1853,7 @@ class OldAutoLocator(Locator):
"""
def __init__(self):
+ super(OldAutoLocator, self).__init__()
self._locator = LinearLocator()
def __call__(self):
@@ -2052,11 +1908,9 @@ def get_locator(self, d):
return locator
-__all__ = ('TickHelper', 'Formatter', 'FixedFormatter',
- 'NullFormatter', 'FuncFormatter', 'FormatStrFormatter',
- 'StrMethodFormatter', 'ScalarFormatter', 'LogFormatter',
- 'LogFormatterExponent', 'LogFormatterMathtext', 'Locator',
- 'IndexLocator', 'FixedLocator', 'NullLocator',
- 'LinearLocator', 'LogLocator', 'AutoLocator',
- 'MultipleLocator', 'MaxNLocator', 'AutoMinorLocator',
- 'SymmetricalLogLocator')
+__all__ = ['Formatter', 'FixedFormatter', 'NullFormatter', 'FuncFormatter',
+ 'FormatStrFormatter', 'StrMethodFormatter', 'ScalarFormatter',
+ 'LogFormatter', 'LogFormatterExponent', 'LogFormatterMathtext',
+ 'Locator', 'IndexLocator', 'FixedLocator', 'NullLocator',
+ 'LinearLocator', 'LogLocator', 'AutoLocator', 'MultipleLocator',
+ 'MaxNLocator', 'AutoMinorLocator', 'SymmetricalLogLocator']
diff --git a/lib/mpl_toolkits/axes_grid1/axes_grid.py b/lib/mpl_toolkits/axes_grid1/axes_grid.py
index 6f07a196ca7b..5903f7ad7d46 100644
--- a/lib/mpl_toolkits/axes_grid1/axes_grid.py
+++ b/lib/mpl_toolkits/axes_grid1/axes_grid.py
@@ -61,17 +61,17 @@ def _config_axes_deprecated(self, X, Y):
linewidth=0.01,
zorder=-1)
ax.add_artist(self.patch)
- ticks, ticklabels, offset_string = self._ticker()
+ ticks, ticklabels, offset_text = self._ticker()
if self.orientation == 'vertical':
ax.set_yticks(ticks)
ax.set_yticklabels(ticklabels)
- ax.yaxis.get_major_formatter().set_offset_string(offset_string)
+ ax.yaxis.get_major_formatter().offset_text = offset_text
else:
ax.set_xticks(ticks)
ax.set_xticklabels(ticklabels)
- ax.xaxis.get_major_formatter().set_offset_string(offset_string)
+ ax.xaxis.get_major_formatter().offset_text = offset_text
class CbarAxesBase(object):
diff --git a/lib/mpl_toolkits/axisartist/axis_artist.py b/lib/mpl_toolkits/axisartist/axis_artist.py
index 6b1904673f71..a78ccb0835c2 100644
--- a/lib/mpl_toolkits/axisartist/axis_artist.py
+++ b/lib/mpl_toolkits/axisartist/axis_artist.py
@@ -1376,7 +1376,7 @@ def _init_offsetText(self, direction):
def _update_offsetText(self):
- self.offsetText.set_text( self.axis.major.formatter.get_offset() )
+ self.offsetText.set_text(self.axis.major.formatter.offset_text)
self.offsetText.set_size(self.major_ticklabels.get_size())
offset = self.major_ticklabels.get_pad() + self.major_ticklabels.get_size() + 2.
self.offsetText.xyann= (0, offset)
diff --git a/lib/mpl_toolkits/axisartist/axislines.py b/lib/mpl_toolkits/axisartist/axislines.py
index 83d65db86055..80fb45a55b05 100644
--- a/lib/mpl_toolkits/axisartist/axislines.py
+++ b/lib/mpl_toolkits/axisartist/axislines.py
@@ -275,13 +275,13 @@ def get_tick_iterators(self, axes):
major = self.axis.major
majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
+ major.formatter.locs = majorLocs
+ majorLabels = [major.formatter.format_for_tick(val, i) for i, val in enumerate(majorLocs)]
minor = self.axis.minor
minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
+ minor.formatter.locs = minorLocs
+ minorLabels = [minor.formatter.format_for_tick(val, i) for i, val in enumerate(minorLocs)]
trans_tick = self.get_tick_transform(axes)
@@ -386,13 +386,13 @@ def get_tick_iterators(self, axes):
major = self.axis.major
majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
+ major.formatter.locs = majorLocs
+ majorLabels = [major.formatter.format_for_tick(val, i) for i, val in enumerate(majorLocs)]
minor = self.axis.minor
minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
+ minor.formatter.locs = minorLocs
+ minorLabels = [minor.formatter.format_for_tick(val, i) for i, val in enumerate(minorLocs)]
tr2ax = axes.transData + axes.transAxes.inverted()
diff --git a/lib/mpl_toolkits/axisartist/grid_finder.py b/lib/mpl_toolkits/axisartist/grid_finder.py
index 5f882d697ac2..6293de69ec47 100644
--- a/lib/mpl_toolkits/axisartist/grid_finder.py
+++ b/lib/mpl_toolkits/axisartist/grid_finder.py
@@ -264,16 +264,18 @@ def __init__(self, nbins = 10, steps = None,
mticker.MaxNLocator.__init__(self, nbins, steps=steps,
trim=trim, integer=integer,
symmetric=symmetric, prune=prune)
- self.create_dummy_axis()
+ self.set_axis({})
self._factor = None
def __call__(self, v1, v2):
if self._factor is not None:
- self.set_bounds(v1*self._factor, v2*self._factor)
+ self.axis.set_data_interval(v1*self._factor, v2*self._factor)
+ self.axis.set_view_interval(v1*self._factor, v2*self._factor)
locs = mticker.MaxNLocator.__call__(self)
return np.array(locs), len(locs), self._factor
else:
- self.set_bounds(v1, v2)
+ self.axis.set_data_interval(v1, v2)
+ self.axis.set_view_interval(v1, v2)
locs = mticker.MaxNLocator.__call__(self)
return np.array(locs), len(locs), None
@@ -304,8 +306,9 @@ def set_factor(self, f):
class FormatterPrettyPrint(object):
def __init__(self, useMathText=True):
- self._fmt = mticker.ScalarFormatter(useMathText=useMathText, useOffset=False)
- self._fmt.create_dummy_axis()
+ self._fmt = mticker.ScalarFormatter(
+ useMathText=useMathText, useOffset=False)
+ self._fmt.set_axis({})
self._ignore_factor = True
def __call__(self, direction, factor, values):
@@ -314,8 +317,8 @@ def __call__(self, direction, factor, values):
factor = 1.
values = [v/factor for v in values]
#values = [v for v in values]
- self._fmt.set_locs(values)
- return [self._fmt(v) for v in values]
+ self._fmt.locs = values
+ return [self._fmt.format_for_tick(v) for v in values]
class DictFormatter(object):
diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py
index 1e2fc5b19829..5b0f078f619f 100755
--- a/lib/mpl_toolkits/mplot3d/axes3d.py
+++ b/lib/mpl_toolkits/mplot3d/axes3d.py
@@ -1323,25 +1323,25 @@ def ticklabel_format(self, **kwargs) :
try:
if sb is not None:
if axis in ['both', 'z']:
- self.xaxis.major.formatter.set_scientific(sb)
+ self.xaxis.major.formatter.scientific = sb
if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_scientific(sb)
+ self.yaxis.major.formatter.scientific = sb
if axis in ['both', 'z'] :
- self.zaxis.major.formatter.set_scientific(sb)
+ self.zaxis.major.formatter.scientific = sb
if scilimits is not None:
if axis in ['both', 'x']:
- self.xaxis.major.formatter.set_powerlimits(scilimits)
+ self.xaxis.major.formatter.powerlimits = scilimits
if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_powerlimits(scilimits)
+ self.yaxis.major.formatter.powerlimits = scilimits
if axis in ['both', 'z']:
- self.zaxis.major.formatter.set_powerlimits(scilimits)
+ self.zaxis.major.formatter.powerlimits = scilimits
if useOffset is not None:
if axis in ['both', 'x']:
- self.xaxis.major.formatter.set_useOffset(useOffset)
+ self.xaxis.major.formatter.use_offset = useOffset
if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_useOffset(useOffset)
+ self.yaxis.major.formatter.use_offset = useOffset
if axis in ['both', 'z']:
- self.zaxis.major.formatter.set_useOffset(useOffset)
+ self.zaxis.major.formatter.use_offset = useOffset
except AttributeError:
raise AttributeError(
"This method only works with the ScalarFormatter.")
diff --git a/lib/mpl_toolkits/mplot3d/axis3d.py b/lib/mpl_toolkits/mplot3d/axis3d.py
index ad07fea32160..9d20e35a0588 100755
--- a/lib/mpl_toolkits/mplot3d/axis3d.py
+++ b/lib/mpl_toolkits/mplot3d/axis3d.py
@@ -123,8 +123,8 @@ def init3d(self):
def get_tick_positions(self):
majorLocs = self.major.locator()
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)]
+ self.major.formatter.locs = majorLocs
+ majorLabels = [self.major.formatter.format_for_tick(val, i) for i, val in enumerate(majorLocs)]
return majorLabels, majorLocs
def get_major_ticks(self, numticks=None):
@@ -224,8 +224,8 @@ def draw(self, renderer):
# Rudimentary clipping
majorLocs = [loc for loc in majorLocs if
locmin <= loc <= locmax]
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
+ self.major.formatter.locs = majorLocs
+ majorLabels = [self.major.formatter.format_for_tick(val, i)
for i, val in enumerate(majorLocs)]
mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
@@ -302,7 +302,7 @@ def draw(self, renderer):
pos = copy.copy(outeredgep)
pos = move_from_center(pos, centers, labeldeltas, axmask)
olx, oly, olz = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M)
- self.offsetText.set_text( self.major.formatter.get_offset() )
+ self.offsetText.set_text(self.major.formatter.offset_text)
self.offsetText.set_position( (olx, oly) )
angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx)))
self.offsetText.set_rotation(angle)