Skip to content

Commit ac81d53

Browse files
committed
Add Delaunay Triangulation Tutorial
1 parent b8062f9 commit ac81d53

5 files changed

Lines changed: 179 additions & 0 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import igraph as ig
2+
import matplotlib.pyplot as plt
3+
import random
4+
from scipy.spatial import Delaunay
5+
6+
# Generate a random geometric graph
7+
random.seed(0)
8+
g = ig.Graph.GRG(30, 0)
9+
10+
# Calculate the delaunay triangulation, and add the edges into the original graph
11+
coords = g.layout_auto().coords
12+
delaunay = Delaunay(coords)
13+
for tri in delaunay.simplices:
14+
g.add_edges([
15+
(tri[0], tri[1]),
16+
(tri[1], tri[2]),
17+
(tri[0], tri[2]),
18+
])
19+
g.simplify()
20+
21+
# Plot the graph
22+
fig, ax = plt.subplots()
23+
ig.plot(
24+
g,
25+
target=ax,
26+
vertex_size=0.04,
27+
vertex_color="lightblue",
28+
edge_width=0.8
29+
)
30+
plt.show()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import igraph as ig
2+
import matplotlib.pyplot as plt
3+
import random
4+
from scipy.spatial import Delaunay
5+
6+
# Generate a random geometric graph
7+
random.seed(0)
8+
g = ig.Graph.GRG(30, 0)
9+
10+
# Calculate the delaunay triangulation, and add the edges into the original graph
11+
coords = g.layout_auto().coords
12+
delaunay = Delaunay(coords)
13+
for tri in delaunay.simplices:
14+
g.add_edges([
15+
(tri[0], tri[1]),
16+
(tri[1], tri[2]),
17+
(tri[0], tri[2]),
18+
])
19+
g.simplify()
20+
21+
# Plot the triangles
22+
fig, ax = plt.subplots()
23+
24+
palette = ig.GradientPalette("midnightblue", "lightblue", 100)
25+
for tri in delaunay.simplices:
26+
# get the points of the triangle
27+
tri_points = [delaunay.points[tri[i]] for i in range(3)]
28+
29+
# calculate the vertical center of the triangle
30+
center = (tri_points[0][1] + tri_points[1][1] + tri_points[2][1]) / 3
31+
32+
# draw triangle onto axes
33+
poly = plt.Polygon(tri_points, color=palette.get(int(center*100)))
34+
ax.add_patch(poly)
35+
36+
# Plot the graph on top
37+
ig.plot(
38+
g,
39+
target=ax,
40+
vertex_size=0.0,
41+
edge_width=0.2,
42+
edge_color="white",
43+
)
44+
plt.show()
45+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
.. include:: ../../include/global.rst
2+
3+
.. _tutorials-delaunay-triangulation:
4+
5+
======================
6+
Delaunay Triangulation
7+
======================
8+
9+
.. _GRG: https://igraph.org/python/doc/api/igraph.Graph.html#GRG
10+
.. |GRG| replace:: :meth:`GRG`
11+
12+
This example demonstrates how to calculate the `Delaunay triangulation <https://en.wikipedia.org/wiki/Delaunay_triangulation>`_ of an input graph. We start by generating a set of points on a 2D grid using |GRG|_ with radius zero, so that there are initially no edges in the graph.
13+
14+
.. code-block:: python
15+
16+
import igraph as ig
17+
import matplotlib.pyplot as plt
18+
import random
19+
from scipy.spatial import Delaunay
20+
21+
# Generate a random geometric graph
22+
random.seed(0)
23+
g = ig.Graph.GRG(30, 0)
24+
25+
We then use `SciPy's Delaunay function <https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.Delaunay.html>`_ to generate the triangles, and then loop through them to add them back into our original graph. We make sure to simplify the graph afterwards to remove multiple edges caused by triangles sharing a side.
26+
27+
.. code-block:: python
28+
29+
# Calculate the delaunay triangulation, and add the edges into the original graph
30+
coords = g.layout_auto().coords
31+
delaunay = Delaunay(coords)
32+
for tri in delaunay.simplices:
33+
g.add_edges([
34+
(tri[0], tri[1]),
35+
(tri[1], tri[2]),
36+
(tri[0], tri[2]),
37+
])
38+
g.simplify()
39+
40+
Finally, we display the graph:
41+
42+
.. code-block:: python
43+
44+
# Plot the graph
45+
fig, ax = plt.subplots()
46+
ig.plot(
47+
g,
48+
target=ax,
49+
vertex_size=0.04,
50+
vertex_color="lightblue",
51+
edge_width=0.8
52+
)
53+
plt.show()
54+
55+
Our output looks like this:
56+
57+
.. figure:: ./figures/delaunay-triangulation.png
58+
:alt: The visual representation of a Delaunay triangulation
59+
:align: center
60+
61+
The Delaunay triangulation
62+
63+
Advanced: Improving plotting style
64+
----------------------------------
65+
Sometimes, we would like to emphasise the actual triangles generated by the Delaunay triangulation. We'll add in some triangles and color them according to their y coordinate.
66+
67+
.. code-block:: python
68+
69+
# Plot the triangles
70+
fig, ax = plt.subplots()
71+
72+
palette = ig.GradientPalette("midnightblue", "lightblue", 100)
73+
for tri in delaunay.simplices:
74+
# get the points of the triangle
75+
tri_points = [delaunay.points[tri[i]] for i in range(3)]
76+
77+
# calculate the vertical center of the triangle
78+
center = (tri_points[0][1] + tri_points[1][1] + tri_points[2][1]) / 3
79+
80+
# draw triangle onto axes
81+
poly = plt.Polygon(tri_points, color=palette.get(int(center*100)))
82+
ax.add_patch(poly)
83+
84+
We then plot the original graph edges on top:
85+
86+
.. code-block:: python
87+
88+
# Plot the graph on top
89+
ig.plot(
90+
g,
91+
target=ax,
92+
vertex_size=0.0,
93+
edge_width=0.2,
94+
edge_color="white",
95+
)
96+
plt.show()
97+
98+
The final output looks like this:
99+
100+
.. figure:: ./figures/delaunay-triangulation2.png
101+
:alt: The visual representation of a Delaunay triangulation
102+
:align: center
103+
104+
The Delaunay triangulation, with colored triangles.
55.1 KB
Loading
40.6 KB
Loading

0 commit comments

Comments
 (0)