1"""
2================
3Anchored Artists
4================
5
6This example illustrates the use of the anchored objects without the
7helper classes found in :mod:`mpl_toolkits.axes_grid1`. This version
8of the figure is similar to the one found in
9:doc:`/gallery/axes_grid1/simple_anchored_artists`, but it is
10implemented using only the matplotlib namespace, without the help
11of additional toolkits.
12"""
13
14from matplotlib import pyplot as plt
15from matplotlib.lines import Line2D
16from matplotlib.patches import Ellipse
17from matplotlib.offsetbox import (
18    AnchoredOffsetbox, AuxTransformBox, DrawingArea, TextArea, VPacker)
19
20
21class AnchoredText(AnchoredOffsetbox):
22    def __init__(self, s, loc, pad=0.4, borderpad=0.5,
23                 prop=None, frameon=True):
24        self.txt = TextArea(s)
25        super().__init__(loc, pad=pad, borderpad=borderpad,
26                         child=self.txt, prop=prop, frameon=frameon)
27
28
29def draw_text(ax):
30    """
31    Draw a text-box anchored to the upper-left corner of the figure.
32    """
33    at = AnchoredText("Figure 1a", loc='upper left', frameon=True)
34    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
35    ax.add_artist(at)
36
37
38class AnchoredDrawingArea(AnchoredOffsetbox):
39    def __init__(self, width, height, xdescent, ydescent,
40                 loc, pad=0.4, borderpad=0.5, prop=None, frameon=True):
41        self.da = DrawingArea(width, height, xdescent, ydescent)
42        super().__init__(loc, pad=pad, borderpad=borderpad,
43                         child=self.da, prop=None, frameon=frameon)
44
45
46def draw_circle(ax):
47    """
48    Draw a circle in axis coordinates
49    """
50    from matplotlib.patches import Circle
51    ada = AnchoredDrawingArea(20, 20, 0, 0,
52                              loc='upper right', pad=0., frameon=False)
53    p = Circle((10, 10), 10)
54    ada.da.add_artist(p)
55    ax.add_artist(ada)
56
57
58class AnchoredEllipse(AnchoredOffsetbox):
59    def __init__(self, transform, width, height, angle, loc,
60                 pad=0.1, borderpad=0.1, prop=None, frameon=True):
61        """
62        Draw an ellipse the size in data coordinate of the give axes.
63
64        pad, borderpad in fraction of the legend font size (or prop)
65        """
66        self._box = AuxTransformBox(transform)
67        self.ellipse = Ellipse((0, 0), width, height, angle)
68        self._box.add_artist(self.ellipse)
69        super().__init__(loc, pad=pad, borderpad=borderpad,
70                         child=self._box, prop=prop, frameon=frameon)
71
72
73def draw_ellipse(ax):
74    """
75    Draw an ellipse of width=0.1, height=0.15 in data coordinates
76    """
77    ae = AnchoredEllipse(ax.transData, width=0.1, height=0.15, angle=0.,
78                         loc='lower left', pad=0.5, borderpad=0.4,
79                         frameon=True)
80
81    ax.add_artist(ae)
82
83
84class AnchoredSizeBar(AnchoredOffsetbox):
85    def __init__(self, transform, size, label, loc,
86                 pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True):
87        """
88        Draw a horizontal bar with the size in data coordinate of the given
89        axes. A label will be drawn underneath (center-aligned).
90
91        pad, borderpad in fraction of the legend font size (or prop)
92        sep in points.
93        """
94        self.size_bar = AuxTransformBox(transform)
95        self.size_bar.add_artist(Line2D([0, size], [0, 0], color="black"))
96        self.txt_label = TextArea(label)
97        self._box = VPacker(children=[self.size_bar, self.txt_label],
98                            align="center",
99                            pad=0, sep=sep)
100        super().__init__(loc, pad=pad, borderpad=borderpad,
101                         child=self._box, prop=prop, frameon=frameon)
102
103
104def draw_sizebar(ax):
105    """
106    Draw a horizontal bar with length of 0.1 in data coordinates,
107    with a fixed label underneath.
108    """
109    asb = AnchoredSizeBar(ax.transData,
110                          0.1,
111                          r"1$^{\prime}$",
112                          loc='lower center',
113                          pad=0.1, borderpad=0.5, sep=5,
114                          frameon=False)
115    ax.add_artist(asb)
116
117
118ax = plt.gca()
119ax.set_aspect(1.)
120
121draw_text(ax)
122draw_circle(ax)
123draw_ellipse(ax)
124draw_sizebar(ax)
125
126plt.show()
127