Last active
December 10, 2020 23:10
-
-
Save joferkington/ced0d2853673d9cedb755f1c7c02084e to your computer and use it in GitHub Desktop.
Using a masked array for contour clipping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# There are two ways to clip data to irregular boundaries. | |
# One uses a masked array (and is most useful for "real" data) | |
# The other uses set_clip_path (and is most useful for graphics) | |
# This demonstrates the first (masked array) | |
import matplotlib.pyplot as plt | |
import scipy.ndimage | |
import numpy as np | |
import skimage.draw | |
np.random.seed(1977) | |
# Generate dummy data. | |
raster = 18 * np.random.random((5,5)) - 10 | |
# Smoothly interpolate to a much denser cellsize | |
raster = scipy.ndimage.zoom(raster, 100, order=3) | |
# Polygon boundary (made up)... | |
x = np.array([93.40206186, 68.1443299, 5., 138.86597938, 194.43298969, | |
323.24742268, 495., 447.01030928, 419.22680412, 399.02061856, | |
351.03092784, 262.62886598, 179.27835052, 194.43298969, | |
17.62886598, 47.93814433, 93.40206186]) | |
y = np.array([209.5296751, 168.89768023, 15.30734213, 10.15472679, 92.34232467, | |
5., 10.15472679, 153.62517763, 335.61141324, 450.40016541, | |
480.15331617, 495., 447.91714297, 345.63913876, 333.10311499, | |
247.49668342, 209.5296751]) | |
# Mask out areas outside of our polygon boundary. | |
# There are a gazillion ways to do this. Use rasterio if you're working with | |
# real geographic data. Using skimage here just to avoid geospatial libs. | |
mask = np.ones(raster.shape, dtype=bool) | |
i, j = skimage.draw.polygon(y, x) | |
mask[i, j] = False | |
raster = np.ma.masked_where(mask, raster) | |
# Now let's make a filled contour plot | |
levels = [-10, -5, -2, 2, 5, 10] | |
fig, ax = plt.subplots(constrained_layout=True) | |
im = ax.contourf(raster, levels, cmap='gist_earth') | |
ctr = ax.contour(raster, levels, colors='k', linewidths=0.8, linestyles='solid') | |
cbar = fig.colorbar(im, orientation='horizontal', aspect=5, shrink=0.5) | |
cbar.add_lines(ctr) | |
# We'll draw our border over it to hide the edges | |
ax.fill(x, y, facecolor='none', edgecolor='k', linewidth=1.5) | |
# And let's configure things to roughly match the original | |
ax.axis('off') | |
cbar.ax.tick_params(length=0) | |
cbar.ax.xaxis.tick_top() | |
ax.set(aspect=1) | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment