How to Use Manim's Coordinate Systems: A Complete Guide to Axes and ThreeDAxes
Manim's CoordinateSystem abstraction provides the Axes class for 2D plotting and ThreeDAxes for 3D surfaces, offering methods like c2p() for coordinate conversion and get_graph() for plotting curves and surfaces.
Manim's animation engine relies heavily on Cartesian coordinate systems to position objects and plot mathematical functions. Whether you are creating 2D graphs or 3D surfaces, understanding the CoordinateSystem hierarchy in the 3b1b/manim repository is essential for precise scene construction.
Understanding the CoordinateSystem Abstraction
The foundation of all coordinate handling is the abstract class CoordinateSystem, defined in manimlib/mobject/coordinate_systems.py (lines 54‑91). This class stores user‑supplied ranges and implements conversion helpers that subclasses inherit.
Key methods provided by the base class include:
coords_to_point/point_to_coords– Map mathematical coordinates to scene points and vice‑versa (implemented by subclasses).get_axes/get_axis– Return the underlyingNumberLineobjects for each dimension.get_graph/get_parametric_curve– BuildParametricCurveobjects that automatically respect the coordinate system's scaling.- Helper utilities –
get_v_line,get_h_line,get_axis_labelfor quickly drawing perpendiculars and labels.
Working with 2D Axes
Instantiating Axes and Configuring Ranges
The Axes class is a concrete subclass of CoordinateSystem that creates two orthogonal NumberLines (X and Y) bundled in a VGroup. Its constructor resides in manimlib/mobject/coordinate_systems.py (lines 46‑90).
Range specification uses x_range and y_range parameters, which accept either a 2‑tuple (min, max) or a 3‑tuple (min, max, step). Internally, these are normalized by full_range_specifier (lines 48‑52). Each axis is built via create_axis, which instantiates a NumberLine (see manimlib/mobject/number_line.py, lines 27‑35) and recenters it at the origin.
Coordinate Conversion with c2p and p2c
To place objects at specific mathematical coordinates, use the c2p (coords to point) and p2c (point to coords) shorthand methods. These wrap coords_to_point and point_to_coords, adding the vectors from the origin to each axis' number point.
pt = axes.c2p(3, -2) # Returns a 3-D scene point at x=3, y=-2
x, y = axes.p2c(pt) # Returns (3.0, -2.0)
Plotting Functions and Curves
The get_graph method constructs a ParametricCurve from a lambda or function. It automatically handles scaling according to the axis ranges.
from manim import *
class TwoDAxesExample(Scene):
def construct(self):
# Create axes ranging from -8 to 8 on x and -4 to 4 on y
axes = Axes(
x_range=(-8, 8, 1),
y_range=(-4, 4, 1),
axis_config={"color": BLUE},
)
axes.add_axis_labels() # adds "x" and "y"
axes.add_coordinate_labels() # numbers the ticks
# Plot y = sin(x)
sine = axes.get_graph(lambda x: np.sin(x), color=RED)
# Label the curve
label = axes.get_graph_label(sine, label="\\sin(x)")
self.play(Create(axes), Create(sine), Write(label))
self.wait()
Key implementation details referenced in this example include the Axes constructor (lines 46‑90), axes.get_graph (lines 84‑92), and axes.get_graph_label (lines 84‑92) in coordinate_systems.py.
Extending to 3D with ThreeDAxes
Setting Up Three-Dimensional Axes
ThreeDAxes inherits from Axes and adds a third orthogonal Z‑axis. Its implementation occupies lines 35‑74 in manimlib/mobject/coordinate_systems.py.
The Z‑axis is created using the same create_axis helper, then rotated -π/2 around the UP direction and oriented to a user‑specified normal (z_normal, defaulting to DOWN) (lines 62‑66). All three axes are stored in self.axes and added as a separate mobject so they behave like a standard VGroup.
Plotting 3D Surfaces and Vectors
For 3D plotting, get_graph (lines 85‑106) builds a ParametricSurface from a function f(u, v). It automatically scales function values by the unit size of each axis and translates them to the origin, allowing you to write axes.get_graph(lambda u, v: u**2 - v**2) without manual scaling.
from manim import *
class ThreeDAxesExample(ThreeDScene):
def construct(self):
# Three‑dimensional axes
three_axes = ThreeDAxes(
x_range=(-6, 6, 1),
y_range=(-5, 5, 1),
z_range=(-4, 4, 1),
)
three_axes.add_axis_labels() # "x", "y", "z"
# Define surface z = x**2 - y**2
surface = three_axes.get_graph(
lambda u, v: u**2 - v**2,
color=GREEN,
opacity=0.6,
)
# Add a vector from the origin to a point on the surface
vector = three_axes.get_vector([2, 1, 3], color=YELLOW)
self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
self.add(three_axes, surface, vector)
self.wait()
Key implementation references include ThreeDAxes constructor (lines 35‑74), three_axes.get_graph (lines 85‑106), and three_axes.get_vector (line 179‑181).
Common Workflows and Utilities
Beyond basic plotting, Manim coordinate systems provide utilities for annotation and measurement:
- Auxiliary geometry – Draw vertical or horizontal reference lines with
axes.get_v_line(point)oraxes.get_h_line(point). - Axis labeling – Use
add_axis_labels()for quick "x", "y", "z" labels, orget_axis_label()for custom text. - Riemann sums and tangents – Helper methods exist for drawing rectangles under curves and tangent lines, all operating relative to the coordinate system origin and scaling.
- Exact placement – Always use
c2p(x, y)orc2p(x, y, z)to ensure objects align with mathematical coordinates rather than raw scene coordinates.
Key Source Files
| File | Role |
|---|---|
manimlib/mobject/coordinate_systems.py |
Core CoordinateSystem, Axes, ThreeDAxes definitions and utility methods. |
manimlib/mobject/number_line.py |
Implements the NumberLine used by Axes for tick marks, numbering and conversion helpers (n2p, p2n). |
manimlib/constants.py |
Provides direction vectors (UP, DOWN, RIGHT, …) and other constants referenced throughout the coordinate system code. |
manimlib/mobject/types/vectorized_mobject.py |
Supplies VGroup and VMobject base classes which Axes and ThreeDAxes extend. |
manimlib/mobject/functions.py |
Contains ParametricCurve used by CoordinateSystem.get_graph. |
manimlib/mobject/types/surface.py |
Supplies ParametricSurface used by ThreeDAxes.get_graph. |
Summary
CoordinateSystemis the abstract base inmanimlib/mobject/coordinate_systems.pythat defines ranges and the API for plotting.Axescreates 2D Cartesian systems usingNumberLineobjects, supportingx_range/y_rangetuples and coordinate conversion viac2p()andp2c().ThreeDAxesextendsAxeswith a Z‑axis (rotated and oriented viaz_normal) and providesget_graph()forParametricSurfaceplotting.- Use
get_graph,get_parametric_curve, andget_vectorto plot mathematical objects that automatically respect axis scaling. - Reference
manimlib/mobject/number_line.pyfor tick mark logic andmanimlib/mobject/types/surface.pyfor 3D surface rendering.
Frequently Asked Questions
How do I convert mathematical coordinates to scene points in Manim?
Use the c2p() method (short for coords_to_point). For a 2D system, call axes.c2p(x, y); for 3D, use three_axes.c2p(x, y, z). This returns a point in scene coordinates that respects the axis ranges and scaling defined in x_range, y_range, or z_range. To reverse the conversion, use p2c() (point_to_coords).
What is the difference between Axes and ThreeDAxes in Manim?
Axes is a 2D Cartesian system inheriting from CoordinateSystem, creating X and Y NumberLines. ThreeDAxes inherits from Axes and adds a third Z‑axis, which is created via create_axis, rotated -π/2 around the UP vector, and oriented to a z_normal (default DOWN). ThreeDAxes also overrides get_graph() to return ParametricSurface objects for 3D plotting.
How do I plot a 3D surface using ThreeDAxes?
Call three_axes.get_graph(func) where func is a lambda taking two arguments (typically u and v). For example, three_axes.get_graph(lambda u, v: u**2 - v**2) plots a hyperbolic paraboloid. The method (lines 85‑106 in coordinate_systems.py) automatically scales the output by the unit size of each axis and translates it to the origin, returning a ParametricSurface instance.
Where are the coordinate system classes defined in the Manim source code?
The core definitions reside in manimlib/mobject/coordinate_systems.py. The abstract CoordinateSystem class is defined at lines 54‑91, the concrete Axes class at lines 46‑90, and ThreeDAxes at lines 35‑74. The underlying NumberLine implementation used by these axes is found in manimlib/mobject/number_line.py.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →