# Use Python to plot Surface graphs of irregular Datasets

Do you want to plot a surface graph of a 3D dataset but your data is not distributed on a regular meshgrid? No need to worry as Matplotlib’s `trisurf`

got you covered. Here is how to use it.

## First things first

Let’s add the proper libraries, shall we?

```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
from mpl_toolkits.mplot3d import Axes3D
```

## Generate the sample data

Create an irregular grid of (x,y) coordinates and the relative z-data

```
points = 500
data = np.zeros([points,3])
x = np.random.rand(points)*100
y = np.random.rand(points)*100
z = np.sinc((x-20)/100*3.14) + np.sinc((y-50)/100*3.14)
```

Plot the generated grid on a scatter graph, just to verify there is no cheating here…

```
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x, y, marker=".", c="#DC143C", edgecolors="black", s=100)
ax.set_xlabel('X')
ax.set_ylabel('Y')
plt.show()
```

Looks quite irregular to me. Let’s continue

## Triangulation

The first things to do is to use the (x,y) coordinates to subdivide the plane into a set of triangles.
The `Triangulation`

method uses the
Delaunay triangulation algorithm for the job and returns the object `triang`

`triang`

contains an unstructured triangular grid from (x,y) coordinates:

`(triang.x, triang.y)`

are the input (x,y) coordinates`triang.triangles`

is an`Array[nrOfTriangles, 3]`

in which each row indicates which 3 points from the grid were used to define each triangle.`nrOfTriangles`

depends on the dataset and the triangulation algorithm.`triang.mask`

can be used to mask out unwanted triangles

If you want to know more about the `Triangulation`

method you can check Matplotlib’s
API

```
triang = mtri.Triangulation(x, y)
```

Let’s have a look at the (x,y) coordinates and the triangles

```
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.triplot(triang, c="#D3D3D3", marker='.', markerfacecolor="#DC143C",
markeredgecolor="black", markersize=10)
ax.set_xlabel('X')
ax.set_ylabel('Y')
plt.show()
```

Depending on the dataset and the algorithm used for the triangulation, some triangles might cause artifact in the 3D surface. In case that happens, it is possible to mask out some of them. In this example we eliminate the triangles for which at least one point is outside of an arbitrary boundary

`isBad`

is an`Array[points,]`

which contains for each (x,y) coordinate a boolean value indicating whether the point is outside (`True`

) or inside (`False`

) of a boundary condition.`mask`

is an`Array[nrOfTriangles,]`

in which each boolean value indicates whether the respective triangles was defined using at least one point outside of the boundary.

```
isBad = np.where((x<1) | (x>99) | (y<1) | (y>99), True, False)
mask = np.any(isBad[triang.triangles],axis=1)
triang.set_mask(mask)
```

Let’s plot again the 2D surface with the (x,y) coordinates and the new triangles. Note how some triangles at the periphery of the plane are now missing.

```
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.triplot(triang, c="#D3D3D3", marker='.', markerfacecolor="#DC143C",
markeredgecolor="black", markersize=10)
ax.set_xlabel('X')
ax.set_ylabel('Y')
plt.show()
```

Finally let’s plot the 3D surface using `plot_trisurf`

```
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
ax.plot_trisurf(triang, z, cmap='jet')
ax.scatter(x,y,z, marker='.', s=10, c="black", alpha=0.5)
ax.view_init(elev=60, azim=-45)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
```

Sep 10, 2017