Skip to content

Instantly share code, notes, and snippets.

@franktoffel
Last active April 20, 2026 15:58
Show Gist options
  • Select an option

  • Save franktoffel/f79d84319f043c1d3c897f3732489460 to your computer and use it in GitHub Desktop.

Select an option

Save franktoffel/f79d84319f043c1d3c897f3732489460 to your computer and use it in GitHub Desktop.
How to plot a 3D heart for San Valentin with Python (matplotlib)
'''
=================================
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()
@ChubaOraka
Copy link
Copy Markdown

ChubaOraka commented Apr 20, 2026

I think it would be beneficial to include the requirements.txt file. This is how mine looks:

contourpy==1.0.7
cycler==0.11.0
fonttools==4.39.3
imageio==2.27.0
kiwisolver==1.4.4
lazy_loader==0.2
matplotlib==3.7.1
networkx==3.1
numpy==1.24.2
packaging==23.1
Pillow==9.5.0
pyparsing==3.0.9
PyQt6==6.11.0
PyQt6-Qt6==6.11.0
PyQt6_sip==13.11.1
python-dateutil==2.8.2
PyWavelets==1.4.1
scikit-image==0.20.0
scipy==1.10.1
six==1.16.0
tifffile==2023.4.12

Also, I had to change Line 35 of python_heart.py from this:

verts, faces, normals, values = measure.marching_cubes_lewiner(vol, 0,  spacing=(0.1, 0.1, 0.1))

to this:

verts, faces, normals, values = measure.marching_cubes(vol, 0,  spacing=(0.1, 0.1, 0.1))

Here's what the Python code looks like now:

'''
=================================
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(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()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment