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

Skip to content

Commit fa9fde9

Browse files
committed
Clean up prose in invariant angle marker example.
Also, simplify locating some annotations.
1 parent 6bc72ec commit fa9fde9

File tree

1 file changed

+65
-67
lines changed

1 file changed

+65
-67
lines changed

examples/lines_bars_and_markers/angle_marker.py

Lines changed: 65 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
"""
2-
=============================
2+
============================
33
Scale invariant angle marker
4-
=============================
4+
============================
55
6-
This example shows how to create a scale invariant angle marker.
7-
It is often useful to mark angles between lines or inside shapes with a
8-
circular arc. While matplotlib provides an `~.patches.Arc`, an inherent problem
9-
when directly using it for such purpose is that an arc being circular in
10-
data space is not necessarily circular in display space. Also, the arc's radius
11-
is often best defined in a coordinate system which is independent on the actual
12-
data coordinates - at least if you want to be able to freely zoom into your
13-
plot without the marker growing to infinity.
6+
This example shows how to create a scale invariant angle marker. It is often
7+
useful to mark angles between lines or inside shapes with a circular arc. While
8+
Matplotlib provides an `~.patches.Arc`, an inherent problem when directly using
9+
it for such purposes is that an arc being circular in data space is not
10+
necessarily circular in display space. Also, the arc's radius is often best
11+
defined in a coordinate system which is independent of the actual data
12+
coordinates - at least if you want to be able to freely zoom into your plot
13+
without the marker growing to infinity.
1414
15-
This calls for a solution where the arc's center is defined in data space,
16-
but its radius in a physical unit like points or pixels, or as a ratio of the
17-
axes dimension. The following ``AngleMarker`` class provides such solution.
15+
This calls for a solution where the arc's center is defined in data space, but
16+
its radius in a physical unit like points or pixels, or as a ratio of the Axes
17+
dimension. The following ``AngleMarker`` class provides such solution.
1818
1919
The example below serves two purposes:
2020
21-
* It provides a read-to-use solution for the problem of easily drawing angles
21+
* It provides a ready-to-use solution for the problem of easily drawing angles
2222
in graphs.
23-
* It shows how to subclass a matplotlib artist to enhance its functionality, as
24-
well as giving a hands-on example on how to use matplotlib's
25-
:doc:`transform system </tutorials/advanced/transforms_tutorial>`.
23+
* It shows how to subclass a Matplotlib artist to enhance its functionality, as
24+
well as giving a hands-on example on how to use Matplotlib's :doc:`transform
25+
system </tutorials/advanced/transforms_tutorial>`.
2626
2727
If mainly interested in the former, you may copy the below class and jump to
2828
the :ref:`angle-marker-usage` section.
@@ -32,28 +32,28 @@
3232
# AngleMarker class
3333
# ~~~~~~~~~~~~~~~~~
3434
# The essential idea here is to subclass `~.patches.Arc` and set its transform
35-
# to the `~.transforms.IdentityTransform`. The parameters of the arc are hence
35+
# to the `~.transforms.IdentityTransform`, making the parameters of the arc
3636
# defined in pixel space.
37-
# We then override the ``Arc``'s attributes ``_center``,
38-
# ``theta1``, ``theta2``, ``width`` and ``height`` and make them properties.
39-
# They are coupled to internal methods that calculate the respective
40-
# parameters each time the attribute is accessed and thereby ensure that the
41-
# arc in pixel space stays synchronized with the input points and size.
42-
# For example, each time the arc's drawing method would query its
43-
# ``_center`` attribute, instead of receiving the same number all over again,
44-
# it will instead receive the result of the ``get_center_in_pixels`` method we
45-
# defined in the subclass. This method transforms the center in data
46-
# coordinates to pixels via the axes transform ``ax.transData``. The
47-
# size and the angles are calculated in a similar fashion, such that the arc
48-
# changes its shape automatically when e.g. zooming or panning interactively.
37+
# We then override the ``Arc``'s attributes ``_center``, ``theta1``,
38+
# ``theta2``, ``width`` and ``height`` and make them properties, coupling to
39+
# internal methods that calculate the respective parameters each time the
40+
# attribute is accessed and thereby ensuring that the arc in pixel space stays
41+
# synchronized with the input points and size.
42+
# For example, each time the arc's drawing method would query its ``_center``
43+
# attribute, instead of receiving the same number all over again, it will
44+
# instead receive the result of the ``get_center_in_pixels`` method we defined
45+
# in the subclass. This method transforms the center in data coordinates to
46+
# pixels via the Axes transform ``ax.transData``. The size and the angles are
47+
# calculated in a similar fashion, such that the arc changes its shape
48+
# automatically when e.g. zooming or panning interactively.
4949
#
5050
# The functionality of this class allows to annotate the arc with a text. This
51-
# text is a `~.text.Annotation` stored in an attribute ``text``.
52-
# Since the arc's position and radius are defined only at draw time, we need to
53-
# update the text's position accordingly. This is done by reimplementing the
54-
# ``Arc``'s ``draw()`` method to let it call an updating method for the text.
51+
# text is a `~.text.Annotation` stored in an attribute ``text``. Since the
52+
# arc's position and radius are defined only at draw time, we need to update
53+
# the text's position accordingly. This is done by reimplementing the ``Arc``'s
54+
# ``draw()`` method to let it call an updating method for the text.
5555
#
56-
# The arc and the text will be added to the provided axes at instantiation: it
56+
# The arc and the text will be added to the provided Axes at instantiation: it
5757
# is hence not strictly necessary to keep a reference to it.
5858

5959

@@ -71,40 +71,40 @@ class AngleMarker(Arc):
7171
def __init__(self, xy, p1, p2, size=75, unit="points", ax=None,
7272
text="", textposition="inside", text_kw={}, **kwargs):
7373
"""
74-
Params
75-
------
74+
Parameters
75+
----------
7676
xy, p1, p2 : tuple or array of two floats
77-
center position and two points. Angle marker is drawn between the
78-
two vectors connecting p1 and p2 with xy, respectively. Units
77+
Center position and two points. Angle marker is drawn between the
78+
two vectors connecting *p1* and *p2* with *xy*, respectively. Units
7979
are data coordinates.
8080
8181
size : float
82-
diameter of the angle marker in units specified by ``unit``.
82+
Diameter of the angle marker in units specified by *unit*.
8383
8484
unit : string
85-
One of the following strings to specify the unit of ``size``:
86-
* "pixels" : pixels
87-
* "points" : points, use points instead of pixels to not have a
88-
dependence of the dpi
89-
* "axes width", "axes height" : relative units of axes
90-
width, height
91-
* "axes min", "axes max" : minimum or maximum of relative axes
92-
width, height
85+
One of the following strings to specify the unit of *size*:
86+
87+
* "pixels": pixels
88+
* "points": points, use points instead of pixels to not have a
89+
dependence on the DPI
90+
* "axes width", "axes height": relative units of Axes width, height
91+
* "axes min", "axes max": minimum or maximum of relative Axes
92+
width, height
9393
9494
ax : `matplotlib.axes.Axes`
95-
The axes to add the angle marker to
95+
The Axes to add the angle marker to.
9696
9797
text : string
9898
The text to mark the angle with.
9999
100-
textposition : ["inside", "outside", "edge"]
100+
textposition : {"inside", "outside", "edge"}
101101
Whether to show the text in- or outside the arc. "edge" can be used
102102
for custom positions anchored at the arc's edge.
103103
104104
text_kw : dict
105105
Dictionary of arguments passed to the Annotation.
106106
107-
kwargs :
107+
**kwargs
108108
Further parameters are passed to `matplotlib.patches.Arc`. Use this
109109
to specify, color, linewidth etc. of the arc.
110110
@@ -218,14 +218,13 @@ def R(a, r, w, h):
218218
# Usage
219219
# ~~~~~
220220
#
221-
# Required arguments to ``AngleMarker`` are the center of the arc, ``xy``,
222-
# and two points, such that the arc spans between the two vectors
223-
# connecting p1 and p2 with xy, respectively. Those are given in data
224-
# coordinates.
225-
# Further arguments are the ``size`` of the arc and its ``unit``.
226-
# Additionally, a ``text`` can be specified, that will be drawn either in- or
227-
# outside of the arc, according to the value of ``textposition``.
228-
# Usage of those arguments is shown below.
221+
# Required arguments to ``AngleMarker`` are the center of the arc, *xy*, and
222+
# two points, such that the arc spans between the two vectors connecting *p1*
223+
# and *p2* with *xy*, respectively. Those are given in data coordinates.
224+
# Further arguments are the *size* of the arc and its *unit*. Additionally, a
225+
# *text* can be specified, that will be drawn either in- or outside of the arc,
226+
# according to the value of *textposition*. Usage of those arguments is shown
227+
# below.
229228

