Skip to content

Commit 2ac0bff

Browse files
Implement simplified padding rules
1 parent 98d4bc4 commit 2ac0bff

File tree

4 files changed

+21
-58
lines changed

4 files changed

+21
-58
lines changed

lib/matplotlib/patches.py

Lines changed: 20 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,7 +2543,9 @@ def __call__(self, x0, y0, width, height, mutation_size):
25432543
dx = (y1 - y0) / 2
25442544
dxx = dx / 2
25452545

2546-
x0 += pad / 1.4 # adjust by ~sqrt(2)
2546+
# Pad text to position text and its padding margin exactly inside arrow tail
2547+
padding_offset = (0.5 * pad) + (0.25 * mutation_size)
2548+
x0 -= padding_offset
25472549

25482550
# The width adjustment is the distance that must be subtracted from
25492551
# y0 and added to y1 to reach the non-tip vertices of the head.
@@ -2567,26 +2569,14 @@ def __call__(self, x0, y0, width, height, mutation_size):
25672569
# (dx+width_adjustment)/(dxx+angle_adjustment).
25682570
angle_adjustment = ((dx + width_adjustment) / tan_half_angle) - dxx
25692571

2570-
# Check padding; the left end of the text should have a minimum
2571-
# clearance of pad from the head
2572-
if -width_adjustment < pad:
2573-
# Only do this if the text fits into the head
2574-
text_clearance = (width_adjustment / tan_half_angle) + \
2575-
pad * ((1 / tan_half_angle) - 1)
2572+
# If there is sufficient space available, shorten the arrow tail to push
2573+
# some of the text padding margin into the head
2574+
if self.head_width > 1 and pad * tan_half_angle < width_adjustment:
2575+
# Pad text into head
2576+
x0 += pad
25762577

2577-
if text_clearance < pad:
2578-
# Lengthen arrow body to accommodate text
2579-
x0 += text_clearance - pad
2580-
else:
2581-
# Pad away from head straight-edge
2582-
2583-
a, b = 1.214, 0.250 # Empirical factors
2584-
padding_offset = (a * pad) + (b * mutation_size)
2585-
2586-
x0 -= padding_offset
2587-
2588-
return Path._create_closed(
2589-
[(x0 + dxx, y0),
2578+
return Path._create_closed([
2579+
(x0 + dxx, y0),
25902580
(x1, y0),
25912581
(x1, y1),
25922582
(x0 + dxx, y1),
@@ -2598,14 +2588,6 @@ def __call__(self, x0, y0, width, height, mutation_size):
25982588
else:
25992589
# Reversed arrow head (>---)
26002590

2601-
# Distance to pad x0 by, in order to ensure consistent spacing
2602-
a, b = 1.214, 0.250 # Empirical factors
2603-
padding_offset = (a * pad) + (b * mutation_size)
2604-
2605-
# No arrow head available for enclosed text to spill over into; add
2606-
# padding to left of text
2607-
x0 -= padding_offset
2608-
26092591
# tan(1/2 * angle subtended by arrow tip)
26102592
tan_half_angle = -np.tan(self.head_angle * (math.pi / 360))
26112593

@@ -2704,7 +2686,10 @@ def __call__(self, x0, y0, width, height, mutation_size):
27042686
dx = (y1 - y0) / 2
27052687
dxx = dx / 2
27062688

2707-
x0 += pad / 1.4 # adjust by ~sqrt(2)
2689+
# Pad text
2690+
padding_offset = (0.5 * pad) + (0.25 * mutation_size)
2691+
x0 -= padding_offset
2692+
x1 += padding_offset
27082693

27092694
# The width adjustment is the distance that must be subtracted from
27102695
# y0 and added to y1 to reach the non-tip vertices of the head.
@@ -2728,25 +2713,12 @@ def __call__(self, x0, y0, width, height, mutation_size):
27282713
# (dx+width_adjustment)/(dxx+angle_adjustment).
27292714
angle_adjustment = ((dx + width_adjustment) / tan_half_angle) - dxx
27302715

2731-
# Check padding; the ends of the text should have a minimum
2732-
# clearance of pad from the heads
2733-
if -width_adjustment < pad:
2734-
# Only do this if the text fits into the head
2735-
text_clearance = (width_adjustment / tan_half_angle) + \
2736-
pad * ((1 / tan_half_angle) - 1)
2737-
2738-
if text_clearance < pad:
2739-
# Lengthen arrow body to accommodate text
2740-
x0 -= pad - text_clearance
2741-
x1 += pad - text_clearance
2742-
else:
2743-
# Pad away from head straight-edges
2744-
2745-
a, b = 1.214, 0.250 # Empirical factors
2746-
padding_offset = (a * pad) + (b * mutation_size)
2747-
2748-
x0 -= padding_offset
2749-
x1 += padding_offset
2716+
# If there is sufficient space available, shorten the arrow tail to push
2717+
# some of the text padding margin into the heads
2718+
if self.head_width > 1 and pad * tan_half_angle < width_adjustment:
2719+
# Pad text into heads
2720+
x0 += pad
2721+
x1 -= pad
27502722

27512723
return Path._create_closed([
27522724
(x0 + dxx, y0),
@@ -2764,15 +2736,6 @@ def __call__(self, x0, y0, width, height, mutation_size):
27642736
else:
27652737
# Reversed arrow heads (>---<)
27662738

2767-
# Distance to pad x0 and x1 by, in order to ensure consistent spacing
2768-
a, b = 1.214, 0.250 # Empirical factors
2769-
padding_offset = (a * pad) + (b * mutation_size)
2770-
2771-
# No arrow head available for enclosed text to spill over into; add
2772-
# padding to both sides of text
2773-
x0 -= padding_offset
2774-
x1 += padding_offset
2775-
27762739
# tan(1/2 * angle subtended by arrow tip)
27772740
tan_half_angle = -np.tan(self.head_angle * (math.pi / 360))
27782741

665 Bytes
Loading
34 Bytes
Loading

lib/matplotlib/tests/test_arrow_patches.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def test_boxarrow_adjustment():
6565
]
6666

6767
# Horizontal and vertical spacings of arrow centres
68-
spacing_horizontal = 3.5
68+
spacing_horizontal = 3.75
6969
spacing_vertical = 1.6
7070

7171
# Numbers of styles and cases

0 commit comments

Comments
 (0)