Skip to content

Commit 6777e33

Browse files
committed
BUG: Fix handling of ticks in Skew example.
Refactor so that ticks, labels, and gridlines are controlled using their flags, compensating for data ranges, rather than a hard-coded check in the draw method. This fixes figures with a bunch of whitespace when using bbox_inches='tight'. Also add this refactor to the test.
1 parent 42d5097 commit 6777e33

File tree

2 files changed

+108
-62
lines changed

2 files changed

+108
-62
lines changed

examples/api/skewt.py

+54-31
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,58 @@
2424
# The sole purpose of this class is to look at the upper, lower, or total
2525
# interval as appropriate and see what parts of the tick to draw, if any.
2626
class SkewXTick(maxis.XTick):
27-
def draw(self, renderer):
28-
if not self.get_visible():
29-
return
30-
renderer.open_group(self.__name__)
27+
def _need_lower(self):
28+
return transforms.interval_contains(self.axes.lower_xlim,
29+
self.get_loc())
3130

32-
lower_interval = self.axes.xaxis.lower_interval
33-
upper_interval = self.axes.xaxis.upper_interval
31+
def _need_upper(self):
32+
return transforms.interval_contains(self.axes.upper_xlim,
33+
self.get_loc())
3434

35-
if self.gridOn and transforms.interval_contains(
36-
self.axes.xaxis.get_view_interval(), self.get_loc()):
37-
self.gridline.draw(renderer)
35+
@property
36+
def gridOn(self):
37+
return (self._gridOn and
38+
transforms.interval_contains(self.get_view_interval(),
39+
self.get_loc()))
40+
41+
@gridOn.setter
42+
def gridOn(self, value):
43+
self._gridOn = value
44+
45+
@property
46+
def tick1On(self):
47+
return self._tick1On and self._need_lower()
3848

39-
if transforms.interval_contains(lower_interval, self.get_loc()):
40-
if self.tick1On:
41-
self.tick1line.draw(renderer)
42-
if self.label1On:
43-
self.label1.draw(renderer)
49+
@tick1On.setter
50+
def tick1On(self, value):
51+
self._tick1On = value
4452

45-
if transforms.interval_contains(upper_interval, self.get_loc()):
46-
if self.tick2On:
47-
self.tick2line.draw(renderer)
48-
if self.label2On:
49-
self.label2.draw(renderer)
53+
@property
54+
def label1On(self):
55+
return self._label1On and self._need_lower()
5056

51-
renderer.close_group(self.__name__)
57+
@label1On.setter
58+
def label1On(self, value):
59+
self._label1On = value
60+
61+
@property
62+
def tick2On(self):
63+
return self._tick2On and self._need_upper()
64+
65+
@tick2On.setter
66+
def tick2On(self, value):
67+
self._tick2On = value
68+
69+
@property
70+
def label2On(self):
71+
return self._label2On and self._need_upper()
72+
73+
@label2On.setter
74+
def label2On(self, value):
75+
self._label2On = value
76+
77+
def get_view_interval(self):
78+
return self.axes.xaxis.get_view_interval()
5279

5380

5481
# This class exists to provide two separate sets of intervals to the tick,
@@ -57,16 +84,8 @@ class SkewXAxis(maxis.XAxis):
5784
def _get_tick(self, major):
5885
return SkewXTick(self.axes, 0, '', major=major)
5986

60-
@property
61-
def lower_interval(self):
62-
return self.axes.viewLim.intervalx
63-
64-
@property
65-
def upper_interval(self):
66-
return self.axes.upper_xlim
67-
6887
def get_view_interval(self):
69-
return self.upper_interval[0], self.lower_interval[1]
88+
return self.axes.upper_xlim[0], self.axes.lower_xlim[1]
7089

7190

7291
# This class exists to calculate the separate data range of the
@@ -76,9 +95,9 @@ class SkewSpine(mspines.Spine):
7695
def _adjust_location(self):
7796
pts = self._path.vertices
7897
if self.spine_type == 'top':
79-
pts[:, 0] = self.axis.upper_interval
98+
pts[:, 0] = self.axes.upper_xlim
8099
else:
81-
pts[:, 0] = self.axis.lower_interval
100+
pts[:, 0] = self.axes.lower_xlim
82101

83102

84103
# This class handles registration of the skew-xaxes as a projection as well
@@ -134,6 +153,10 @@ def _set_lim_and_transforms(self):
134153
transforms.IdentityTransform()) +
135154
transforms.Affine2D().skew_deg(rot, 0)) + self.transAxes
136155

