|
3 | 3 | Plotting multiple lines with a LineCollection
|
4 | 4 | =============================================
|
5 | 5 |
|
6 |
| -Matplotlib can efficiently draw multiple lines at once using a |
7 |
| -`~.LineCollection`, as showcased below. |
| 6 | +Matplotlib can efficiently draw multiple lines at once using a `~.LineCollection`. |
8 | 7 | """
|
9 | 8 |
|
10 | 9 | import matplotlib.pyplot as plt
|
11 | 10 | import numpy as np
|
12 | 11 |
|
13 | 12 | from matplotlib.collections import LineCollection
|
14 | 13 |
|
15 |
| -x = np.arange(100) |
16 |
| -# Here are many sets of y to plot vs. x |
17 |
| -ys = x[:50, np.newaxis] + x[np.newaxis, :] |
| 14 | +colors = ['violet', 'blue', 'green', 'yellow', 'orange', 'red'] |
18 | 15 |
|
19 |
| -segs = np.zeros((50, 100, 2)) |
20 |
| -segs[:, :, 1] = ys |
21 |
| -segs[:, :, 0] = x |
| 16 | +# create a list of half-circles with varying radii |
| 17 | +theta = np.linspace(0, np.pi, 36) |
| 18 | +radii = np.linspace(4, 5, num=len(colors)) |
| 19 | +arcs = [np.column_stack([r * np.cos(theta), r * np.sin(theta)]) for r in radii] |
22 | 20 |
|
23 |
| -# Mask some values to test masked array support: |
24 |
| -segs = np.ma.masked_where((segs > 50) & (segs < 60), segs) |
| 21 | +fig, ax = plt.subplots(figsize=(6.4, 3.2)) |
| 22 | +# set axes limits manually because Collections do not take part in autoscaling |
| 23 | +ax.set_xlim(-6, 6) |
| 24 | +ax.set_ylim(0, 6) |
| 25 | +ax.set_aspect("equal") # to make the arcs look circular |
25 | 26 |
|
26 |
| -# We need to set the plot limits, they will not autoscale |
27 |
| -fig, ax = plt.subplots() |
28 |
| -ax.set_xlim(x.min(), x.max()) |
29 |
| -ax.set_ylim(ys.min(), ys.max()) |
| 27 | +# create a LineCollection with the half-circles |
| 28 | +# its properties can be set per line by passing a sequence (here used for *colors*) |
| 29 | +# or they can be set for all lines by passing a scalar (here used for *linewidths*) |
| 30 | +line_collection = LineCollection(arcs, colors=colors, linewidths=4) |
| 31 | +ax.add_collection(line_collection) |
30 | 32 |
|
31 |
| -# *colors* is sequence of rgba tuples. |
32 |
| -# *linestyle* is a string or dash tuple. Legal string values are |
33 |
| -# solid|dashed|dashdot|dotted. The dash tuple is (offset, onoffseq) where |
34 |
| -# onoffseq is an even length tuple of on and off ink in points. If linestyle |
35 |
| -# is omitted, 'solid' is used. |
36 |
| -# See `matplotlib.collections.LineCollection` for more information. |
37 |
| -colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] |
38 |
| - |
39 |
| -line_segments = LineCollection(segs, linewidths=(0.5, 1, 1.5, 2), |
40 |
| - colors=colors, linestyle='solid') |
41 |
| -ax.add_collection(line_segments) |
42 |
| -ax.set_title('Line collection with masked arrays') |
43 | 33 | plt.show()
|
44 | 34 |
|
45 | 35 | # %%
|
46 |
| -# In the following example, instead of passing a list of colors |
47 |
| -# (``colors=colors``), we pass an array of values (``array=x``) that get |
48 |
| -# colormapped. |
| 36 | +# Instead of passing a list of colors (``colors=colors``), we can use colormapping. |
| 37 | +# The data to be mapped are passed via the ``array`` parameter. |
| 38 | + |
| 39 | +num_arcs = 15 |
| 40 | +theta = np.linspace(0, np.pi, 36) |
| 41 | +radii = np.linspace(4, 5.5, num=num_arcs) |
| 42 | +arcs = [np.column_stack([r * np.cos(theta), r * np.sin(theta)]) for r in radii] |
| 43 | +arc_numbers = np.arange(num_arcs) |
49 | 44 |
|
50 |
| -N = 50 |
51 |
| -x = np.arange(N) |
52 |
| -ys = [x + i for i in x] # Many sets of y to plot vs. x |
53 |
| -segs = [np.column_stack([x, y]) for y in ys] |
| 45 | +fig, ax = plt.subplots(figsize=(6.4, 3)) |
| 46 | +# set axes limits manually because Collections do not take part in autoscaling |
| 47 | +ax.set_xlim(-6, 6) |
| 48 | +ax.set_ylim(0, 6) |
| 49 | +ax.set_aspect("equal") # to make the arcs look circular |
54 | 50 |
|
55 |
| -fig, ax = plt.subplots() |
56 |
| -ax.set_xlim(np.min(x), np.max(x)) |
57 |
| -ax.set_ylim(np.min(ys), np.max(ys)) |
| 51 | +# create a LineCollection with the half-circles and color mapping |
| 52 | +line_collection = LineCollection(arcs, array=arc_numbers, cmap='rainbow') |
| 53 | +ax.add_collection(line_collection) |
58 | 54 |
|
59 |
| -line_segments = LineCollection(segs, array=x, |
60 |
| - linewidths=(0.5, 1, 1.5, 2), |
61 |
| - linestyles='solid') |
62 |
| -ax.add_collection(line_segments) |
63 |
| -axcb = fig.colorbar(line_segments) |
64 |
| -axcb.set_label('Line Number') |
| 55 | +fig.colorbar(line_collection, label='Line number') |
65 | 56 | ax.set_title('Line Collection with mapped colors')
|
66 |
| -plt.sci(line_segments) # This allows interactive changing of the colormap. |
67 |
| -plt.show() |
68 | 57 |
|
| 58 | +plt.show() |
69 | 59 | # %%
|
70 | 60 | #
|
71 | 61 | # .. admonition:: References
|
72 | 62 | #
|
73 | 63 | # The use of the following functions, methods, classes and modules is shown
|
74 | 64 | # in this example:
|
75 | 65 | #
|
76 |
| -# - `matplotlib.collections` |
77 | 66 | # - `matplotlib.collections.LineCollection`
|
78 |
| -# - `matplotlib.cm.ScalarMappable.set_array` |
| 67 | +# - `matplotlib.collections.Collection.set_array` |
79 | 68 | # - `matplotlib.axes.Axes.add_collection`
|
80 | 69 | # - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
|
81 |
| -# - `matplotlib.pyplot.sci` |
0 commit comments