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

Skip to content

Commit 59deb80

Browse files
committed
Merge branch 'trisurf' of https://github.com/dmcdougall/matplotlib into dmcdouggall-trisurf
Conflicts: CHANGELOG
2 parents 6fce428 + c34e2de commit 59deb80

3 files changed

Lines changed: 124 additions & 0 deletions

File tree

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
2012-02-29 errorevery keyword added to errorbar to enable errorbar
22
subsampling. fixes issue #600.
33

4+
2012-02-28 Added plot_trisurf to the mplot3d toolkit. This supports plotting
5+
three dimensional surfaces on an irregular grid. - Damon McDougall
6+
47
2012-01-23 The radius labels in polar plots no longer use a fixed
58
padding, but use a different alignment depending on the
69
quadrant they are in. This fixes numerical problems when

examples/mplot3d/trisurf3d_demo.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from mpl_toolkits.mplot3d import Axes3D
2+
from matplotlib import cm
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
6+
n_angles = 36
7+
n_radii = 8
8+
9+
# An array of radii
10+
# Does not include radius r=0, this is to eliminate duplicate points
11+
radii = np.linspace(0.125, 1.0, n_radii)
12+
13+
# An array of angles
14+
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
15+
16+
# Repeat all angles for each radius
17+
angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1)
18+
19+
# Convert polar (radii, angles) coords to cartesian (x, y) coords
20+
# (0, 0) is added here. There are no duplicate points in the (x, y) plane
21+
x = np.append(0, (radii*np.cos(angles)).flatten())
22+
y = np.append(0, (radii*np.sin(angles)).flatten())
23+
24+
# Pringle surface
25+
z = np.sin(-x*y)
26+
27+
fig = plt.figure()
28+
ax = fig.gca(projection='3d')
29+
30+
ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2)
31+
32+
plt.show()

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import matplotlib.collections as mcoll
2020
from matplotlib import docstring
2121
import matplotlib.scale as mscale
22+
from matplotlib.tri.triangulation import Triangulation
2223
import numpy as np
2324
from matplotlib.colors import Normalize, colorConverter, LightSource
2425

@@ -1570,6 +1571,94 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
15701571

15711572
return linec
15721573

1574+
def plot_trisurf(self, X, Y, Z, *args, **kwargs):
1575+
'''
1576+
============= ================================================
1577+
Argument Description
1578+
============= ================================================
1579+
*X*, *Y*, *Z* Data values as 1D arrays
1580+
*color* Color of the surface patches
1581+
*cmap* A colormap for the surface patches.
1582+
*norm* An instance of Normalize to map values to colors
1583+
*vmin* Minimum value to map
1584+
*vmax* Maximum value to map
1585+
*shade* Whether to shade the facecolors
1586+
============= ================================================
1587+
1588+
Other arguments are passed on to
1589+
:class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
1590+
'''
1591+
1592+
had_data = self.has_data()
1593+
1594+
# TODO: Support custom face colours
1595+
color = np.array(colorConverter.to_rgba(kwargs.pop('color', 'b')))
1596+
1597+
cmap = kwargs.get('cmap', None)
1598+
norm = kwargs.pop('norm', None)
1599+
vmin = kwargs.pop('vmin', None)
1600+
vmax = kwargs.pop('vmax', None)
1601+
linewidth = kwargs.get('linewidth', None)
1602+
shade = kwargs.pop('shade', cmap is None)
1603+
lightsource = kwargs.pop('lightsource', None)
1604+
1605+
# TODO: Support masked triangulations
1606+
tri = Triangulation(X, Y)
1607+
x = tri.x
1608+
y = tri.y
1609+
triangles = tri.triangles
1610+
1611+
xt = x[triangles][...,np.newaxis]
1612+
yt = y[triangles][...,np.newaxis]
1613+
zt = np.array(Z)[triangles][...,np.newaxis]
1614+
1615+
verts = np.concatenate((xt, yt, zt), axis=2)
1616+
1617+
# Only need these vectors to shade if there is no cmap
1618+
if cmap is None and shade:
1619+
totpts = len(verts)
1620+
v1 = np.empty((totpts, 3))
1621+
v2 = np.empty((totpts, 3))
1622+
# This indexes the vertex points
1623+
which_pt = 0
1624+
1625+
colset = []
1626+
for i in xrange(len(verts)):
1627+
avgzsum = verts[i,0,2] + verts[i,1,2] + verts[i,2,2]
1628+
colset.append(avgzsum / 3.0)
1629+
1630+
# Only need vectors to shade if no cmap
1631+
if cmap is None and shade:
1632+
v1[which_pt] = np.array(verts[i,0]) - np.array(verts[i,1])
1633+
v2[which_pt] = np.array(verts[i,1]) - np.array(verts[i,2])
1634+
which_pt += 1
1635+
1636+
if cmap is None and shade:
1637+
normals = np.cross(v1, v2)
1638+
else:
1639+
normals = []
1640+
1641+
polyc = art3d.Poly3DCollection(verts, *args, **kwargs)
1642+
1643+
if cmap:
1644+
colset = np.array(colset)
1645+
polyc.set_array(colset)
1646+
if vmin is not None or vmax is not None:
1647+
polyc.set_clim(vmin, vmax)
1648+
if norm is not None:
1649+
polyc.set_norm(norm)
1650+
else:
1651+
if shade:
1652+
colset = self._shade_colors(color, normals)
1653+
else:
1654+
colset = color
1655+
polyc.set_facecolors(colset)
1656+
1657+
self.add_collection(polyc)
1658+
self.auto_scale_xyz(X, Y, Z, had_data)
1659+
1660+
return polyc
1661+
15731662
def _3d_extend_contour(self, cset, stride=5):
15741663
'''
15751664
Extend a contour in 3D by creating

0 commit comments

Comments
 (0)