Carly
Carly

Reputation: 123

Lines in 3d plot in python

I have the following script:

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

nn = 400  # number of points along circle's perimeter
theta = np.linspace(0, 2*np.pi, nn)
rho = np.ones(nn)

# (x,y) represents points on circle's perimeter
x = np.ravel(rho*np.cos(theta))
y = np.ravel(rho*np.sin(theta))

fig, ax = plt.subplots()
plt.rcParams["figure.figsize"] = [6, 10]
ax = plt.axes(projection='3d')  # set the axes for 3D plot

ax.azim = -90   # y rotation (default=270)
ax.elev = 21    # x rotation (default=0)

# low, high values of z for plotting 2 circles at different elev.
loz, hiz = -15, 15

# Plot two circles
ax.plot(x, y, hiz)   
ax.plot(x, y, loz)  

# set some indices to get proper (x,y) for line plotting
lo1,hi1 = 15, 15+nn//2
lo2,hi2 = lo1+nn//2-27, hi1-nn//2-27

# plot 3d lines using coordinates of selected points
ax.plot([x[lo1], x[hi1]], [y[lo1], y[hi1]], [loz, hiz]) 
ax.plot([x[lo2], x[hi2]], [y[lo2], y[hi2]], [loz, hiz]) 

ax.plot([0, 0, 0], [0, 0, 10])
ax.plot([0, 0, 0], [9, 0, 0])
ax.plot([0, 0, 0], [0, 8, 0])

plt.show()

At the end of the script, I would like to plot three lines in three directions. How to do that? Why this:

ax.plot([0, 0, 0], [0, 0, 10])
ax.plot([0, 0, 0], [9, 0, 0])
ax.plot([0, 0, 0], [0, 8, 0])

gives the line in same direction?

And I have a second question, please. How to make the cone more narrower (the base more similar to circle)?

Output now: enter image description here

Upvotes: 1

Views: 7455

Answers (2)

tmdavison
tmdavison

Reputation: 69056

ax.plot([0, 0, 0], [0, 0, 10]) is giving plot the x and y coordinates of 3 points, but you haven't given any coordinates in the z direction. Remember the inputs to plot are x, y, z, not, as you seem to have assumed, (x0,y0,z0), (x1,y1,z1)

So this is drawing 3 "lines" where two of them start and end at x=y=z=0, and one of them extends to y=10. The other two ax.plot calls you have are doing similar things.

To draw three lines that start at the origin and each extend along one of the x, y, or z directions, you perhaps meant to use:

ax.plot([0, 0], [0, 0], [0, 10])  # extend in z direction
ax.plot([0, 0], [0, 8], [0, 0])   # extend in y direction
ax.plot([0, 9], [0, 0], [0, 0])   # extend in x direction

Note that this also makes your circles look more like circles

enter image description here

Upvotes: 4

PeakyBlinder
PeakyBlinder

Reputation: 1117

After commenting the last 3 lines of your code, the image is the output I am getting

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

nn = 400  # number of points along circle's perimeter
theta = np.linspace(0, 2*np.pi, nn)
rho = np.ones(nn)

# (x,y) represents points on circle's perimeter
x = np.ravel(rho*np.cos(theta))
y = np.ravel(rho*np.sin(theta))

fig, ax = plt.subplots()
plt.rcParams["figure.figsize"] = [6, 10]
ax = plt.axes(projection='3d')  # set the axes for 3D plot

ax.azim = -90   # y rotation (default=270)
ax.elev = 21    # x rotation (default=0)

# low, high values of z for plotting 2 circles at different elev.
loz, hiz = -15, 15

# Plot two circles
ax.plot(x, y, hiz)   
ax.plot(x, y, loz)  

# set some indices to get proper (x,y) for line plotting
lo1,hi1 = 15, 15+nn//2
lo2,hi2 = lo1+nn//2-27, hi1-nn//2-27

# plot 3d lines using coordinates of selected points
ax.plot([x[lo1], x[hi1]], [y[lo1], y[hi1]], [loz, hiz]) 
ax.plot([x[lo2], x[hi2]], [y[lo2], y[hi2]], [loz, hiz]) 

#ax.plot([0, 0, 0], [0, 0, 10])
#ax.plot([0, 0, 0], [9, 0, 0])
#ax.plot([0, 0, 0], [0, 8, 0])

plt.show()

Output

You can see that the base is almost a perfect circle. Because you are also plotting lines in your figure, it is giving an illusion that the base in not a circle.

And regarding the lines in 3 different directions. Since this part of code

ax.plot([0, 0, 0], [0, 0, 10])
ax.plot([0, 0, 0], [9, 0, 0])
ax.plot([0, 0, 0], [0, 8, 0])

has all zeroes in X-Axis, it is essentially plotting the lines on Y-Axis only.

When I give some values in the X-Axis part, like this

ax.plot([1, 0, 0], [0, 0, 10])
ax.plot([0, 0, 5], [9, 0, 0])
ax.plot([0, 8, 0], [0, 8, 0])

The output is

Output

I hope this is what you were asking.

Upvotes: 1

Related Questions