How to do a 3D circle in Matplotlib

Question:

I am a beginner in Python. I’m trying to plot a circle using matplotlib that has tangent to Z axis. I know how to draw a sphere in 3D but don’t know how to draw a circle/ring in 3D plot. Can someone help me with the code? Thanks in advance!

Asked By: Higa

||

Answers:

You need the usual imports, plus the 3D toolkit

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

You need a 3D enabled axes object

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

You need a circle, contained in the plane y-z

theta = np.linspace(0, 2 * np.pi, 201)
y = 10*np.cos(theta)
z = 10*np.sin(theta)

now we can plot the original circle and, as an example, a number of circles rotated about the z-axis and whose centers are also placed at a fixed distance (equal to the c ircles’radius) from the z-axis, so that they are tangent to it

for i in range(18):
    phi = i*np.pi/9
    ax.plot(y*np.sin(phi)+10*np.sin(phi),
            y*np.cos(phi)+10*np.cos(phi), z)

eventually we place a vertical axis and a legend

ax.plot((0,0),(0,0), (-10,10), '-k', label='z-axis')
ax.legend()

It’s time to see what we got

plt.show()

enter image description here

Answered By: gboffi

mpl_toolkits.mplot3d.art3d

https://matplotlib.org/3.2.1/gallery/mplot3d/pathpatch3d.html was mentioned
in a comment
, the example can be minimized to:

#!/usr/bin/env python3

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import mpl_toolkits.mplot3d.art3d as art3d

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Draw a circle on the x=0 'wall'
p = Circle((5, 5), 3)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0, zdir="x")

ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_zlim(0, 10)

plt.show()

which gives:

enter image description here

This is a bit nicer than https://stackoverflow.com/a/56871467/895245 as it uses a higher level Circle object directly, instead of requiring you to explicitly plot the lines.

Unfortunately, 3D support in matplotlib is a bit limited as mentioned in the documentation itself, and you have to do some extra work to plot on planes not parallel to the main coordinate plane: How can matplotlib 2D patches be transformed to 3D with arbitrary normals?

Tested on matplotlib==3.2.2.

I don’t know how to draw a circle/ring in 3D plot. I’m trying to plot a circle that has tangent to Z axis

You can either

  • use a Circle patch. This should be the best solution, but it doesn’t work very well in some configurations (e.g. it throws an error when the figure has a constrained layout)

  • use discrete points with individual (x,y,z) triplets, linked by a line. Just set one of the coordinate constant to project a flat circle onto that axis. This is the method used in the currently selected answer.

While the latter method is not intellectually optimal, it is a workable bypass for the problems with Circle. However iterating over all individual points can be slow when using a Python loop. The variant in this answer speeds up and allows for more concise code using numpy array operations directly, instead of Python loops.

enter image description here

import numpy as np
import matplotlib.pyplot as plt

r = 2 # desired radius
n = 100 # number of points for the circle
x,y,z = 12, 56, 20 # circle center

# Get circle discrete points in z-plane
# Convert to Cartesian coordinates
# Set the 3rd coordinate to a fixed value
points = r*np.exp(1j*np.linspace(0, 2*np.pi, n))
u,v = np.real(points), np.imag(points)
w = np.repeat(r, n)

# Set pyplot configuration
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_aspect('equal')

# To plot one circle, just use:
#ax.plot (u+x,v+y,w+z)

# ---------------------------------------------

# # Fancy plot of circles at different locations
from itertools import permutations
perms = set(permutations([0,1,2])).union(permutations([0,1,3]))

coords = [u,v,w,-w]
for idx, idy, idz in perms: ax.plot(coords[idx]+x, coords[idy]+y, coords[idz]+z)
Answered By: mins
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.