Skip to content

Follow-on to #6834 #6880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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)

Expand Down Expand Up @@ -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.
"""
Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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': [
Expand Down
14 changes: 14 additions & 0 deletions lib/matplotlib/tests/test_ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 11 additions & 2 deletions lib/matplotlib/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
9 changes: 9 additions & 0 deletions lib/matplotlib/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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 ''

Expand All @@ -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}$') % \
Expand Down
1 change: 1 addition & 0 deletions matplotlibrc.template
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down