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