Toby Hawkins Toby Hawkins -3 years ago 228
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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download