From 46ae4d9794fef5437a66ad6fc21366201316ba0c Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 15 Dec 2015 11:29:37 -0500 Subject: [PATCH 1/5] Include outward ticks in bounding box --- lib/matplotlib/axes/_base.py | 6 +++++- lib/matplotlib/axis.py | 28 +++++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index fa0a42f17c99..4c563e19d905 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -567,7 +567,11 @@ def get_window_extent(self, *args, **kwargs): get the axes bounding box in display space; *args* and *kwargs* are empty """ - return self.bbox + bbox = self.bbox + x_pad = self.xaxis.get_tick_padding() + y_pad = self.yaxis.get_tick_padding() + return mtransforms.Bbox([[bbox.x0 - x_pad, bbox.y0 - y_pad], + [bbox.x1 + x_pad, bbox.y1 + y_pad]]) def _init_axis(self): "move this out of __init__ because non-separable axes don't use it" diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 6597d70f8ac7..407ae40bb714 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -169,6 +169,21 @@ def apply_tickdir(self, tickdir): """ pass + def get_tickdir(self): + return self._tickdir + + def get_tick_padding(self): + """ + Get the length of the tick outside of the axes. + """ + tickdir = self._tickdir + if tickdir == 'in': + return 0.0 + elif tickdir == 'inout': + return self._size / 2 + elif tickdir == 'out': + return self._size + def get_children(self): children = [self.tick1line, self.tick2line, self.gridline, self.label1, self.label2] @@ -349,13 +364,11 @@ def apply_tickdir(self, tickdir): if self._tickdir == 'in': self._tickmarkers = (mlines.TICKUP, mlines.TICKDOWN) - self._pad = self._base_pad elif self._tickdir == 'inout': self._tickmarkers = ('|', '|') - self._pad = self._base_pad + self._size / 2. else: self._tickmarkers = (mlines.TICKDOWN, mlines.TICKUP) - self._pad = self._base_pad + self._size + self._pad = self._base_pad + self.get_tick_padding() self.stale = True def _get_text1(self): @@ -485,13 +498,11 @@ def apply_tickdir(self, tickdir): if self._tickdir == 'in': self._tickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT) - self._pad = self._base_pad elif self._tickdir == 'inout': self._tickmarkers = ('_', '_') - self._pad = self._base_pad + self._size / 2. else: self._tickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT) - self._pad = self._base_pad + self._size + self._pad = self._base_pad + self.get_tick_padding() self.stale = True # how far from the y axis line the right of the ticklabel are @@ -1067,7 +1078,7 @@ def _get_tick_bboxes(self, ticks, renderer): def get_tightbbox(self, renderer): """ Return a bounding box that encloses the axis. It only accounts - tick labels, axis label, and offsetText. + tick labels, axis label, offsetText and ticks themselves. """ if not self.get_visible(): return @@ -1097,6 +1108,9 @@ def get_tightbbox(self, renderer): else: return None + def get_tick_padding(self): + return self.majorTicks[0].get_tick_padding() + @allow_rasterization def draw(self, renderer, *args, **kwargs): 'Draw the axis lines, grid lines, tick lines and labels' From 62804e8531593c4cfcebd9139bda7b2f196df1b8 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 15 Dec 2015 11:37:26 -0500 Subject: [PATCH 2/5] Correct comment --- lib/matplotlib/axis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 407ae40bb714..8570fd0fe47d 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1078,7 +1078,7 @@ def _get_tick_bboxes(self, ticks, renderer): def get_tightbbox(self, renderer): """ Return a bounding box that encloses the axis. It only accounts - tick labels, axis label, offsetText and ticks themselves. + tick labels, axis label, and offsetText. """ if not self.get_visible(): return From 97b398507c9bbe6981999a6f5c58adebd5943348 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 17 Dec 2015 12:08:41 -0500 Subject: [PATCH 3/5] Address comments in PR --- lib/matplotlib/axis.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 8570fd0fe47d..6bc475a0025e 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -176,13 +176,12 @@ def get_tick_padding(self): """ Get the length of the tick outside of the axes. """ - tickdir = self._tickdir - if tickdir == 'in': - return 0.0 - elif tickdir == 'inout': - return self._size / 2 - elif tickdir == 'out': - return self._size + padding = { + 'in': 0.0, + 'inout': 0.5, + 'out': 1.0 + } + return self._size * padding[self._tickdir] def get_children(self): children = [self.tick1line, self.tick2line, @@ -1109,7 +1108,8 @@ def get_tightbbox(self, renderer): return None def get_tick_padding(self): - return self.majorTicks[0].get_tick_padding() + return max(self.majorTicks[0].get_tick_padding(), + self.minorTicks[0].get_tick_padding()) @allow_rasterization def draw(self, renderer, *args, **kwargs): From 0bf73c17593bf4fd95f344f0108a3438140ca478 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 16 Dec 2015 08:36:54 -0500 Subject: [PATCH 4/5] Add test --- .../test_tightlayout/outward_ticks.pdf | Bin 0 -> 2242 bytes .../test_tightlayout/outward_ticks.png | Bin 0 -> 6177 bytes .../test_tightlayout/outward_ticks.svg | 807 ++++++++++++++++++ lib/matplotlib/tests/test_tightlayout.py | 25 + 4 files changed, 832 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.png create mode 100644 lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.svg diff --git a/lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.pdf b/lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7e0dd1ebcb58a4624e8a54bbc2e6cbdcf77b680c GIT binary patch literal 2242 zcmZ{m4OA0X7RTvYP-g8)-Qso?+gAk%3YnRFLeLgSAbcn&XpvxQC&?s)giJ^#X^f)P zs>sKxTS274%39RAQL11?EsFIhLeU~c5mD5xXDz7+N);DbcJ~dCg2m1`IWOtNS;&jZkR~8Xy?SOwcrGG64S2bhI2Cg9g_D!VLzBHpAWJ0F|03 zixDu#5+?yvLRz&-GEoYvfU~70!eBNMCeol>Lc0`7B+Zn?q=b?&nn20Kuza{~1|iHG8Ih1tb&P(@nycQ0q(MWc0i3x67$2q8 z!!yEB4<(h5N=h{pXr@ghk%8DsN{bo|H^U}JK6{R2t>^SytPEf8CO^K%t6ckuYFSzT zV7xxv*6`;WnSa`P*wM(Hvc#vZ0?m`}Nv=9`tZ5+qdUoHc4;FrHPgTS}9C-R#RR~()2~`-fqW@6>04uH7lpy&br(2 z{O}^@pmNvK?guS*?rclA^LF?3i|6P9M+s za!?!IbTQ6YaW?vyz5Hhq%ken5GFIGHkSm*0pIiTtsL;AS$P-FtV>qojwQf|X5<^$W_gkIWtnM%z^tKW;J? zMYHERdpA^;9$2T*)b3Lp%Dbf2e)xOgk!6#DE}b|WtW59JZ{IBUHmDzXDOP`djgBq; z&gF1)N5>(&E>&H{JF;m;+gue(SlKpH_2#3qqJ}(slB{4&!8DqE_oSk8MM@1fbxXh; z|IFs>Z3jKy&}OxIt-cqN$@?k44e1Lmt|mB_t&Ots)9;mdK0T*>oI{={IbXHwwOm=? zg4t_&cURp$DD$jTKMT!Qd)9w*zHjT*f0!p(E^JO+aVt!0XQf&LoH?IYIM?Jk%icNN z9#qh`)3HD*Z|R@b5A-(RCr8$x?p>ks z6g=Q){sei^X0N6C@PD(H$KCCdM^_(vG_d85`CWJYlUlkRy3V(@)I`_ZJ|itz zdx`hm+PZeD+p|p8Ioq2Nyq@z4cUvGbM>3Cnyz^BL&-yZi_dDK<=}$^8PpwQT)Vr|+ zPk!8}cCQaaFo}-M<7U=-`HDr8cy4bD_*~Apn5>yqO?2FQu)QSoz{5oczbdtsUdX-g ziE@{nExw7w-F#x*yz>tpF+29{ZWe89t1t+zr`slkO>aB*n%+C2%X(>5YTW&G9G5|# zGO2F5?+s?Lw}EX-@R-}Nde)VFA4gnWSJ2+DOB!Zaf354-gXg01n68djel`#Gs64-_ zjgZb(OjJ5-vRfytrewEU{Dyx`OCkPFKFs!so9wY<`%!UgT6c2jXMSN-tmZ3k>3BlN z%*#{DQVP;K|Ke@`TXMe7jtw&ugY|WK>hJ9alcb$pR>34i*L6Sv(f`T z&z8l8er(;KoA-Sr-~Cj@ehG6I@0aJ<5n7&*v$e0Z;*hk5_5HHQ()%9Gg_iz_z5coj z40cBVFaqEqS}+8`F`Vb3G6T&Ks*JLcfwBuV;rK8M!=VjT5&(B`ZGQGxCp_sBjw!&@Wv?_+-Lu5~6ushs}hP%_~>F^hVAtGtY z1XvjaZPZh=UaJ5&o6pABM#@YJ1;Tk60ZDRsYEB?XqiLfEMMpi^lt~kSps;zVEJ_IA zu}O?7HBb;r9TYzR5}w&cOBp0g&tpkM91Q2<99#&0Tucyz@%%B&KL8mm(qA`6!L#Xv^w?x literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.png b/lib/matplotlib/tests/baseline_images/test_tightlayout/outward_ticks.png new file mode 100644 index 0000000000000000000000000000000000000000..cc73be432858983bb2c64844fd6d796776b027f5 GIT binary patch literal 6177 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 x_hq+V;j>@db;U@Tv=R + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_tightlayout.py b/lib/matplotlib/tests/test_tightlayout.py index 9d43242ed9f5..588f66dbae65 100644 --- a/lib/matplotlib/tests/test_tightlayout.py +++ b/lib/matplotlib/tests/test_tightlayout.py @@ -159,6 +159,31 @@ def test_tight_layout8(): example_plot(ax, fontsize=24) +@image_comparison(baseline_images=['outward_ticks'], remove_text=True) +def test_outward_ticks(): + 'Test automatic use of tight_layout' + fig = plt.figure() + ax = fig.add_subplot(221) + ax.xaxis.set_tick_params(tickdir='out', length=16, width=3) + ax.yaxis.set_tick_params(tickdir='out', length=16, width=3) + ax.xaxis.set_tick_params( + tickdir='out', length=32, width=3, tick1On=True, which='minor') + ax.yaxis.set_tick_params( + tickdir='out', length=32, width=3, tick1On=True, which='minor') + ax.xaxis.set_ticks([0], minor=True) + ax.yaxis.set_ticks([0], minor=True) + ax = fig.add_subplot(222) + ax.xaxis.set_tick_params(tickdir='in', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='in', length=32, width=3) + ax = fig.add_subplot(223) + ax.xaxis.set_tick_params(tickdir='inout', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='inout', length=32, width=3) + ax = fig.add_subplot(224) + ax.xaxis.set_tick_params(tickdir='out', length=32, width=3) + ax.yaxis.set_tick_params(tickdir='out', length=32, width=3) + plt.tight_layout() + + def add_offsetboxes(ax, size=10, margin=.1, color='black'): """ Surround ax with OffsetBoxes From 0a4b52e90dae60517c34ba3af09c8b43f002d950 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 17 Dec 2015 12:12:02 -0500 Subject: [PATCH 5/5] Handle case where there are no ticks --- lib/matplotlib/axis.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 6bc475a0025e..d5cca9d6ea63 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1108,8 +1108,14 @@ def get_tightbbox(self, renderer): return None def get_tick_padding(self): - return max(self.majorTicks[0].get_tick_padding(), - self.minorTicks[0].get_tick_padding()) + values = [] + if len(self.majorTicks): + values.append(self.majorTicks[0].get_tick_padding()) + if len(self.minorTicks): + values.append(self.minorTicks[0].get_tick_padding()) + if len(values): + return max(values) + return 0.0 @allow_rasterization def draw(self, renderer, *args, **kwargs): 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