diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index b722e2602903..2911cab3c526 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1098,6 +1098,9 @@ def get_tick_padding(self): return max(values) return 0.0 + def _adjust_ticks(self, renderer, ticks_to_draw): + pass + @allow_rasterization def draw(self, renderer, *args, **kwargs): 'Draw the axis lines, grid lines, tick lines and labels' @@ -1110,6 +1113,8 @@ def draw(self, renderer, *args, **kwargs): ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + self._adjust_ticks(renderer, ticks_to_draw) + for tick in ticks_to_draw: tick.draw(renderer) @@ -1680,6 +1685,20 @@ class XAxis(Axis): __name__ = 'xaxis' axis_name = 'x' + def _adjust_ticks(self, renderer, ticks_to_draw): + heights = [] + for tick in ticks_to_draw: + label1 = tick.label1 + text = label1.get_text() + is_math = label1.is_math_text(text) + _, h, _ = renderer.get_text_width_height_descent( + text, label1.get_fontproperties(), is_math) + heights.append(h) + max_height = max(heights) + + for tick, h in zip(ticks_to_draw, heights): + tick.label1.set_offset((0, max_height - h)) + def contains(self, mouseevent): """Test whether the mouse event occured in the x axis. """ diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 1fc24148c0a4..64e39ab71670 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -1082,6 +1082,7 @@ def validate_animation_writer_path(p): 'axes.formatter.use_locale': [False, validate_bool], # Use the current locale to format ticks 'axes.formatter.use_mathtext': [False, validate_bool], + 'axes.formatter.min_exponent': [0, validate_int], # minimum exponent to format in scientific notation 'axes.formatter.useoffset': [True, validate_bool], 'axes.unicode_minus': [True, validate_bool], 'axes.color_cycle': [ diff --git a/lib/matplotlib/tests/test_ticker.py b/lib/matplotlib/tests/test_ticker.py index 59deeaef892a..8ce49525aff9 100644 --- a/lib/matplotlib/tests/test_ticker.py +++ b/lib/matplotlib/tests/test_ticker.py @@ -251,6 +251,20 @@ def get_view_interval(self): formatter.axis = FakeAxis(1, base**50) yield _logfe_helper, formatter, base, locs, i, expected_result +def test_LogFormatterMathtext_min_exponent(): + fmt = mticker.LogFormatterMathtext() + + with matplotlib.rc_context({'axes.formatter.min_exponent': 0}): + assert fmt(1) == '${10^{0}}$' + assert fmt(1e-2) == '${10^{-2}}$' + assert fmt(1e2) == '${10^{2}}$' + + with matplotlib.rc_context({'axes.formatter.min_exponent': 3}): + assert fmt(1) == '${1}$' + assert fmt(1e-2) == '${0.01}$' + assert fmt(1e2) == '${100}$' + assert fmt(1e-3) == '${10^{-3}}$' + assert fmt(1e3) == '${10^{3}}$' def _pprint_helper(value, domain, expected): fmt = mticker.LogFormatter() diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index 5cc75f719abd..f01bdc785564 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -233,6 +233,7 @@ def __init__(self, linespacing = 1.2 # Maybe use rcParam later. self._linespacing = linespacing self.set_rotation_mode(rotation_mode) + self._offset = (0, 0) self.update(kwargs) def update(self, kwargs): @@ -773,12 +774,13 @@ def draw(self, renderer): textobj._set_gc_clip(gc) angle = textobj.get_rotation() + ox, oy = self._offset for line, wh, x, y in info: mtext = textobj if len(info) == 1 else None - x = x + posx - y = y + posy + x = x + posx + ox + y = y + posy - oy if renderer.flipy(): y = canvash - y clean_line, ismath = textobj.is_math_text(line) @@ -803,6 +805,13 @@ def draw(self, renderer): renderer.close_group('text') self.stale = False + def set_offset(self, offset): + """ + Set extra offset (in pixel space) to be applied immediately + before drawing the text. + """ + self._offset = offset + def get_color(self): "Return the color of the text" return self._color diff --git a/lib/matplotlib/ticker.py b/lib/matplotlib/ticker.py index a2be7cbd805e..0a1ada102eae 100644 --- a/lib/matplotlib/ticker.py +++ b/lib/matplotlib/ticker.py @@ -959,6 +959,7 @@ def __call__(self, x, pos=None): """ b = self._base usetex = rcParams['text.usetex'] + min_exp = rcParams['axes.formatter.min_exponent'] # only label the decades if x == 0: @@ -969,6 +970,8 @@ def __call__(self, x, pos=None): fx = math.log(abs(x)) / math.log(b) is_decade = is_close_to_int(fx) + if is_decade: + fx = nearest_long(fx) sign_string = '-' if x < 0 else '' @@ -980,6 +983,12 @@ def __call__(self, x, pos=None): if not is_decade and self.labelOnlyBase: return '' + elif np.abs(fx) < min_exp: + if usetex: + return r'${0}{1:g}$'.format(sign_string, x) + else: + return '${0}$'.format(_mathdefault( + '{0}{1:g}'.format(sign_string, x))) elif not is_decade: if usetex: return (r'$%s%s^{%.2f}$') % \ diff --git a/matplotlibrc.template b/matplotlibrc.template index 9b96f90cbcee..6e565f3d94fa 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -315,6 +315,7 @@ backend : $TEMPLATE_BACKEND # separator in the fr_FR locale. #axes.formatter.use_mathtext : False # When True, use mathtext for scientific # notation. +#axes.formatter.min_exponent: 0 # minimum exponent to format in scientific notation #axes.formatter.useoffset : True # If True, the tick label formatter # will default to labeling ticks relative # to an offset when the data range is very pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy