Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Surface disappears in Matplotlib 3D plot

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.

Everything correct. After slight pan to the right.

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()
like image 744
Warrick Avatar asked Mar 14 '26 12:03

Warrick


1 Answers

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()
like image 181
Warrick Avatar answered Mar 16 '26 00:03

Warrick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!