Skip to content

Commit fa99afc

Browse files
committed
[plot] bump version to 0.3.0, fix colormap handling in plotmesh
1 parent b6c4f92 commit fa99afc

File tree

4 files changed

+49
-42
lines changed

4 files changed

+49
-42
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
* Copyright: (C) Qianqian Fang (2024-2025) <q.fang at neu.edu>, Edward Xu (2024) <xu.ed at northeastern.edu>
66
* License: GNU Public License V3 or later
7-
* Version: 0.2.4
7+
* Version: 0.3.0
88
* URL: [https://pypi.org/project/iso2mesh/](https://pypi.org/project/iso2mesh/)
99
* Github: [https://github.com/NeuroJSON/pyiso2mesh](https://github.com/NeuroJSON/pyiso2mesh)
1010

@@ -44,6 +44,8 @@ python3 -m pip install iso2mesh
4444
* **numpy**: `pyiso2mesh` relies heavily on vectorized NumPy
4545
matrix operations, similar to those used in the MATLAB version of Iso2Mesh.
4646
* **matplotlib**: Used for plotting results. Install with `pip install matplotlib`.
47+
* **jdata** (optional): A lightweight module to load JSON-encoded volume/mesh data,
48+
including dynamically downloading data from [NeuroJSON.io](https://neurojson.io) `pip install jdata`.
4749

4850
Many core meshing functions in `pyiso2mesh` require the set of mesh processing
4951
executables provided in the Iso2Mesh package under the `iso2mesh/bin` folder.
@@ -137,7 +139,7 @@ i2m.plotmesh(no2, fc1)
137139

138140
# meshing a cylinder
139141
no, fc, el = i2m.meshacylinder([0,0,0], [0, 0, 10], 2, 50)
140-
i2m.plotmesh(no, el, 'x < 0', shade=False, edgecolor='r')
142+
i2m.plotmesh(no, el, 'x < 0', edgecolor='r')
141143

142144
# creating and plotting polyhedral solids (PLCs)
143145
mesh = i2m.latticegrid([0,1],[0,1,2], [0,2])

iso2mesh/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
barycentricgrid,
138138
)
139139

140-
__version__ = "0.2.4"
140+
__version__ = "0.3.0"
141141
__all__ = [
142142
"advancefront",
143143
"barycentricgrid",

iso2mesh/plot.py

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
def plotsurf(node, face, *args, **kwargs):
2727
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
28+
from matplotlib.colors import Normalize
2829

2930
rngstate = np.random.get_state()
3031
h = []
@@ -43,9 +44,14 @@ def plotsurf(node, face, *args, **kwargs):
4344
plt.figure() # Create a new figure
4445
ax = plt.gcf().add_subplot(projection="3d") # Add 3D axes to the current figure
4546

47+
if not "color" in kwargs and not "cmap" in kwargs:
48+
kwargs["cmap"] = plt.get_cmap("jet")
49+
4650
if isinstance(face, list): # polyhedral facets
4751

4852
newsurf = {}
53+
colormap = []
54+
4955
for fc in face:
5056
if (
5157
isinstance(fc, (list, tuple))
@@ -64,7 +70,21 @@ def plotsurf(node, face, *args, **kwargs):
6470
for subface in newsurf.values()
6571
for subf in subface
6672
]
67-
colormap = [sc[i - 1, :] for i, subface in newsurf.items() for subf in subface]
73+
if node.shape[1] > 3:
74+
node_values = node[:, 3]
75+
face_values = np.array(
76+
[
77+
np.mean(node_values[np.array(subf).flatten()])
78+
for subface in newsurf.values()
79+
for subf in subface
80+
]
81+
)
82+
norm = Normalize(vmin=face_values.min(), vmax=face_values.max())
83+
colormap = kwargs["cmap"](norm(face_values))
84+
else:
85+
colormap = [
86+
sc[i - 1, :] for i, subface in newsurf.items() for subf in subface
87+
]
6888

6989
elif face.shape[1] == 2:
7090
h = plotedges(node, face, *args, **kwargs)
@@ -90,27 +110,17 @@ def plotsurf(node, face, *args, **kwargs):
90110
else:
91111
polydata, colormap = plotasurf(node, face, *args, **kwargs)
92112

93-
if node.shape[1] > 3 and not "color" in kwargs and not "facecolors" in kwargs:
94-
colormap = []
95-
maxval = np.max(node[:, 3])
96-
minval = np.min(node[:, 3])
97-
98-
for tri in polydata:
99-
val = node[tri, 3]
100-
val = np.mean(val)
101-
face_color = kwargs["cmap"](
102-
(val - minval) / (maxval - minval)
103-
) # Normalize for colormap
104-
colormap.append(face_color)
105-
106113
if "colormap" in locals() and len(colormap) > 0 and not "facecolors" in kwargs:
107114
kwargs["facecolors"] = colormap
108-
print(len(colormap))
109115

110-
if not "color" in kwargs and not "cmap" in kwargs:
111-
kwargs["cmap"] = plt.get_cmap("jet")
116+
if "cmap" in kwargs and not "facecolors" in kwargs:
117+
node_values = node[:, 3] if node.shape[1] > 3 else node[:, 2]
118+
face_values = np.array([np.mean(node_values[f]) for f in face[:, :3] - 1])
119+
norm = Normalize(vmin=face_values.min(), vmax=face_values.max())
120+
kwargs["facecolors"] = kwargs["cmap"](norm(face_values))
112121

113122
patch = Poly3DCollection(polydata, edgecolors="k", **kwargs)
123+
114124
ax.add_collection3d(patch)
115125
_autoscale_3d(ax, node)
116126
h.append(patch)
@@ -125,23 +135,13 @@ def plotsurf(node, face, *args, **kwargs):
125135

126136

127137
def plotasurf(node, face, *args, **kwargs):
128-
poly3d = [[node[i, :3] for i in p] for p in face[:, :3] - 1]
129-
colmap = []
130-
if node.shape[1] > 3 and not "color" in kwargs and not "facecolors" in kwargs:
131-
maxval = np.max(node[:, 3])
132-
minval = np.min(node[:, 3])
133-
134-
for tri in face:
135-
val = node[tri, 3]
136-
val = np.mean(val)
137-
face_color = kwargs["cmap"](
138-
(val - minval) / (maxval - minval)
139-
) # Normalize for colormap
140-
colmap.append(face_color)
141-
142-
if not "facecolors" in kwargs:
143-
kwargs["facecolors"] = colmap
138+
from matplotlib.colors import Normalize
144139

140+
poly3d = [[node[i, :3] for i in p] for p in face[:, :3] - 1]
141+
node_values = node[:, 3] if node.shape[1] > 3 else node[:, 2]
142+
face_values = np.array([np.mean(node_values[f]) for f in face[:, :3] - 1])
143+
norm = Normalize(vmin=face_values.min(), vmax=face_values.max())
144+
colmap = kwargs["cmap"](norm(face_values))
145145
return poly3d, colmap
146146

147147

@@ -164,6 +164,7 @@ def plottetra(node, elem, *args, **kwargs):
164164
"""
165165

166166
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
167+
from matplotlib.colors import Normalize
167168

168169
# Save current RNG state
169170
rngstate = np.random.get_state()
@@ -182,6 +183,9 @@ def plottetra(node, elem, *args, **kwargs):
182183
plt.figure() # Create a new figure
183184
ax = plt.gcf().add_subplot(projection="3d") # Add 3D axes to the current figure
184185

186+
if not "color" in kwargs and not "cmap" in kwargs:
187+
kwargs["cmap"] = plt.get_cmap("jet")
188+
185189
h = []
186190
polydata = []
187191
colormap = []
@@ -205,14 +209,15 @@ def plottetra(node, elem, *args, **kwargs):
205209
if "colormap" in locals() and len(colormap) > 0 and not "facecolors" in kwargs:
206210
kwargs["facecolors"] = colormap
207211

208-
if not "color" in kwargs and not "cmap" in kwargs:
209-
kwargs["cmap"] = plt.get_cmap("jet")
210-
print("set cmap to jet")
211-
212-
print(kwargs.keys())
212+
if "cmap" in kwargs and not "facecolors" in kwargs:
213+
node_values = node[:, 3] if node.shape[1] > 3 else node[:, 2]
214+
face_values = np.array([np.mean(node_values[f]) for f in elem[:, :4] - 1])
215+
norm = Normalize(vmin=face_values.min(), vmax=face_values.max())
216+
kwargs["facecolors"] = kwargs["cmap"](norm(face_values))
213217

214218
patch = Poly3DCollection(polydata, edgecolors="k", **kwargs)
215219
ax.add_collection3d(patch)
220+
216221
_autoscale_3d(ax, node)
217222
h.append(patch)
218223

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
setup(
77
name="iso2mesh",
88
packages=["iso2mesh"],
9-
version="0.2.4",
9+
version="0.3.0",
1010
license='GPLv3+',
1111
description="Image-based 3D Surface and Volumetric Mesh Generator",
1212
long_description=readme,

0 commit comments

Comments
 (0)