230229
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, sharex=True, figsize=(7, 7),
231230
gridspec_kw=dict(height_ratios=(3, 1, 1)))
@@ -249,7 +248,7 @@ def R(a, r, w, h):
249248
am4 = AngleMarker(center, p2[0], p1[1], ax=ax1, size=35, text=r"$\theta$")
250249

251250

252-
# Showcase some styling options for the angle arc, as well as the text
251+
# Showcase some styling options for the angle arc, as well as the text.
253252
p = [(6.0, 400), (5.3, 410), (5.6, 300)]
254253
ax1.plot(*zip(*p))
255254
am5 = AngleMarker(p[1], p[0], p[2], ax=ax1, size=40, text=r"$\Phi$",
@@ -258,14 +257,14 @@ def R(a, r, w, h):
258257

259258

260259
#### SUBPLOT 2 ####
261-
# Helper function to draw angle easily
260+
# Helper function to draw angle easily.
262261
def plot_angle(ax, pos, angle, length=0.95, acol="C0", **kwargs):
263262
vec2 = np.array([np.cos(np.deg2rad(angle)), np.sin(np.deg2rad(angle))])
264263
xy = np.c_[[length, 0], [0, 0], vec2*length].T + np.array(pos)
265264
ax.plot(*xy.T, color=acol)
266265
return AngleMarker(pos, xy[0], xy[2], ax=ax, **kwargs)
267266

268-
# Showcase different textpositions
267+
# Showcase different text positions.
269268
kw = dict(size=75, unit="points", text=r"$60°$")
270269

271270
am6 = plot_angle(ax2, (2.0, 0), 60, textposition="inside", **kw)
@@ -276,8 +275,8 @@ def plot_angle(ax, pos, angle, length=0.95, acol="C0", **kwargs):
276275
text_kw=dict(xytext=(30, 20), arrowprops=dict(arrowstyle="->",
277276
connectionstyle="arc3,rad=-0.2")), **kw)
278277

