8000 Merge pull request #16615 from anntzer/boxstyles · matplotlib/matplotlib@ed79353 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ed79353

Browse files
authored
Merge pull request #16615 from anntzer/boxstyles
Update custom boxstyles example.
2 parents a6bd231 + 8db6d05 commit ed79353

File tree

3 files changed

+114
-117
lines changed

3 files changed

+114
-117
lines changed
Lines changed: 114 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,142 @@
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+
# Here, we return a new path which adds an "arrow" shape on the left of the
22+
# box.
23+
#
24+
# The custom box style can then be used by passing
25+
# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`.
826

927

1028
def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
1129
"""
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.
30+
Given the location and size of the box, return the path of the box around
31+
it.
32+
33+
Rotation is automatically taken care of.
34+
35+
Parameters
36+
----------
37+
x0, y0, width, height : float
38+
Box location and size.
39+
mutation_size : float
40+
Mutation reference scale, typically the text font size.
41+
mutation_aspect
42+
Mutation aspect ratio.
1843
"""
19-
20-
# note that we are ignoring mutation_aspect. This is okay in general.
44+
# We ignore mutation_aspect. This is okay in general.
2145

2246
# padding
2347
mypad = 0.3
2448
pad = mutation_size * mypad
25-
2649
# width and height with padding added.
2750
width = width + 2 * pad
2851
height = height + 2 * pad
29-
3052
# boundary of the padded box
3153
x0, y0 = x0 - pad, y0 - pad
3254
x1, y1 = x0 + width, y0 + height
55+
# return the new path
56+
return Path([(x0, y0),
57+
(x1, y0), (x1, y1), (x0, y1),
58+
(x0-pad, (y0+y1)/2), (x0, y0),
59+
(x0, y0)],
60+
closed=True)
3361

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]
4362

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

4867

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

51136
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))
137+
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
138+
bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2))
139+
140+
del BoxStyle._style_list["angled"] # Unregister it.
54141

55142
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