vinayv
vinayv

Reputation: 21

Plotting a 3d line intersecting a surface

I am trying to plot a surface and a line which is passing through it. I want to have a plot where the portion of the line which is behind the surface, is hidden.

I tried this in matplotlib but the portion of the line behind the surface is also visible.

Line intersecting a surface

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

x = np.arange(0,10,1)
y = np.arange(0,10,1)
z = np.arange(0,10,1)

X, Y = np.meshgrid(x,y)
Z= np.ones((len(x),len(x)))*5

fig = plt.figure()
ax1 = fig.gca(projection='3d')
ax1.plot_surface(X, Y, Z, color='red', edgecolor='black')
ax1.plot(x,y,z,'-',color='black',linewidth=4)
plt.show()

Upvotes: 2

Views: 2175

Answers (1)

Dominic McLoughlin
Dominic McLoughlin

Reputation: 278

In matplotlib, there is a concept of the zorder. Objects with a higher zorder are plotted in a layer on top of objects with a lower zorder, as per the docs. By default, the patch has a higher zorder than the line, which is why your red surface appears to block out the line. Here I have created a new set of coordinates for the background and foreground parts of the line, by selecting indices where z <= 5 or z >= 5 respectively. Then I plot these two sets of points separately, setting the zorder for all three - the surface and both of the lines.

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

x = np.arange(0, 10, 1)
y = np.arange(0, 10, 1)
z = np.arange(0, 10, 1)

x_background = x[z <= 5]
y_background = y[z <= 5]
z_background = z[z <= 5]
x_foreground = x[z >= 5]
y_foreground = y[z >= 5]
z_foreground = z[z >= 5]

X, Y = np.meshgrid(x, y)
Z = np.ones((len(x), len(x))) * 5

fig = plt.figure()
ax1 = fig.gca(projection='3d')
ax1.plot_surface(X, Y, Z, color='red', edgecolor='black', zorder=1)
ax1.plot(
    z_background, z_background, z_background, '-', color='black', linewidth=4,
    zorder=2)
ax1.plot(
    z_foreground, z_foreground, z_foreground, '-', color='black', linewidth=4,
    zorder=3)
plt.show()

Line from behind using zorder

Hope this helps!

Upvotes: 2

Related Questions