156+
@property
157+
def lower_xlim(self):
158+
return self.axes.viewLim.intervalx
159+
137160
@property
138161
def upper_xlim(self):
139162
pts = [[0., 1.], [1., 1.]]

lib/matplotlib/tests/test_skew.py

+54-31
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,58 @@
2020
# The sole purpose of this class is to look at the upper, lower, or total
2121
# interval as appropriate and see what parts of the tick to draw, if any.
2222
class SkewXTick(maxis.XTick):
23-
def draw(self, renderer):
24-
if not self.get_visible():
25-
return
26-
renderer.open_group(self.__name__)
23+
def _need_lower(self):
24+
return transforms.interval_contains(self.axes.lower_xlim,
25+
self.get_loc())
2726

28-
lower_interval = self.axes.xaxis.lower_interval
29-
upper_interval = self.axes.xaxis.upper_interval
27+
def _need_upper(self):
28+
return transforms.interval_contains(self.axes.upper_xlim,
29+
self.get_loc())
3030

31-
if self.gridOn and transforms.interval_contains(
32-
self.axes.xaxis.get_view_interval(), self.get_loc()):
33-
self.gridline.draw(renderer)
31+
@property
32+
def gridOn(self):
33+
return (self._gridOn and
34+
transforms.interval_contains(self.get_view_interval(),
35+
self.get_loc()))
36+
37+
@gridOn.setter
38+
def gridOn(self, value):
39+
self._gridOn = value
40+
41+
@property
42+
def tick1On(self):
43+
return self._tick1On and self._need_lower()
3444

35-
if transforms.interval_contains(lower_interval, self.get_loc()):
36-
if self.tick1On:
37-
self.tick1line.draw(renderer)
38-
if self.label1On:
39-
self.label1.draw(renderer)
45+
@tick1On.setter
46+
def tick1On(self, value):
47+
self._tick1On = value
4048

41-
if transforms.interval_contains(upper_interval, self.get_loc()):
42-
if self.tick2On:
43-
self.tick2line.draw(renderer)
44-
if self.label2On:
45-
self.label2.draw(renderer)
49+
@property
50+
def label1On(self):
51+
return self._label1On and self._need_lower()
4652

47-
renderer.close_group(self.__name__)
53+
@label1On.setter
54+
def label1On(self, value):
55+
self._label1On = value
56+
57+
@property
58+
def tick2On(self):
59+
return self._tick2On and self._need_upper()
60+
61+
@tick2On.setter
62+
def tick2On(self, value):
63+
self._tick2On = value
64+
65+
@property
66+
def label2On(self):
67+
return self._label2On and self._need_upper()
68+
69+
@label2On.setter
70+
def label2On(self, value):
71+
self._label2On = value
72+
73+
def get_view_interval(self):
74+
return self.axes.xaxis.get_view_interval()
4875

4976

5077
# This class exists to provide two separate sets of intervals to the tick,
@@ -53,16 +80,8 @@ class SkewXAxis(maxis.XAxis):
5380
def _get_tick(self, major):
5481
return SkewXTick(self.axes, 0, '', major=major)
5582

56-
@property
57-
def lower_interval(self):
58-
return self.axes.viewLim.intervalx
59-
60-
@property
61-
def upper_interval(self):
62-
return self.axes.upper_xlim
63-
6483
def get_view_interval(self):
65-
return self.upper_interval[0], self.lower_interval[1]
84+
return self.axes.upper_xlim[0], self.axes.lower_xlim[1]
6685

6786

6887
# This class exists to calculate the separate data range of the
@@ -72,9 +91,9 @@ class SkewSpine(mspines.Spine):
7291
def _adjust_location(self):
7392
pts = self._path.vertices
7493
if self.spine_type == 'top':
75-
pts[:, 0] = self.axis.upper_interval
94+
pts[:, 0] = self.axes.upper_xlim
7695
else:
77-
pts[:, 0] = self.axis.lower_interval
96+
pts[:, 0] = self.axes.lower_xlim
7897

7998

8099
# This class handles registration of the skew-xaxes as a projection as well
@@ -131,6 +150,10 @@ def _set_lim_and_transforms(self):
131150
transforms.IdentityTransform()) +
132151
transforms.Affine2D().skew_deg(rot, 0)) + self.transAxes
133152

153+
@property
154+
def lower_xlim(self):
155+
return self.axes.viewLim.intervalx
156+
134157
@property
135158
def upper_xlim(self):
136159
pts = [[0., 1.], [1., 1.]]

0 commit comments

Comments
 (0)