Reputation: 727
I'm trying to plot a sphere with a segment cut out. I think I've created the co-ordinates correctly but I find that as I pan around the sliced sphere, the inner surface disappears. What am I doing wrong? If at all relevant, this is Python 2.7.3 with Matplotlib 1.5.1 on openSUSE Leap 42.1, using backend TkAgg
.
Code:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as pl
import numpy as np
fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
phi = np.linspace(0.5*np.pi, 2.0*np.pi, 100)
theta = np.linspace(0, np.pi, 100)
x = np.outer(np.cos(phi), np.sin(theta))
y = np.outer(np.sin(phi), np.sin(theta))
z = np.outer(np.ones(np.size(phi)), np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
r = np.linspace(0.,1.,25)
x = np.outer(r, np.sin(theta))
y = 0.*x
z = np.outer(r, np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='g')
ax.view_init(30.,60.)
pl.show()
Upvotes: 3
Views: 1345
Reputation: 727
It turns out that this is such a common problem that it's mentioned in the FAQ:
My 3D plot doesn’t look right at certain viewing angles
This is probably the most commonly reported issue with mplot3d. The problem is that – from some viewing angles – a 3D object would appear in front of another object, even though it is physically behind it. This can result in plots that do not look “physically correct.”
Unfortunately, while some work is being done to reduce the occurance of this artifact, it is currently an intractable problem, and can not be fully solved until matplotlib supports 3D graphics rendering at its core.
In this case, you can create a crude fix by plotting the three quarters of the sphere separately. e.g.
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as pl
import numpy as np
fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
theta = np.linspace(0, np.pi, 100)
# first quarter
phi = np.linspace(0.5*np.pi, 1.0*np.pi, 34)
x = np.outer(np.cos(phi), np.sin(theta))
y = np.outer(np.sin(phi), np.sin(theta))
z = np.outer(np.ones(np.size(phi)), np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
# second quarter
phi = np.linspace(1.0*np.pi, 1.5*np.pi, 34)
x = np.outer(np.cos(phi), np.sin(theta))
y = np.outer(np.sin(phi), np.sin(theta))
z = np.outer(np.ones(np.size(phi)), np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
# third quarter
phi = np.linspace(1.5*np.pi, 2.0*np.pi, 34)
x = np.outer(np.cos(phi), np.sin(theta))
y = np.outer(np.sin(phi), np.sin(theta))
z = np.outer(np.ones(np.size(phi)), np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b')
r = np.linspace(0.,1.,25)
x = np.outer(r, np.sin(theta))
y = 0.*x
z = np.outer(r, np.cos(theta))
ax.plot_surface(x, y, z, rstride=4, cstride=4, color='g')
ax.view_init(30.,60.)
pl.show()
Upvotes: 2