-
-
Save franktoffel/f79d84319f043c1d3c897f3732489460 to your computer and use it in GitHub Desktop.
''' | |
================================= | |
3D heart shape in matplotlib | |
================================= | |
Demonstrates how to plot a 3D function in cartesian coordinates. | |
Uses the marching cubes algorithm in scikit-image to obtain a isosurface. | |
Example contributed by CAChemE.org | |
Adapted from: http://www.walkingrandomly.com/?p=2326 | |
''' | |
from mpl_toolkits.mplot3d import Axes3D | |
from matplotlib import pyplot as plt | |
import numpy as np | |
from skimage import measure | |
# Set up mesh | |
n = 100 | |
x = np.linspace(-3,3,n) | |
y = np.linspace(-3,3,n) | |
z = np.linspace(-3,3,n) | |
X, Y, Z = np.meshgrid(x, y, z) | |
# Create cardioid function | |
def f_heart(x,y,z): | |
F = 320 * ((-x**2 * z**3 -9*y**2 * z**3/80) + | |
(x**2 + 9*y**2/4 + z**2-1)**3) | |
return F | |
# Obtain value to at every point in mesh | |
vol = f_heart(X,Y,Z) | |
# Extract a 2D surface mesh from a 3D volume (F=0) | |
verts, faces, normals, values = measure.marching_cubes_lewiner(vol, 0, spacing=(0.1, 0.1, 0.1)) | |
# Create a 3D figure | |
fig = plt.figure(figsize=(12,8)) | |
ax = fig.add_subplot(111, projection='3d') | |
# Plot the surface | |
ax.plot_trisurf(verts[:, 0], verts[:,1], faces, verts[:, 2], | |
cmap='Spectral', lw=1) | |
# Change the angle of view and title | |
ax.view_init(15, -15) | |
# ax.set_title(u"Made with ❤ (and Python)", fontsize=15) # if you have Python 3 | |
ax.set_title("Made with <3 (and Python)", fontsize=15) | |
# Show me some love ^^ | |
plt.show() |
franktoffel
commented
Feb 14, 2017
Hi. I tried this code but getting an error
verts, faces = measure.marching_cubes(vol, 0, spacing=(0.1, 0.1, 0.1))
ValueError: too many values to unpack (expected 2)
I tried even "marching_cubes_lewiner(vol, 0, spacing=(0.1, 0.1, 0.1))" but still the same error. Could you please help?
hi, kapooramit, this works for me.
verts, faces ,_ ,_ = measure.marching_cubes_lewiner(vol, 0, spacing=(0.1, 0.1, 0.1))
Make sure you have matplotlib (and all the libraries installed) installed.
Try the importing lines separately in your IDLE Shell.
from matplotlib import pyplot as plt
import numpy as np
from skimage import measure
Thank you so much for putting this together! It looks amazing!!! I did, however, notice one thing when running the code. It seems that skimage might have undergone some updates, so now the code in line 35 errors. This is the error message I received:
module 'skimage.measure' has no attribute 'marching_cubes'
I was able to resolve the error by changing measure.marching_cubes
to measure.marching_cubes_lewiner
, according siva's and Lucan's answer here: https://stackoverflow.com/questions/54056565/attributeerror-module-skimage-measure-has-no-attribute-marching-cubes
After this modification, the code ran successfully, and the heart rendered beautifully. Thank you so much again!