Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5185368

Browse files
committed
Merge pull request #1299 from dmcdougall/update_3dtricontour
Update Axes3D.tricontour for custom triangulations
2 parents d81498f + 05ea24b commit 5185368

5 files changed

Lines changed: 124 additions & 10 deletions

File tree

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@
7474

7575
2013-04-16 Added patheffect support for Line2D objects. -JJL
7676

77+
2013-03-31 Added support for arbitrary unstructured user-specified
78+
triangulations to Axes3D.tricontour[f] - Damon McDougall
79+
7780
2013-03-19 Added support for passing `linestyle` kwarg to `step` so all `plot`
7881
kwargs are passed to the underlying `plot` call. -TAC
7982

doc/users/whats_new.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,15 @@ to modify each artist's sketch parameters individually with
250250

251251
.. plot:: mpl_examples/showcase/xkcd.py
252252

253+
Updated Axes3D.contour methods
254+
------------------------------
255+
Damon McDougall updated the
256+
:meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.tricontour` and
257+
:meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.tricontourf` methods to allow 3D
258+
contour plots on abitrary unstructured user-specified triangulations.
259+
260+
.. plot:: mpl_examples/mplot3d/tricontour3d_demo.py
261+
253262
New eventplot plot type
254263
```````````````````````
255264
Todd Jennings added a :func:`~matplotlib.pyplot.eventplot` function to
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Contour plots of unstructured triangular grids.
3+
"""
4+
import matplotlib.pyplot as plt
5+
from mpl_toolkits.mplot3d import Axes3D
6+
import matplotlib.tri as tri
7+
import numpy as np
8+
import math
9+
10+
# First create the x and y coordinates of the points.
11+
n_angles = 48
12+
n_radii = 8
13+
min_radius = 0.25
14+
radii = np.linspace(min_radius, 0.95, n_radii)
15+
16+
angles = np.linspace(0, 2*math.pi, n_angles, endpoint=False)
17+
angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1)
18+
angles[:,1::2] += math.pi/n_angles
19+
20+
x = (radii*np.cos(angles)).flatten()
21+
y = (radii*np.sin(angles)).flatten()
22+
z = (np.cos(radii)*np.cos(angles*3.0)).flatten()
23+
24+
# Create a custom triangulation
25+
triang = tri.Triangulation(x, y)
26+
27+
# Mask off unwanted triangles.
28+
xmid = x[triang.triangles].mean(axis=1)
29+
ymid = y[triang.triangles].mean(axis=1)
30+
mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)
31+
triang.set_mask(mask)
32+
33+
plt.figure()
34+
plt.gca(projection='3d')
35+
plt.tricontour(triang, z)
36+
plt.show()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Contour plots of unstructured triangular grids.
3+
"""
4+
import matplotlib.pyplot as plt
5+
from mpl_toolkits.mplot3d import Axes3D
6+
import matplotlib.tri as tri
7+
import numpy as np
8+
import math
9+
10+
# First create the x and y coordinates of the points.
11+
n_angles = 48
12+
n_radii = 8
13+
min_radius = 0.25
14+
radii = np.linspace(min_radius, 0.95, n_radii)
15+
16+
angles = np.linspace(0, 2*math.pi, n_angles, endpoint=False)
17+
angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1)
18+
angles[:,1::2] += math.pi/n_angles
19+
20+
x = (radii*np.cos(angles)).flatten()
21+
y = (radii*np.sin(angles)).flatten()
22+
z = (np.cos(radii)*np.cos(angles*3.0)).flatten()
23+
24+
# Create a custom triangulation
25+
triang = tri.Triangulation(x, y)
26+
27+
# Mask off unwanted triangles.
28+
xmid = x[triang.triangles].mean(axis=1)
29+
ymid = y[triang.triangles].mean(axis=1)
30+
mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)
31+
triang.set_mask(mask)
32+
33+
plt.figure()
34+
plt.gca(projection='3d')
35+
plt.tricontourf(triang, z)
36+
plt.show()

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,8 +1985,8 @@ def contour(self, X, Y, Z, *args, **kwargs):
19851985

19861986
contour3D = contour
19871987

1988-
def tricontour(self, X, Y, Z, *args, **kwargs):
1989-
'''
1988+
def tricontour(self, *args, **kwargs):
1989+
"""
19901990
Create a 3D contour plot.
19911991
19921992
========== ================================================
@@ -2006,8 +2006,12 @@ def tricontour(self, X, Y, Z, *args, **kwargs):
20062006
20072007
Returns a :class:`~matplotlib.axes.Axes.contour`
20082008
2009-
.. versionadded:: 1.1.0
2010-
'''
2009+
.. versionchanged:: 1.3.0
2010+
Added support for custom triangulations
2011+
2012+
EXPERIMENTAL: This method currently produces incorrect output due to a
2013+
longstanding bug in 3D PolyCollection rendering.
2014+
"""
20112015

20122016
extend3d = kwargs.pop('extend3d', False)
20132017
stride = kwargs.pop('stride', 5)
@@ -2016,8 +2020,19 @@ def tricontour(self, X, Y, Z, *args, **kwargs):
20162020

20172021
had_data = self.has_data()
20182022

2023+
tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
2024+
*args, **kwargs)
2025+
X = tri.x
2026+
Y = tri.y
2027+
Z = args[0]
2028+
2029+
# We do this so Z doesn't get passed as an arg to Axes.tricontour
2030+
args = args[1:]
2031+
20192032
jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
2020-
cset = Axes.tricontour(self, jX, jY, jZ, *args, **kwargs)
2033+
tri = Triangulation(jX, jY, tri.triangles, tri.mask)
2034+
2035+
cset = Axes.tricontour(self, tri, jZ, *args, **kwargs)
20212036
self.add_contour_set(cset, extend3d, stride, zdir, offset)
20222037

20232038
self.auto_scale_xyz(X, Y, Z, had_data)
@@ -2060,8 +2075,8 @@ def contourf(self, X, Y, Z, *args, **kwargs):
20602075

20612076
contourf3D = contourf
20622077

2063-
def tricontourf(self, X, Y, Z, offset=None, zdir='z', *args, **kwargs):
2064-
'''
2078+
def tricontourf(self, *args, **kwargs):
2079+
"""
20652080
Create a 3D contourf plot.
20662081
20672082
========== ================================================
@@ -2079,15 +2094,30 @@ def tricontourf(self, X, Y, Z, offset=None, zdir='z', *args, **kwargs):
20792094
20802095
Returns a :class:`~matplotlib.axes.Axes.contour`
20812096
2082-
.. versionadded :: 1.1.0
2083-
'''
2097+
.. versionchanged :: 1.3.0
2098+
Added support for custom triangulations
2099+
2100+
EXPERIMENTAL: This method currently produces incorrect output due to a
2101+
longstanding bug in 3D PolyCollection rendering.
2102+
"""
20842103
zdir = kwargs.pop('zdir', 'z')
20852104
offset = kwargs.pop('offset', None)
20862105

20872106
had_data = self.has_data()
20882107

2108+
tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
2109+
*args, **kwargs)
2110+
X = tri.x
2111+
Y = tri.y
2112+
Z = args[0]
2113+
2114+
# We do this so Z doesn't get passed as an arg to Axes.tricontour
2115+
args = args[1:]
2116+
20892117
jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
2090-
cset = Axes.tricontourf(self, X, Y, Z, *args, **kwargs)
2118+
tri = Triangulation(jX, jY, tri.triangles, tri.mask)
2119+
2120+
cset = Axes.tricontourf(self, tri, jZ, *args, **kwargs)
20912121
self.add_contourf_set(cset, zdir, offset)
20922122

20932123
self.auto_scale_xyz(X, Y, Z, had_data)

0 commit comments

Comments
 (0)