1""" 2========================== 3Tricontour Smooth Delaunay 4========================== 5 6Demonstrates high-resolution tricontouring of a random set of points ; 7a `matplotlib.tri.TriAnalyzer` is used to improve the plot quality. 8 9The initial data points and triangular grid for this demo are: 10 11- a set of random points is instantiated, inside [-1, 1] x [-1, 1] square 12- A Delaunay triangulation of these points is then computed, of which a 13 random subset of triangles is masked out by the user (based on 14 *init_mask_frac* parameter). This simulates invalidated data. 15 16The proposed generic procedure to obtain a high resolution contouring of such 17a data set is the following: 18 191. Compute an extended mask with a `matplotlib.tri.TriAnalyzer`, which will 20 exclude badly shaped (flat) triangles from the border of the 21 triangulation. Apply the mask to the triangulation (using set_mask). 222. Refine and interpolate the data using a 23 `matplotlib.tri.UniformTriRefiner`. 243. Plot the refined data with `~.axes.Axes.tricontour`. 25 26""" 27from matplotlib.tri import Triangulation, TriAnalyzer, UniformTriRefiner 28import matplotlib.pyplot as plt 29import matplotlib.cm as cm 30import numpy as np 31 32 33#----------------------------------------------------------------------------- 34# Analytical test function 35#----------------------------------------------------------------------------- 36def experiment_res(x, y): 37 """ An analytic function representing experiment results """ 38 x = 2. * x 39 r1 = np.sqrt((0.5 - x)**2 + (0.5 - y)**2) 40 theta1 = np.arctan2(0.5 - x, 0.5 - y) 41 r2 = np.sqrt((-x - 0.2)**2 + (-y - 0.2)**2) 42 theta2 = np.arctan2(-x - 0.2, -y - 0.2) 43 z = (4 * (np.exp((r1 / 10)**2) - 1) * 30. * np.cos(3 * theta1) + 44 (np.exp((r2 / 10)**2) - 1) * 30. * np.cos(5 * theta2) + 45 2 * (x**2 + y**2)) 46 return (np.max(z) - z) / (np.max(z) - np.min(z)) 47 48#----------------------------------------------------------------------------- 49# Generating the initial data test points and triangulation for the demo 50#----------------------------------------------------------------------------- 51# User parameters for data test points 52n_test = 200 # Number of test data points, tested from 3 to 5000 for subdiv=3 53 54subdiv = 3 # Number of recursive subdivisions of the initial mesh for smooth 55 # plots. Values >3 might result in a very high number of triangles 56 # for the refine mesh: new triangles numbering = (4**subdiv)*ntri 57 58init_mask_frac = 0.0 # Float > 0. adjusting the proportion of 59 # (invalid) initial triangles which will be masked 60 # out. Enter 0 for no mask. 61 62min_circle_ratio = .01 # Minimum circle ratio - border triangles with circle 63 # ratio below this will be masked if they touch a 64 # border. Suggested value 0.01 ; Use -1 to keep 65 # all triangles. 66 67# Random points 68random_gen = np.random.RandomState(seed=19680801) 69x_test = random_gen.uniform(-1., 1., size=n_test) 70y_test = random_gen.uniform(-1., 1., size=n_test) 71z_test = experiment_res(x_test, y_test) 72 73# meshing with Delaunay triangulation 74tri = Triangulation(x_test, y_test) 75ntri = tri.triangles.shape[0] 76 77# Some invalid data are masked out 78mask_init = np.zeros(ntri, dtype=bool) 79masked_tri = random_gen.randint(0, ntri, int(ntri * init_mask_frac)) 80mask_init[masked_tri] = True 81tri.set_mask(mask_init) 82 83 84#----------------------------------------------------------------------------- 85# Improving the triangulation before high-res plots: removing flat triangles 86#----------------------------------------------------------------------------- 87# masking badly shaped triangles at the border of the triangular mesh. 88mask = TriAnalyzer(tri).get_flat_tri_mask(min_circle_ratio) 89tri.set_mask(mask) 90 91# refining the data 92refiner = UniformTriRefiner(tri) 93tri_refi, z_test_refi = refiner.refine_field(z_test, subdiv=subdiv) 94 95# analytical 'results' for comparison 96z_expected = experiment_res(tri_refi.x, tri_refi.y) 97 98# for the demo: loading the 'flat' triangles for plot 99flat_tri = Triangulation(x_test, y_test) 100flat_tri.set_mask(~mask) 101 102 103#----------------------------------------------------------------------------- 104# Now the plots 105#----------------------------------------------------------------------------- 106# User options for plots 107plot_tri = True # plot of base triangulation 108plot_masked_tri = True # plot of excessively flat excluded triangles 109plot_refi_tri = False # plot of refined triangulation 110plot_expected = False # plot of analytical function values for comparison 111 112 113# Graphical options for tricontouring 114levels = np.arange(0., 1., 0.025) 115cmap = cm.get_cmap(name='Blues', lut=None) 116 117fig, ax = plt.subplots() 118ax.set_aspect('equal') 119ax.set_title("Filtering a Delaunay mesh\n" + 120 "(application to high-resolution tricontouring)") 121 122# 1) plot of the refined (computed) data contours: 123ax.tricontour(tri_refi, z_test_refi, levels=levels, cmap=cmap, 124 linewidths=[2.0, 0.5, 1.0, 0.5]) 125# 2) plot of the expected (analytical) data contours (dashed): 126if plot_expected: 127 ax.tricontour(tri_refi, z_expected, levels=levels, cmap=cmap, 128 linestyles='--') 129# 3) plot of the fine mesh on which interpolation was done: 130if plot_refi_tri: 131 ax.triplot(tri_refi, color='0.97') 132# 4) plot of the initial 'coarse' mesh: 133if plot_tri: 134 ax.triplot(tri, color='0.7') 135# 4) plot of the unvalidated triangles from naive Delaunay Triangulation: 136if plot_masked_tri: 137 ax.triplot(flat_tri, color='red') 138 139plt.show() 140 141############################################################################# 142# 143# ------------ 144# 145# References 146# """""""""" 147# 148# The use of the following functions, methods, classes and modules is shown 149# in this example: 150 151import matplotlib 152matplotlib.axes.Axes.tricontour 153matplotlib.pyplot.tricontour 154matplotlib.axes.Axes.tricontourf 155matplotlib.pyplot.tricontourf 156matplotlib.axes.Axes.triplot 157matplotlib.pyplot.triplot 158matplotlib.tri 159matplotlib.tri.Triangulation 160matplotlib.tri.TriAnalyzer 161matplotlib.tri.UniformTriRefiner 162