279-
ax2.annotate("textpostion", xy=(.02, .9), xycoords="axes fraction",
280-
bbox=dict(boxstyle="round", fc="w"), ha="left")
278+
ax2.annotate("textposition", xy=(.02, 1), xycoords="axes fraction",
279+
bbox=dict(boxstyle="round", fc="w"), ha="left", va="center")
281280
for x, text in zip([2.0, 3.5, 5.0, 6.5], ['"inside"', '"outside"', '"edge"',
282281
'"edge", custom arrow']):
283282
ax2.annotate(text, xy=(x, 0), xycoords=ax2.get_xaxis_transform(),
@@ -293,14 +292,13 @@ def plot_angle(ax, pos, angle, length=0.95, acol="C0", **kwargs):
293292
am12 = plot_angle(ax3, (5.0, 0), 60, size=0.25, unit="axes min", **kw)
294293
am13 = plot_angle(ax3, (6.5, 0), 60, size=0.25, unit="axes max", **kw)
295294

296-
ax3.annotate("unit", xy=(.02, .9), xycoords="axes fraction",
297-
bbox=dict(boxstyle="round", fc="w"), ha="left")
295+
ax3.annotate("unit", xy=(.02, 1), xycoords="axes fraction",
296+
bbox=dict(boxstyle="round", fc="w"), ha="left", va="center")
298297
for x, text in zip([2.0, 3.5, 5.0, 6.5], ['"pixels"', '"points"',
299298
'"axes min"', '"axes max"']):
300299
ax3.annotate(text, xy=(x, 0), xycoords=ax3.get_xaxis_transform(),
301300
bbox=dict(boxstyle="round", fc="w"), ha="left", fontsize=8)
302301

303-
fig.tight_layout()
304302
plt.show()
305303

306304

0 commit comments

Comments
 (0)