Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e671b63

Browse files
committed
initial submission of the annotation guide.
svn path=/trunk/matplotlib/; revision=7262
1 parent d7894c1 commit e671b63

20 files changed

Lines changed: 1150 additions & 0 deletions

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2009-07-14 initial submission of the annotation guide. -JJL
2+
13
2009-07-14 axes_grid : minor improvements in anchored_artists and
24
inset_locator. -JJL
35

doc/users/plotting.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,11 @@ Creating figure and axes legends
146146

147147
:ref:`plotting-guide-legend`
148148

149+
Annotating plot
150+
===============
151+
:func:`~matplotlib.pyplot.text` and :func:`~matplotlib.pyplot.annotate`
152+
153+
:ref:`plotting-guide-annotation`
154+
149155
TODO; see :ref:`how-to-contribute-docs`.
150156

doc/users/plotting/annotation.rst

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
.. _plotting-guide-annotation:
2+
3+
****************
4+
Annotating Axes
5+
****************
6+
7+
Do not proceed unless you already have read
8+
:func:`~matplotlib.pyplot.text` and :func:`~matplotlib.pyplot.annotate`!
9+
10+
11+
Annotating with Text with Box
12+
=============================
13+
14+
Let's start with a simple example.
15+
16+
.. plot:: users/plotting/examples/annotate_text_arrow.py
17+
18+
19+
The :func:`~matplotlib.pyplot.text` function in the pyplot module (or
20+
text method of the Axes class) takes bbox keyword argument, and when
21+
given, a box around the text is drawn. ::
22+
23+
bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2)
24+
t = ax.text(0, 0, "Direction", ha="center", va="center", rotation=45,
25+
size=15,
26+
bbox=bbox_props)
27+
28+
29+
The patch object associated with the text can be accessed by::
30+
31+
bb = t.get_bbox_patch()
32+
33+
The return value is an instance of FancyBboxPatch and the patch
34+
properties like facecolor, edgewidth, etc. can be accessed and
35+
modified as usual. To change the shape of the box, use *set_boxstyle*
36+
method. ::
37+
38+
bb.set_boxstyle("rarrow", pad=0.6)
39+
40+
The arguments are the name of the box style with its attributes as
41+
keyword arguments. Currently, followign box styles are implemented.
42+
43+
========== ============== ==========================
44+
Class Name Attrs
45+
========== ============== ==========================
46+
LArrow ``larrow`` pad=0.3
47+
RArrow ``rarrow`` pad=0.3
48+
Round ``round`` pad=0.3,rounding_size=None
49+
Round4 ``round4`` pad=0.3,rounding_size=None
50+
Roundtooth ``roundtooth`` pad=0.3,tooth_size=None
51+
Sawtooth ``sawtooth`` pad=0.3,tooth_size=None
52+
Square ``square`` pad=0.3
53+
========== ============== ==========================
54+
55+
.. plot:: mpl_examples/pylab_examples/fancybox_demo2.py
56+
57+
58+
Note that the attrubutes arguments can be specified within the style
59+
name with separating comma (this form can be used as "boxstyle" value
60+
of bbox argument when initializing the text instance) ::
61+
62+
bb.set_boxstyle("rarrow,pad=0.6")
63+
64+
65+
66+
67+
Annotating with Arrow
68+
=====================
69+
70+
The :func:`~matplotlib.pyplot.annotate` function in the pyplot module
71+
(or annotate method of the Axes class) is used to draw an arrow
72+
connecting two points on the plot. ::
73+
74+
ax.annotate("Annotation",
75+
xy=(x1, y1), xycoords='data',
76+
xytext=(x2, y2), textcoords='offset points',
77+
)
78+
79+
This annotates a point at ``xy`` in the given coordinate (``xycoords``)
80+
with the text at ``xytext`` given in ``textcoords``. Often, the
81+
annotated point is specified in the *data* coordinate and the annotating
82+
text in *offset points*.
83+
See :func:`~matplotlib.pyplot.annotate` for available coordinate systems.
84+
85+
An arrow connecting two point (xy & xytext) can be optionally drawn by
86+
specifying the ``arrowprops`` argument. To draw only an arrow, use
87+
empty string as the first argument. ::
88+
89+
ax.annotate("",
90+
xy=(0.2, 0.2), xycoords='data',
91+
xytext=(0.8, 0.8), textcoords='data',
92+
arrowprops=dict(arrowstyle="->",
93+
connectionstyle="arc3"),
94+
)
95+
96+
.. plot:: users/plotting/examples/annotate_simple01.py
97+
98+
The arrow drawing takes a few steps.
99+
100+
1. a connecting path between two points are created. This is
101+
controlled by ``connectionstyle`` key value.
102+
103+
2. If patch object is given (*patchA* & *patchB*), the path is clipped to
104+
avoid the patch.
105+
106+
3. The path is further shrinked by given amount of pixels (*shirnkA*
107+
& *shrinkB*)
108+
109+
4. The path is transmuted to arrow patch, which is controlled by the
110+
``arrowstyle`` key value.
111+
112+
113+
.. plot:: users/plotting/examples/annotate_explain.py
114+
115+
116+
The creation of the connecting path between two points is controlled by
117+
``connectionstyle`` key and follwing styles are available.
118+
119+
========== =============================================
120+
Name Attrs
121+
========== =============================================
122+
``angle`` angleA=90,angleB=0,rad=0.0
123+
``angle3`` angleA=90,angleB=0
124+
``arc`` angleA=0,angleB=0,armA=None,armB=None,rad=0.0
125+
``arc3`` rad=0.0
126+
``bar`` armA=0.0,armB=0.0,fraction=0.3,angle=None
127+
========== =============================================
128+
129+
Note that "3" in ``angle3`` and ``arc3`` is meant to indicate that the
130+
resulting path is a quadratic spline segment (three control
131+
points). As will be discussed below, some arrow style option only can
132+
be used when the connecting path is a quadratic spline.
133+
134+
The behavior of each connection style is (limitedly) demonstrated in the
135+
example below. (Warning : The behavior of the ``bar`` style is currently not
136+
well defined, it may be changed in the future).
137+
138+
.. plot:: users/plotting/examples/connectionstyle_demo.py
139+
140+
141+
The connecting path (after clipping and shrinking) is then mutated to
142+
an arrow patch, according to the given ``arrowstyle``.
143+
144+
========== =============================================
145+
Name Attrs
146+
========== =============================================
147+
``-`` None
148+
``->`` head_length=0.4,head_width=0.2
149+
``-[`` widthB=1.0,lengthB=0.2,angleB=None
150+
``-|>`` head_length=0.4,head_width=0.2
151+
``<-`` head_length=0.4,head_width=0.2
152+
``<->`` head_length=0.4,head_width=0.2
153+
``<|-`` head_length=0.4,head_width=0.2
154+
``<|-|>`` head_length=0.4,head_width=0.2
155+
``fancy`` head_length=0.4,head_width=0.4,tail_width=0.4
156+
``simple`` head_length=0.5,head_width=0.5,tail_width=0.2
157+
``wedge`` tail_width=0.3,shrink_factor=0.5
158+
========== =============================================
159+
160+
.. plot:: mpl_examples/pylab_examples/fancyarrow_demo.py
161+
162+
Some arrowstyles only work with connection style that generates a
163+
quadratic-spline segment. They are ``fancy``, ``simple``, and ``wedge``.
164+
For these arrow styles, you must use "angle3" or "arc3" connection
165+
style.
166+
167+
If the annotation string is given, the patchA is set to the bbox patch
168+
of the text by default.
169+
170+
.. plot:: users/plotting/examples/annotate_simple02.py
171+
172+
As in the text command, a box around the text can be drawn using
173+
the ``bbox`` argument.
174+
175+
.. plot:: users/plotting/examples/annotate_simple03.py
176+
177+
By default, the starting point is set to the center of the text
178+
extent. This can be adjusted with ``relpos`` key value. The values
179+
are normalized to the extent of the text. For example, (0,0) means
180+
lower-left corner and (1,1) means top-right.
181+
182+
.. plot:: users/plotting/examples/annotate_simple04.py
183+
184+
185+
Using ConnectorPatch
186+
====================
187+
188+
The ConnectorPatch is like an annotation without a text. While the
189+
annotate function is recommended in most of situation, the
190+
ConnectorPatch is useful when you want to connect points in different
191+
axes. ::
192+
193+
from matplotlib.patches import ConnectionPatch
194+
xy = (0.2, 0.2)
195+
con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data",
196+
axesA=ax1, axesB=ax2)
197+
ax2.add_artist(con)
198+
199+
The above code connects point xy in data coordinate of ``ax1`` to
200+
point xy int data coordiante of ``ax2``. Here is a simple example.
201+
202+
.. plot:: users/plotting/examples/connect_simple01.py
203+
204+
205+
While the ConnectorPatch instance can be added to any axes, but you
206+
may want it to be added to the axes in the latter (?) of the axes
207+
drawing order to prevent overlap (?) by other axes.
208+
209+
210+
Placing Artist at the anchored location of the Axes
211+
===================================================
212+
213+
There are class of artist that can be placed at the anchored location
214+
of the Axes. A common example is the legend. This type of artists can
215+
be created by using the OffsetBox class. A few predefined classes are
216+
available in ``mpl_toolkits.axes_grid.anchored_artists``. ::
217+
218+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
219+
at = AnchoredText("Figure 1a",
220+
prop=dict(size=8), frameon=True,
221+
loc=2,
222+
)
223+
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
224+
ax.add_artist(at)
225+
226+
227+
.. plot:: users/plotting/examples/anchored_box01.py
228+
229+
230+
The *loc* keyword has same meaning as in the legend command.
231+
232+
A simple application is when the size of the artist (or collection of
233+
artists) is knwon in pixel size during the time of creation. For
234+
example, If you want to draw a circle with fixed size of 20 pixel x 20
235+
pixel (radius = 10 pixel), you can utilize
236+
``AnchoredDrawingArea``. The instance is created with a size of the
237+
drawing area (in pixel). And user can add arbitrary artist to the
238+
drawing area. Note that the extents of the artists that are added to
239+
the drawing area has nothing to do with the placement of the drawing
240+
area itself. The initial size only matters. ::
241+
242+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea
243+
244+
ada = AnchoredDrawingArea(20, 20, 0, 0,
245+
loc=1, pad=0., frameon=False)
246+
p1 = Circle((10, 10), 10)
247+
ada.drawing_area.add_artist(p1)
248+
p2 = Circle((30, 10), 5, fc="r")
249+
ada.drawing_area.add_artist(p2)
250+
251+
The artists that are added to the drawing area should not have
252+
transform set (they will be overridden) and the dimension of those
253+
artists are interpreted as a pixel coordinate, i.e., the radius of the
254+
circles in above example are 10 pixel and 5 pixel, respectively.
255+
256+
.. plot:: users/plotting/examples/anchored_box02.py
257+
258+
Sometimes, you want to your artists scale with data coordinate (or
259+
other coordinate than canvas pixel). You can use
260+
``AnchoredAuxTransformBox`` class. This is similar to
261+
``AnchoredDrawingArea`` except that the extent of the artist is
262+
determined during the drawing time respecting the specified transform. ::
263+
264+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredAuxTransformBox
265+
266+
box = AnchoredAuxTransformBox(ax.transData, loc=2)
267+
el = Ellipse((0,0), width=0.1, height=0.4, angle=30) # in data coordinates!
268+
box.drawing_area.add_artist(el)
269+
270+
The ellipse in the above example will have width and height
271+
corresponds to 0.1 and 0.4 in data coordinate and will be
272+
automatically scaled when the view limits of the axes change.
273+
274+
.. plot:: users/plotting/examples/anchored_box03.py
275+
276+
As in the legend, the bbox_to_anchor argument can be set. Using the
277+
HPacker and VPacker, you can have an arrangement(?) of artist as in the
278+
legend (as a matter of fact, this is how the legend is created).
279+
280+
.. plot:: users/plotting/examples/anchored_box04.py
281+
282+
Note that unlike the legend, the ``bbox_transform`` is set
283+
to IdentityTransform by default.
284+
285+
Advanced Topics
286+
***************
287+
288+
Zoom effect between Axes
289+
========================
290+
291+
mpl_toolkits.axes_grid.inset_locator defines some patch classs useful
292+
for interconnect two axes. Understanding the code requires some
293+
knowledge of how mpl's transform works. But, utilizing it will be
294+
straight forward.
295+
296+
297+
.. plot:: mpl_examples/pylab_examples/axes_zoom_effect.py
298+
299+
300+
Define Custom BoxStyle
301+
======================
302+
303+
You can use a custom box style. The value for the ``boxstyle`` can be a
304+
callable object in following forms.::
305+
306+
def __call__(self, x0, y0, width, height, mutation_size,
307+
aspect_ratio=1.):
308+
"""
309+
Given the location and size of the box, return the path of
310+
the box around it.
311+
312+
- *x0*, *y0*, *width*, *height* : location and size of the box
313+
- *mutation_size* : a reference scale for the mutation.
314+
- *aspect_ratio* : aspect-ration for the mutation.
315+
"""
316+
path = ...
317+
return path
318+
319+
Here is a complete example.
320+
321+
.. plot:: users/plotting/examples/custom_boxstyle01.py
322+
323+
However, it is recommended that you derive from the
324+
matplotlib.patches.BoxStyle._Base as demonstrated below.
325+
326+
.. plot:: users/plotting/examples/custom_boxstyle02.py
327+
:include-source:
328+
329+
330+
Similarly, you can define custom ConnectionStyle and Custome ArrowStyle.
331+
See the source code of ``lib/matplotlib/patches.py`` and check
332+
how each style class is defined.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import matplotlib.pyplot as plt
2+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
3+
4+
fig=plt.figure(1, figsize=(3,3))
5+
ax = plt.subplot(111)
6+
7+
at = AnchoredText("Figure 1a",
8+
prop=dict(size=15), frameon=True,
9+
loc=2,
10+
)
11+
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
12+
ax.add_artist(at)
13+
14+
plt.show()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from matplotlib.patches import Circle
2+
import matplotlib.pyplot as plt
3+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea
4+
5+
fig=plt.figure(1, figsize=(3,3))
6+
ax = plt.subplot(111)
7+
8+
9+
ada = AnchoredDrawingArea(40, 20, 0, 0,
10+
loc=1, pad=0., frameon=False)
11+
p1 = Circle((10, 10), 10)
12+
ada.drawing_area.add_artist(p1)
13+
p2 = Circle((30, 10), 5, fc="r")
14+
ada.drawing_area.add_artist(p2)
15+
16+
ax.add_artist(ada)
17+
18+
plt.show()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from matplotlib.patches import Ellipse
2+
import matplotlib.pyplot as plt
3+
from mpl_toolkits.axes_grid.anchored_artists import AnchoredAuxTransformBox
4+
5+
fig=plt.figure(1, figsize=(3,3))
6+
ax = plt.subplot(111)
7+
8+
box = AnchoredAuxTransformBox(ax.transData, loc=2)
9+
el = Ellipse((0,0), width=0.1, height=0.4, angle=30) # in data coordinates!
10+
box.drawing_area.add_artist(el)
11+
12+
ax.add_artist(box)
13+
14+
plt.show()

0 commit comments

Comments
 (0)