|
| 1 | +""" |
| 2 | +============================ |
| 3 | +Pcolormesh grids and shading |
| 4 | +============================ |
| 5 | +
|
| 6 | +`.axes.Axes.pcolormesh` and `~.axes.Axes.pcolor` have a few options for |
| 7 | +how grids are laid out and the shading between the grid points. |
| 8 | +
|
| 9 | +Generally, if *Z* is size *(M, N)* then the grid *X* and *Y* can be |
| 10 | +specified with either size *(M+1, N+1)* or *(M, N)*, depending on the |
| 11 | +argument for the ``shading`` keyword argument. Note that below we specify |
| 12 | +vectors *x* as either length N or N+1 and *y* as length M or M+1, and |
| 13 | +`~.axes.Axes.pcolormesh` internally makes the mesh matrices *X* and *Y* from |
| 14 | +the input vectors. |
| 15 | +
|
| 16 | +""" |
| 17 | + |
| 18 | +import matplotlib |
| 19 | +import matplotlib.pyplot as plt |
| 20 | +import numpy as np |
| 21 | + |
| 22 | +############################################################################### |
| 23 | +# Flat Shading |
| 24 | +# ------------ |
| 25 | +# |
| 26 | +# The grid specification with the least assumptions is ``shading='flat'`` |
| 27 | +# and if the grid is one larger than the data in each dimesion, i.e. has size |
| 28 | +# *(M+1, N+1)*. In that case *X* and *Y* sepcify the corners of quadrilaterals |
| 29 | +# that are colored with the values in *Z*. Here we specify the edges of the |
| 30 | +# *(3, 5)* quadrilaterals with *X* and *Y* that are *(4, 6)*. |
| 31 | + |
| 32 | +np.random.seed(19680801) |
| 33 | +Z = np.arange(15).reshape(3, 5) |
| 34 | +x = np.arange(6) # len = 6 |
| 35 | +y = np.arange(4) # len = 4 |
| 36 | + |
| 37 | +fig, ax = plt.subplots() |
| 38 | +ax.pcolormesh(x, y, Z, shading='flat', vmin=Z.min(), vmax=Z.max()) |
| 39 | + |
| 40 | + |
| 41 | +def _annote(ax, x, y, title): |
| 42 | + # this all gets repeated below: |
| 43 | + X, Y = np.meshgrid(x, y) |
| 44 | + ax.plot(X.flat, Y.flat, 'o', color='m') |
| 45 | + ax.set_xlim(-0.7, 5.2) |
| 46 | + ax.set_ylim(-0.7, 3.2) |
| 47 | + ax.set_title(title) |
| 48 | + |
| 49 | +_annote(ax, x, y, "shading='flat'") |
| 50 | + |
| 51 | + |
| 52 | +############################################################################### |
| 53 | +# Flat Shading, same size grid |
| 54 | +# ---------------------------- |
| 55 | +# |
| 56 | +# Often, however, data is provided where *X* and *Y* match the size of *Z*. |
| 57 | +# As of Matplotlib v3.3, ``shading='flat'`` is deprecated when this is the |
| 58 | +# case, a warning is raised, and the last row and column of *Z* are dropped. |
| 59 | +# This dropping of the last row and column is what Matplotlib did silently |
| 60 | +# previous to v3.3, and is compatible with what Matlab does. |
| 61 | + |
| 62 | +x = np.arange(5) # len = 5 |
| 63 | +y = np.arange(3) # len = 3 |
| 64 | + |
| 65 | +fig, ax = plt.subplots() |
| 66 | +ax.pcolormesh(x, y, Z, shading='flat', vmin=Z.min(), vmax=Z.max()) |
| 67 | +_annote(ax, x, y, "shading='flat': X, Y, C same size") |
| 68 | + |
| 69 | +############################################################################### |
| 70 | +# Nearest Shading, same size grid |
| 71 | +# ------------------------------- |
| 72 | +# |
| 73 | +# Usually, dropping a row and column of data is not what the user means when |
| 74 | +# the make *X*, *Y* and *Z* all the same size. For this case, Matplotlib |
| 75 | +# allows ``shading='nearest'`` and centers the colored qudrilaterals on the |
| 76 | +# grid points. |
| 77 | +# |
| 78 | +# If a grid that is not the correct size is passed with ``shading='nearest'`` |
| 79 | +# an error is raised. |
| 80 | + |
| 81 | +fig, ax = plt.subplots() |
| 82 | +ax.pcolormesh(x, y, Z, shading='nearest', vmin=Z.min(), vmax=Z.max()) |
| 83 | +_annote(ax, x, y, "shading='nearest'") |
| 84 | + |
| 85 | +############################################################################### |
| 86 | +# Auto Shading |
| 87 | +# ------------ |
| 88 | +# |
| 89 | +# Its possible that the user would like the code to automatically choose |
| 90 | +# which to use, in which case ``shading='auto'`` will decide whether to |
| 91 | +# use 'flat' or 'nearest' shading based on the sizes of *X*, *Y* and *Z*. |
| 92 | + |
| 93 | +fig, axs = plt.subplots(2, 1, constrained_layout=True) |
| 94 | +ax = axs[0] |
| 95 | +x = np.arange(5) # len = 5 |
| 96 | +y = np.arange(3) # len = 3 |
| 97 | +ax.pcolormesh(x, y, Z, shading='auto', vmin=Z.min(), vmax=Z.max()) |
| 98 | +_annote(ax, x, y, "shading='auto'; X, Y, Z: same size (nearest)") |
| 99 | + |
| 100 | +ax = axs[1] |
| 101 | +x = np.arange(6) # len = 5 |
| 102 | +y = np.arange(4) # len = 3 |
| 103 | +ax.pcolormesh(x, y, Z, shading='auto', vmin=Z.min(), vmax=Z.max()) |
| 104 | +_annote(ax, x, y, "shading='auto'; X, Y one larger than Z (flat)") |
| 105 | + |
| 106 | +############################################################################### |
| 107 | +# Gouraud Shading |
| 108 | +# --------------- |
| 109 | +# |
| 110 | +# `Gouraud shading <https://en.wikipedia.org/wiki/Gouraud_shading>`_ can also |
| 111 | +# be specified, where the colour in the quadrilaterals is linearly |
| 112 | +# interpolated between the grid points. The sizes of *X*, *Y*, *Z* must |
| 113 | +# be the same. |
| 114 | + |
| 115 | +fig, ax = plt.subplots(constrained_layout=True) |
| 116 | +x = np.arange(5) # len = 5 |
| 117 | +y = np.arange(3) # len = 3 |
| 118 | +ax.pcolormesh(x, y, Z, shading='gouraud', vmin=Z.min(), vmax=Z.max()) |
| 119 | +_annote(ax, x, y, "shading='gouruad'; X, Y same size as Z") |
| 120 | + |
| 121 | +plt.show() |
| 122 | +############################################################################# |
| 123 | +# |
| 124 | +# ------------ |
| 125 | +# |
| 126 | +# References |
| 127 | +# """""""""" |
| 128 | +# |
| 129 | +# The use of the following functions and methods is shown in this example: |
| 130 | + |
| 131 | +matplotlib.axes.Axes.pcolormesh |
| 132 | +matplotlib.pyplot.pcolormesh |
0 commit comments