|
| 1 | +""" |
| 2 | +=============== |
| 3 | +Tricontour Demo |
| 4 | +=============== |
| 5 | +
|
| 6 | +Contour plots of unstructured triangular grids. |
| 7 | +""" |
| 8 | +import matplotlib.pyplot as plt |
| 9 | +import matplotlib.tri as tri |
| 10 | +import numpy as np |
| 11 | + |
| 12 | +############################################################################### |
| 13 | +# Creating a Triangulation without specifying the triangles results in the |
| 14 | +# Delaunay triangulation of the points. |
| 15 | + |
| 16 | +# First create the x and y coordinates of the points. |
| 17 | +n_angles = 48 |
| 18 | +n_radii = 8 |
| 19 | +min_radius = 0.25 |
| 20 | +radii = np.linspace(min_radius, 0.95, n_radii) |
| 21 | + |
| 22 | +angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False) |
| 23 | +angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) |
| 24 | +angles[:, 1::2] += np.pi / n_angles |
| 25 | + |
| 26 | +x = (radii * np.cos(angles)).flatten() |
| 27 | +y = (radii * np.sin(angles)).flatten() |
| 28 | +z = (np.cos(radii) * np.cos(3 * angles)).flatten() |
| 29 | + |
| 30 | +# Create the Triangulation; no triangles so Delaunay triangulation created. |
| 31 | +triang = tri.Triangulation(x, y) |
| 32 | + |
| 33 | +# Mask off unwanted triangles. |
| 34 | +triang.set_mask(np.hypot(x[triang.triangles].mean(axis=1), |
| 35 | + y[triang.triangles].mean(axis=1)) |
| 36 | + < min_radius) |
| 37 | + |
| 38 | +############################################################################### |
| 39 | +# pcolor plot. |
| 40 | + |
| 41 | +fig1, ax1 = plt.subplots() |
| 42 | +ax1.set_aspect('equal') |
| 43 | +tcf = ax1.tricontourf(triang, z) |
| 44 | +fig1.colorbar(tcf) |
| 45 | +ax1.tricontour(triang, z, colors='k') |
| 46 | +ax1.set_title('Contour plot of Delaunay triangulation') |
| 47 | + |
| 48 | + |
| 49 | +############################################################################### |
| 50 | +# You could also specify hatching patterns along with different cmaps. |
| 51 | + |
| 52 | +fig2, ax2 = plt.subplots() |
| 53 | +ax2.set_aspect("equal") |
| 54 | +tcf = ax2.tricontourf( |
| 55 | + triang, |
| 56 | + z, |
| 57 | + hatches=["*", "-", "/", "//", "\\", None], |
| 58 | + cmap="cividis" |
| 59 | +) |
| 60 | +fig2.colorbar(tcf) |
| 61 | +ax2.tricontour(triang, z, linestyles="solid", colors="k", linewidths=2.0) |
| 62 | +ax2.set_title("Hatched Contour plot of Delaunay triangulation") |
| 63 | + |
| 64 | +############################################################################### |
| 65 | +# You could also generate hatching patterns labeled with no color. |
| 66 | + |
| 67 | +fig3, ax3 = plt.subplots() |
| 68 | +n_levels = 7 |
| 69 | +tcf = ax3.tricontourf( |
| 70 | + triang, |
| 71 | + z, |
| 72 | + n_levels, |
| 73 | + colors="none", |
| 74 | + hatches=[".", "/", "\\", None, "\\\\", "*"], |
| 75 | +) |
| 76 | +ax3.tricontour(triang, z, n_levels, colors="black", linestyles="-") |
| 77 | + |
| 78 | + |
| 79 | +# create a legend for the contour set |
| 80 | +artists, labels = tcf.legend_elements(str_format="{:2.1f}".format) |
| 81 | +ax3.legend(artists, labels, handleheight=2, framealpha=1) |
| 82 | + |
| 83 | +############################################################################### |
| 84 | +# You can specify your own triangulation rather than perform a Delaunay |
| 85 | +# triangulation of the points, where each triangle is given by the indices of |
| 86 | +# the three points that make up the triangle, ordered in either a clockwise or |
| 87 | +# anticlockwise manner. |
| 88 | + |
| 89 | +xy = np.asarray([ |
| 90 | + [-0.101, 0.872], [-0.080, 0.883], [-0.069, 0.888], [-0.054, 0.890], |
| 91 | + [-0.045, 0.897], [-0.057, 0.895], [-0.073, 0.900], [-0.087, 0.898], |
| 92 | + [-0.090, 0.904], [-0.069, 0.907], [-0.069, 0.921], [-0.080, 0.919], |
| 93 | + [-0.073, 0.928], [-0.052, 0.930], [-0.048, 0.942], [-0.062, 0.949], |
| 94 | + [-0.054, 0.958], [-0.069, 0.954], [-0.087, 0.952], [-0.087, 0.959], |
| 95 | + [-0.080, 0.966], [-0.085, 0.973], [-0.087, 0.965], [-0.097, 0.965], |
| 96 | + [-0.097, 0.975], [-0.092, 0.984], [-0.101, 0.980], [-0.108, 0.980], |
| 97 | + [-0.104, 0.987], [-0.102, 0.993], [-0.115, 1.001], [-0.099, 0.996], |
| 98 | + [-0.101, 1.007], [-0.090, 1.010], [-0.087, 1.021], [-0.069, 1.021], |
| 99 | + [-0.052, 1.022], [-0.052, 1.017], [-0.069, 1.010], [-0.064, 1.005], |
| 100 | + [-0.048, 1.005], [-0.031, 1.005], [-0.031, 0.996], [-0.040, 0.987], |
| 101 | + [-0.045, 0.980], [-0.052, 0.975], [-0.040, 0.973], [-0.026, 0.968], |
| 102 | + [-0.020, 0.954], [-0.006, 0.947], [ 0.003, 0.935], [ 0.006, 0.926], |
| 103 | + [ 0.005, 0.921], [ 0.022, 0.923], [ 0.033, 0.912], [ 0.029, 0.905], |
| 104 | + [ 0.017, 0.900], [ 0.012, 0.895], [ 0.027, 0.893], [ 0.019, 0.886], |
| 105 | + [ 0.001, 0.883], [-0.012, 0.884], [-0.029, 0.883], [-0.038, 0.879], |
| 106 | + [-0.057, 0.881], [-0.062, 0.876], [-0.078, 0.876], [-0.087, 0.872], |
| 107 | + [-0.030, 0.907], [-0.007, 0.905], [-0.057, 0.916], [-0.025, 0.933], |
| 108 | + [-0.077, 0.990], [-0.059, 0.993]]) |
| 109 | +x = np.degrees(xy[:, 0]) |
| 110 | +y = np.degrees(xy[:, 1]) |
| 111 | +x0 = -5 |
| 112 | +y0 = 52 |
| 113 | +z = np.exp(-0.01 * ((x - x0) ** 2 + (y - y0) ** 2)) |
| 114 | + |
| 115 | +triangles = np.asarray([ |
| 116 | + [67, 66, 1], [65, 2, 66], [ 1, 66, 2], [64, 2, 65], [63, 3, 64], |
| 117 | + [60, 59, 57], [ 2, 64, 3], [ 3, 63, 4], [ 0, 67, 1], [62, 4, 63], |
| 118 | + [57, 59, 56], [59, 58, 56], [61, 60, 69], [57, 69, 60], [ 4, 62, 68], |
| 119 | + [ 6, 5, 9], [61, 68, 62], [69, 68, 61], [ 9, 5, 70], [ 6, 8, 7], |
| 120 | + [ 4, 70, 5], [ 8, 6, 9], [56, 69, 57], [69, 56, 52], [70, 10, 9], |
| 121 | + [54, 53, 55], [56, 55, 53], [68, 70, 4], [52, 56, 53], [11, 10, 12], |
| 122 | + [69, 71, 68], [68, 13, 70], [10, 70, 13], [51, 50, 52], [13, 68, 71], |
| 123 | + [52, 71, 69], [12, 10, 13], [71, 52, 50], [71, 14, 13], [50, 49, 71], |
| 124 | + [49, 48, 71], [14, 16, 15], [14, 71, 48], [17, 19, 18], [17, 20, 19], |
| 125 | + [48, 16, 14], [48, 47, 16], [47, 46, 16], [16, 46, 45], [23, 22, 24], |
| 126 | + [21, 24, 22], [17, 16, 45], [20, 17, 45], [21, 25, 24], [27, 26, 28], |
| 127 | + [20, 72, 21], [25, 21, 72], [45, 72, 20], [25, 28, 26], [44, 73, 45], |
| 128 | + [72, 45, 73], [28, 25, 29], [29, 25, 31], [43, 73, 44], [73, 43, 40], |
| 129 | + [72, 73, 39], [72, 31, 25], [42, 40, 43], [31, 30, 29], [39, 73, 40], |
| 130 | + [42, 41, 40], [72, 33, 31], [32, 31, 33], [39, 38, 72], [33, 72, 38], |
| 131 | + [33, 38, 34], [37, 35, 38], [34, 38, 35], [35, 37, 36]]) |
| 132 | + |
| 133 | +############################################################################### |
| 134 | +# Rather than create a Triangulation object, can simply pass x, y and triangles |
| 135 | +# arrays to tripcolor directly. It would be better to use a Triangulation |
| 136 | +# object if the same triangulation was to be used more than once to save |
| 137 | +# duplicated calculations. |
| 138 | + |
| 139 | +fig4, ax4 = plt.subplots() |
| 140 | +ax4.set_aspect('equal') |
| 141 | +tcf = ax4.tricontourf(x, y, triangles, z) |
| 142 | +fig4.colorbar(tcf) |
| 143 | +ax4.set_title('Contour plot of user-specified triangulation') |
| 144 | +ax4.set_xlabel('Longitude (degrees)') |
| 145 | +ax4.set_ylabel('Latitude (degrees)') |
| 146 | + |
| 147 | +plt.show() |
| 148 | + |
| 149 | +############################################################################# |
| 150 | +# |
| 151 | +# .. admonition:: References |
| 152 | +# |
| 153 | +# The use of the following functions, methods, classes and modules is shown |
| 154 | +# in this example: |
| 155 | +# |
| 156 | +# - `matplotlib.axes.Axes.tricontourf` / `matplotlib.pyplot.tricontourf` |
| 157 | +# - `matplotlib.tri.Triangulation` |
| 158 | +# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar` |
| 159 | +# - `matplotlib.axes.Axes.legend` / `matplotlib.pyplot.legend` |
| 160 | +# - `matplotlib.contour.ContourSet.legend_elements` |
0 commit comments