Toby Hawkins Toby Hawkins - 2 months ago 23
Python Question

Python: Plotting Evenly Spaced Spheres in Matplotlib

I'm trying to create a plot a bit like this:

enter image description here

Where there are spheres above all the minimums.

The surface can be approximated with a sin(x)*sin(y) plot:

import numpy as np
import matplotlib.pyplot as plt

def func(x, y):
return np.sin(2*np.pi*x)*np.sin(2*np.pi*y) / 3

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = y = np.arange(-1.0, 1.0, 0.05)
X, Y = np.meshgrid(x, y)
zs = np.array([func(x,y) for x,y in zip(np.ravel(X), np.ravel(Y))])
Z = zs.reshape(X.shape)

ax.plot_surface(X, Y, Z, color="grey")

However I'm unsure how to add evenly spaced spheres into this. Would anyone be able to help?

Answer Source

Using matplotlib one will inevitably run into problems of objects being hidden behind others. This is also stated in the matplotlib 3d FAQ and the recommendation is to use mayavi.

In mayavi the solution would look like this:

from mayavi import mlab
import numpy as np

### SURFACE '''
x,y = np.meshgrid(np.linspace(-2.5,2), np.linspace(-2,2))
f = lambda x,y: .4*np.sin(2*np.pi*x)*np.sin(2*np.pi*y)
z=f(x,y),y.T,z.T, colormap="copper")

### SPHERES '''
px,py = np.meshgrid(np.arange(-2,2)+.25, np.arange(-2,2)+.75)
px,py = px.flatten(),py.flatten()
pz = np.ones_like(px)*0.05
r = np.ones_like(px)*.4
mlab.points3d(px,py,pz,r, color=(0.9,0.05,.3), scale_factor=1)

enter image description here