|
1 | 1 | """
|
2 |
| -============== |
3 |
| -Stackplot Demo |
4 |
| -============== |
| 2 | +=========================== |
| 3 | +Stackplots and streamgraphs |
| 4 | +=========================== |
| 5 | +""" |
| 6 | + |
| 7 | +############################################################################## |
| 8 | +# Stackplots |
| 9 | +# ---------- |
| 10 | +# |
| 11 | +# Stackplots draw multiple datasets as vertically stacked areas. This is |
| 12 | +# useful when the individual data values and additionally their cumulative |
| 13 | +# value are of interest. |
5 | 14 |
|
6 |
| -How to create stackplots with Matplotlib. |
7 | 15 |
|
8 |
| -Stackplots are generated by plotting different datasets vertically on |
9 |
| -top of one another rather than overlapping with one another. Below we |
10 |
| -show some examples to accomplish this with Matplotlib. |
11 |
| -""" |
12 | 16 | import numpy as np
|
13 | 17 | import matplotlib.pyplot as plt
|
14 | 18 |
|
| 19 | +# data from United Nations World Population Prospects (Revision 2019) |
| 20 | +# https://population.un.org/wpp/, license: CC BY 3.0 IGO |
| 21 | +year = [1950, 1960, 1970, 1980, 1990, 2000, 2010, 2018] |
| 22 | +population_by_continent = { |
| 23 | + 'africa': [228, 284, 365, 477, 631, 814, 1044, 1275], |
| 24 | + 'americas': [340, 425, 519, 619, 727, 840, 943, 1006], |
| 25 | + 'asia': [1394, 1686, 2120, 2625, 3202, 3714, 4169, 4560], |
| 26 | + 'europe': [220, 253, 276, 295, 310, 303, 294, 293], |
| 27 | + 'oceania': [12, 15, 19, 22, 26, 31, 36, 39], |
| 28 | +} |
15 | 29 |
|
16 |
| -# Fixing random state for reproducibility |
17 |
| -np.random.seed(19680801) |
| 30 | +fig, ax = plt.subplots() |
| 31 | +ax.stackplot(year, population_by_continent.values(), |
| 32 | + labels=population_by_continent.keys()) |
| 33 | +ax.legend(loc='upper left') |
| 34 | +ax.set_title('World population') |
| 35 | +ax.set_xlabel('Year') |
| 36 | +ax.set_ylabel('Number of people (millions)') |
18 | 37 |
|
19 |
| -x = [1, 2, 3, 4, 5] |
20 |
| -y1 = [1, 1, 2, 3, 5] |
21 |
| -y2 = [0, 4, 2, 6, 8] |
22 |
| -y3 = [1, 3, 5, 7, 9] |
| 38 | +plt.show() |
23 | 39 |
|
24 |
| -y = np.vstack([y1, y2, y3]) |
| 40 | +############################################################################## |
| 41 | +# Streamgraphs |
| 42 | +# ------------ |
| 43 | +# |
| 44 | +# Using the *baseline* parameter, you can turn an ordinary stacked area plot |
| 45 | +# with baseline 0 into a stream graph. |
25 | 46 |
|
26 |
| -labels = ["Fibonacci ", "Evens", "Odds"] |
27 | 47 |
|
28 |
| -fig, ax = plt.subplots() |
29 |
| -ax.stackplot(x, y1, y2, y3, labels=labels) |
30 |
| -ax.legend(loc='upper left') |
31 |
| -plt.show() |
| 48 | +# Fixing random state for reproducibility |
| 49 | +np.random.seed(19680801) |
32 | 50 |
|
33 |
| -fig, ax = plt.subplots() |
34 |
| -ax.stackplot(x, y) |
35 |
| -plt.show() |
36 | 51 |
|
37 |
| -############################################################################### |
38 |
| -# Here we show an example of making a streamgraph using stackplot |
39 |
| - |
40 |
| - |
41 |
| -def layers(n, m): |
42 |
| - """ |
43 |
| - Return *n* random Gaussian mixtures, each of length *m*. |
44 |
| - """ |
45 |
| - def bump(a): |
46 |
| - x = 1 / (.1 + np.random.random()) |
47 |
| - y = 2 * np.random.random() - .5 |
48 |
| - z = 10 / (.1 + np.random.random()) |
49 |
| - for i in range(m): |
50 |
| - w = (i / m - y) * z |
51 |
| - a[i] += x * np.exp(-w * w) |
52 |
| - a = np.zeros((m, n)) |
53 |
| - for i in range(n): |
54 |
| - for j in range(5): |
55 |
| - bump(a[:, i]) |
| 52 | +def gaussian_mixture(x, n=5): |
| 53 | + """Return a random mixture of *n* Gaussians, evaluated at positions *x*.""" |
| 54 | + def add_random_gaussian(a): |
| 55 | + amplitude = 1 / (.1 + np.random.random()) |
| 56 | + dx = x[-1] - x[0] |
| 57 | + x0 = (2 * np.random.random() - .5) * dx |
| 58 | + z = 10 / (.1 + np.random.random()) / dx |
| 59 | + a += amplitude * np.exp(-(z * (x - x0))**2) |
| 60 | + a = np.zeros_like(x) |
| 61 | + for j in range(n): |
| 62 | + add_random_gaussian(a) |
56 | 63 | return a
|
57 | 64 |
|
58 | 65 |
|
59 |
| -d = layers(3, 100) |
| 66 | +x = np.linspace(0, 100, 101) |
| 67 | +ys = [gaussian_mixture(x) for _ in range(3)] |
60 | 68 |
|
61 | 69 | fig, ax = plt.subplots()
|
62 |
| -ax.stackplot(range(100), d.T, baseline='wiggle') |
| 70 | +ax.stackplot(x, ys, baseline='wiggle') |
63 | 71 | plt.show()
|
0 commit comments