Skip to content

Commit ba242b1

Browse files
committed
Apply padding to theta ticks in polar plots.
1 parent 386bb30 commit ba242b1

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

lib/matplotlib/projections/polar.py

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import numpy as np
77

8+
import matplotlib.artist as martist
89
from matplotlib.axes import Axes
910
import matplotlib.axis as maxis
1011
from matplotlib import cbook
@@ -248,18 +249,52 @@ class ThetaTick(maxis.XTick):
248249
This subclass of `XTick` provides angular ticks with some small
249250
modification to their re-positioning such that ticks are rotated based on
250251
tick location. This results in ticks that are correctly perpendicular to
251-
the arc spine. Labels are also rotated to be parallel to the spine.
252+
the arc spine.
253+
254+
Labels are also rotated to be parallel to the spine. The label padding is
255+
also applied here since it's not possible to use a generic axes transform
256+
to produce tick-specific padding.
252257
"""
258+
def __init__(self, axes, *args, **kwargs):
259+
self._text1_translate = mtransforms.ScaledTranslation(
260+
0, 0,
261+
axes.figure.dpi_scale_trans)
262+
self._text2_translate = mtransforms.ScaledTranslation(
263+
0, 0,
264+
axes.figure.dpi_scale_trans)
265+
maxis.XTick.__init__(self, axes, *args, **kwargs)
266+
253267
def _get_text1(self):
254268
t = maxis.XTick._get_text1(self)
255269
t.set_rotation_mode('anchor')
270+
t.set_transform(t.get_transform() + self._text1_translate)
256271
return t
257272

258273
def _get_text2(self):
259274
t = maxis.XTick._get_text2(self)
260275
t.set_rotation_mode('anchor')
276+
t.set_transform(t.get_transform() + self._text2_translate)
261277
return t
262278

279+
def _apply_params(self, **kw):
280+
maxis.XTick._apply_params(self, **kw)
281+
282+
# Ensure transform is correct; sometimes this gets reset.
283+
trans = self.label1.get_transform()
284+
if not trans.contains_branch(self._text1_translate):
285+
self.label1.set_transform(trans + self._text1_translate)
286+
trans = self.label2.get_transform()
287+
if not trans.contains_branch(self._text2_translate):
288+
self.label2.set_transform(trans + self._text2_translate)
289+
290+
def _update_padding(self, angle):
291+
padx = self._pad * np.cos(angle) / 72
292+
pady = self._pad * np.sin(angle) / 72
293+
self._text1_translate._t = (padx, pady)
294+
self._text1_translate.invalidate()
295+
self._text2_translate._t = (-padx, -pady)
296+
self._text2_translate.invalidate()
297+
263298
def update_position(self, loc):
264299
maxis.XTick.update_position(self, loc)
265300
axes = self.axes
@@ -292,6 +327,9 @@ def update_position(self, loc):
292327
if self.label2On:
293328
self.label2.set_rotation(np.rad2deg(angle) + self._labelrotation)
294329

330+
self._update_padding(self._loc * axes.get_theta_direction() +
331+
axes.get_theta_offset())
332+
295333

296334
class ThetaAxis(maxis.XAxis):
297335
"""
@@ -325,6 +363,18 @@ def _set_scale(self, value, **kwargs):
325363
maxis.XAxis._set_scale(self, value, **kwargs)
326364
self._wrap_locator_formatter()
327365

366+
def _copy_tick_props(self, src, dest):
367+
'Copy the props from src tick to dest tick'
368+
if src is None or dest is None:
369+
return
370+
maxis.XAxis._copy_tick_props(self, src, dest)
371+
372+
# Ensure that tick transforms are independent so that padding works.
373+
trans = dest._get_text1_transform()[0]
374+
dest.label1.set_transform(trans + dest._text1_translate)
375+
trans = dest._get_text2_transform()[0]
376+
dest.label2.set_transform(trans + dest._text2_translate)
377+
328378

329379
class RadialLocator(mticker.Locator):
330380
"""
@@ -752,14 +802,7 @@ def _set_lim_and_transforms(self):
752802
.translate(0.0, -0.5) \
753803
.scale(1.0, -1.0) \
754804
.translate(0.0, 0.5)
755-
self._xaxis_text1_transform = (
756-
flipr_transform +
757-
mtransforms.Affine2D().translate(0.0, 0.1) +
758-
self._xaxis_transform)
759-
self._xaxis_text2_transform = (
760-
flipr_transform +
761-
mtransforms.Affine2D().translate(0.0, -0.1) +
762-
self._xaxis_transform)
805+
self._xaxis_text_transform = flipr_transform + self._xaxis_transform
763806

764807
# This is the transform for r-axis ticks. It scales the theta
765808
# axis so the gridlines from 0.0 to 1.0, now go from thetamin to
@@ -782,10 +825,10 @@ def get_xaxis_transform(self, which='grid'):
782825
return self._xaxis_transform
783826

784827
def get_xaxis_text1_transform(self, pad):
785-
return self._xaxis_text1_transform, 'bottom', 'center'
828+
return self._xaxis_text_transform, 'bottom', 'center'
786829

787830
def get_xaxis_text2_transform(self, pad):
788-
return self._xaxis_text2_transform, 'top', 'center'
831+
return self._xaxis_text_transform, 'top', 'center'
789832

790833
def get_yaxis_transform(self, which='grid'):
791834
if which in ('tick1', 'tick2'):

0 commit comments

Comments
 (0)