1"""
2=========================================================
3Line, Poly and RegularPoly Collection with autoscaling
4=========================================================
5
6For the first two subplots, we will use spirals.  Their
7size will be set in plot units, not data units.  Their positions
8will be set in data units by using the "offsets" and "transOffset"
9kwargs of the `~.collections.LineCollection` and
10`~.collections.PolyCollection`.
11
12The third subplot will make regular polygons, with the same
13type of scaling and positioning as in the first two.
14
15The last subplot illustrates the use of "offsets=(xo, yo)",
16that is, a single tuple instead of a list of tuples, to generate
17successively offset curves, with the offset given in data
18units.  This behavior is available only for the LineCollection.
19"""
20
21import matplotlib.pyplot as plt
22from matplotlib import collections, colors, transforms
23import numpy as np
24
25nverts = 50
26npts = 100
27
28# Make some spirals
29r = np.arange(nverts)
30theta = np.linspace(0, 2*np.pi, nverts)
31xx = r * np.sin(theta)
32yy = r * np.cos(theta)
33spiral = np.column_stack([xx, yy])
34
35# Fixing random state for reproducibility
36rs = np.random.RandomState(19680801)
37
38# Make some offsets
39xyo = rs.randn(npts, 2)
40
41# Make a list of colors cycling through the default series.
42colors = [colors.to_rgba(c)
43          for c in plt.rcParams['axes.prop_cycle'].by_key()['color']]
44
45fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
46fig.subplots_adjust(top=0.92, left=0.07, right=0.97,
47                    hspace=0.3, wspace=0.3)
48
49
50col = collections.LineCollection([spiral], offsets=xyo,
51                                 transOffset=ax1.transData)
52trans = fig.dpi_scale_trans + transforms.Affine2D().scale(1.0/72.0)
53col.set_transform(trans)  # the points to pixels transform
54# Note: the first argument to the collection initializer
55# must be a list of sequences of (x, y) tuples; we have only
56# one sequence, but we still have to put it in a list.
57ax1.add_collection(col, autolim=True)
58# autolim=True enables autoscaling.  For collections with
59# offsets like this, it is neither efficient nor accurate,
60# but it is good enough to generate a plot that you can use
61# as a starting point.  If you know beforehand the range of
62# x and y that you want to show, it is better to set them
63# explicitly, leave out the autolim kwarg (or set it to False),
64# and omit the 'ax1.autoscale_view()' call below.
65
66# Make a transform for the line segments such that their size is
67# given in points:
68col.set_color(colors)
69
70ax1.autoscale_view()  # See comment above, after ax1.add_collection.
71ax1.set_title('LineCollection using offsets')
72
73
74# The same data as above, but fill the curves.
75col = collections.PolyCollection([spiral], offsets=xyo,
76                                 transOffset=ax2.transData)
77trans = transforms.Affine2D().scale(fig.dpi/72.0)
78col.set_transform(trans)  # the points to pixels transform
79ax2.add_collection(col, autolim=True)
80col.set_color(colors)
81
82
83ax2.autoscale_view()
84ax2.set_title('PolyCollection using offsets')
85
86# 7-sided regular polygons
87
88col = collections.RegularPolyCollection(
89    7, sizes=np.abs(xx) * 10.0, offsets=xyo, transOffset=ax3.transData)
90trans = transforms.Affine2D().scale(fig.dpi / 72.0)
91col.set_transform(trans)  # the points to pixels transform
92ax3.add_collection(col, autolim=True)
93col.set_color(colors)
94ax3.autoscale_view()
95ax3.set_title('RegularPolyCollection using offsets')
96
97
98# Simulate a series of ocean current profiles, successively
99# offset by 0.1 m/s so that they form what is sometimes called
100# a "waterfall" plot or a "stagger" plot.
101
102nverts = 60
103ncurves = 20
104offs = (0.1, 0.0)
105
106yy = np.linspace(0, 2*np.pi, nverts)
107ym = np.max(yy)
108xx = (0.2 + (ym - yy) / ym) ** 2 * np.cos(yy - 0.4) * 0.5
109segs = []
110for i in range(ncurves):
111    xxx = xx + 0.02*rs.randn(nverts)
112    curve = np.column_stack([xxx, yy * 100])
113    segs.append(curve)
114
115col = collections.LineCollection(segs, offsets=offs)
116ax4.add_collection(col, autolim=True)
117col.set_color(colors)
118ax4.autoscale_view()
119ax4.set_title('Successive data offsets')
120ax4.set_xlabel('Zonal velocity component (m/s)')
121ax4.set_ylabel('Depth (m)')
122# Reverse the y-axis so depth increases downward
123ax4.set_ylim(ax4.get_ylim()[::-1])
124
125
126plt.show()
127
128#############################################################################
129#
130# .. admonition:: References
131#
132#    The use of the following functions, methods, classes and modules is shown
133#    in this example:
134#
135#    - `matplotlib.figure.Figure`
136#    - `matplotlib.collections`
137#    - `matplotlib.collections.LineCollection`
138#    - `matplotlib.collections.RegularPolyCollection`
139#    - `matplotlib.axes.Axes.add_collection`
140#    - `matplotlib.axes.Axes.autoscale_view`
141#    - `matplotlib.transforms.Affine2D`
142#    - `matplotlib.transforms.Affine2D.scale`
143