8000 Update custom boxstyles example. · matplotlib/matplotlib@d6aedda · GitHub
[go: up one dir, main page]

Skip to content

Commit d6aedda

Browse files
committed
Update custom boxstyles example.
- Merge the two examples together (especially given that one of them demonstrates private API anyways...). - General modernization/simplification/s-g-ification.
1 parent 70d59ae commit d6aedda

File tree

3 files changed

+111
-117
lines changed

3 files changed

+111
-117
lines changed
Lines changed: 111 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,139 @@
1-
"""
1+
r"""
22
=================
3-
Custom Boxstyle01
3+
Custom box styles
44
=================
55
6+
This example demonstrates the implementation of a custom `.BoxStyle`.
7+
Custom `.ConnectionStyle`\s and `.ArrowStyle`\s can be similarly defined.
68
"""
9+
10+
from matplotlib.patches import BoxStyle
711
from matplotlib.path import Path
12+
import matplotlib.pyplot as plt
13+
14+
15+
###############################################################################
16+
# Custom box styles can be implemented as a function that takes arguments
17+
# specifying both a rectangular box and the amount of "mutation", and
18+
# returns the "mutated" path. The specific signature is the one of
19+
# ``custom_box_style`` below.
20+
#
21+
# The custom box style can then be used by passing
22+
# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`.
823

924

1025
def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
1126
"""
12-
Given the location and size of the box, return the path of
13-
the box around it.
14-
15-
- *x0*, *y0*, *width*, *height* : location and size of the box
16-
- *mutation_size* : a reference scale for the mutation.
17-
- *aspect_ratio* : aspect-ration for the mutation.
27+
Given the location and size of the box, return the path of the box around
28+
it.
29+
30+
Rotation is automatically taken care of.
31+
32+
Parameters
33+
----------
34+
x0, y0, width, height : float
35+
Box location and size.
36+
mutation_size : float
37+
Mutation reference scale, typically the text font size.
38+
mutation_aspect
39+
Mutation aspect ratio.
1840
"""
19-
20-
# note that we are ignoring mutation_aspect. This is okay in general.
41+
10000 # We ignore mutation_aspect. This is okay in general.
2142

2243
# padding
2344
mypad = 0.3
2445
pad = mutation_size * mypad
25-
2646
# width and height with padding added.
2747
width = width + 2 * pad
2848
height = height + 2 * pad
29-
3049
# boundary of the padded box
3150
x0, y0 = x0 - pad, y0 - pad
3251
x1, y1 = x0 + width, y0 + height
52+
# return the new path
53+
return Path([(x0, y0),
54+
(x1, y0), (x1, y1), (x0, y1),
55+
(x0-pad, (y0+y1)/2.), (x0, y0),
56+
(x0, y0)],
57+
closed=True)
3358

34-
cp = [(x0, y0),
35-
(x1, y0), (x1, y1), (x0, y1),
36-
(x0-pad, (y0+y1)/2.), (x0, y0),
37-
(x0, y0)]
38-
39-
com = [Path.MOVETO,
40-
Path.LINETO, Path.LINETO, Path.LINETO,
41-
Path.LINETO, Path.LINETO,
42-
Path.CLOSEPOLY]
4359

44-
path = Path(cp, com)
45-
46-
return path
60+
fig, ax = plt.subplots(figsize=(3, 3))
61+
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
62+
bbox=dict(boxstyle=custom_box_style, alpha=0.2))
4763

4864

49-
import matplotlib.pyplot as plt
65+
###############################################################################
66+
# Alternatively, custom box styles can be implemented as subclasses of
67+
# matplotlib.patches.BoxStyle._Base, by overriding the ``transmute`` method,
68+
# as demonstrated below.
69+
#
70+
# The subclass can then be registered into the ``BoxStyle._style_list`` dict,
71+
# which allows specifying the box style as a string,
72+
# ``bbox=dict(boxstyle="registered_name,param=value,...", ...)``.
73+
#
74+
# Note that this approach relies on internal APIs and is therefore not
75+
# officially supported.
76+
77+
78+
class MyStyle(BoxStyle._Base):
79+
"""A simple box."""
80+
81+
def __init__(self, pad=0.3):
82+
"""
83+
The arguments must be floats and have default values.
84+
85+
Parameters
86+
----------
87+
pad : float
88+
amount of padding
89+
"""
90+
self.pad = pad
91+
super().__init__()
92+
93+
def transmute(self, x0, y0, width, height, mutation_size):
94+
"""
95+
Given the location and size of the box, return the path of the box
96+
around it.
97+
98+
Rotation is automatically taken care of.
99+
100+
Parameters
101+
----------
102+
x0, y0, width, height : float
103+
Box location and size.
104+
mutation_size : float
105+
Reference scale for the mutation, typically the text font size.
106+
107+
Notes
108+
-----
109+
Unlike when defining the box style as a function (as in
110+
`custom_box_style`), here there is no *mutation_aspect* parameter.
111+
Matplotlib will first squeeze the box's y-axis by *mutation_aspect*
112+
before calling the `transmute` method, and then later reexpand the
113+
y-axis by the same amount.
114+
"""
115+
# padding
116+
pad = mutation_size * self.pad
117+
# width and height with padding added
118+
width = width + 2.*pad
119+
height = height + 2.*pad
120+
# boundary of the padded box
121+
x0, y0 = x0 - pad, y0 - pad
122+
x1, y1 = x0 + width, y0 + height
123+
# return the new path
124+
return Path([(x0, y0),
125+
(x1, y0), (x1, y1), (x0, y1),
126+
(x0-pad, (y0+y1)/2.), (x0, y0),
127+
(x0, y0)],
128+
closed=True)
129+
130+
131+
BoxStyle._style_list["angled"] = MyStyle # Register the custom style.
50132

51133
fig, ax = plt.subplots(figsize=(3, 3))
52-
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center",
53-
bbox=dict(boxstyle=custom_box_style, alpha=0.2))
134+
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
135+
bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2))
136+
137+
del BoxStyle._style_list["angled"] # Unregister it.
54138

55139
plt.show()

examples/userdemo/custom_boxstyle02.py

Lines changed: 0 additions & 79 deletions
This file was deleted.

tutorials/text/annotations.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -590,17 +590,6 @@ def __call__(self, x0, y0, width, height, mutation_size,
590590
591591
Custom Boxstyle01
592592
593-
However, it is recommended that you derive from the
594-
matplotlib.patches.BoxStyle._Base as demonstrated below.
595-
596-
.. figure:: ../../gallery/userdemo/images/sphx_glr_custom_boxstyle02_001.png
597-
:target: ../../gallery/userdemo/custom_boxstyle02.html
598-
:align: center
599-
:scale: 50
600-
601-
Custom Boxstyle02
602-
603-
604593
Similarly, you can define a custom ConnectionStyle and a custom ArrowStyle.
605594
See the source code of ``lib/matplotlib/patches.py`` and check
606595
how each style class is defined.

0 commit comments

Comments
 (0)
0