Animation engine for explanatory math videos.
—
Mathematical coordinate systems and graphing utilities including 2D/3D axes, number lines, polar coordinates, and function plotting with automatic scaling and labeling. These systems provide the mathematical foundation for plotting functions, displaying data, and creating precise mathematical visualizations.
Abstract foundation providing common functionality for all coordinate systems including coordinate mapping, scaling, and mathematical transformations.
class CoordinateSystem:
"""
Abstract base class providing core coordinate system functionality.
Defines the interface for coordinate mapping, scaling, and mathematical
transformations that all coordinate systems inherit.
"""
def __init__(
x_range: Sequence[float] = None,
y_range: Sequence[float] = None,
x_length: float = None,
y_length: float = None,
dimension: int = 2
) -> None:
"""
Parameters:
- x_range: [x_min, x_max, x_step] for x-axis
- y_range: [y_min, y_max, y_step] for y-axis
- x_length: Physical length of x-axis in Manim units
- y_length: Physical length of y-axis in Manim units
- dimension: Coordinate system dimensionality (2 or 3)
"""
# Coordinate mapping methods
def coords_to_point(x: float, y: float, z: float = 0) -> np.ndarray:
"""Convert mathematical coordinates to Manim scene point."""
def point_to_coords(point: np.ndarray) -> tuple[float, float, float]:
"""Convert Manim scene point to mathematical coordinates."""
def c2p(x: float, y: float, z: float = 0) -> np.ndarray:
"""Alias for coords_to_point - convert coordinates to point."""
def p2c(point: np.ndarray) -> tuple[float, float, float]:
"""Alias for point_to_coords - convert point to coordinates."""
def __matmul__(coords: Sequence[float]) -> np.ndarray:
"""Matrix multiplication syntax for coordinate conversion: axes @ [x, y]."""
# Axis access methods
def get_x_axis() -> NumberLine:
"""Get the x-axis as a NumberLine object."""
def get_y_axis() -> NumberLine:
"""Get the y-axis as a NumberLine object."""
def get_z_axis() -> NumberLine:
"""Get the z-axis as a NumberLine object (3D only)."""
def get_axes() -> VGroup:
"""Get all axes as a VGroup."""
# Range and length properties
def get_x_range() -> Sequence[float]:
"""Get x-axis range [min, max, step]."""
def get_y_range() -> Sequence[float]:
"""Get y-axis range [min, max, step]."""
def get_x_length() -> float:
"""Get physical x-axis length."""
def get_y_length() -> float:
"""Get physical y-axis length."""Standard Cartesian coordinate system with customizable axes, ticks, labels, and grid lines for 2D mathematical plotting.
class Axes(VGroup, CoordinateSystem):
"""
2D Cartesian coordinate system with full customization.
Provides x and y axes with ticks, labels, and grid lines for
mathematical function plotting and data visualization.
"""
def __init__(
x_range: Sequence[float] = None,
y_range: Sequence[float] = None,
x_length: float = round(config["frame_width"]) - 2,
y_length: float = round(config["frame_height"]) - 2,
axis_config: dict = None,
x_axis_config: dict = None,
y_axis_config: dict = None,
tips: bool = True,
**kwargs
) -> None:
"""
Parameters:
- x_range: [x_min, x_max, x_step] for x-axis domain
- y_range: [y_min, y_max, y_step] for y-axis domain
- x_length: Physical width of coordinate system
- y_length: Physical height of coordinate system
- axis_config: Configuration applied to both axes
- x_axis_config: Configuration specific to x-axis
- y_axis_config: Configuration specific to y-axis
- tips: Whether to show arrow tips on axes
"""
# Function plotting methods
def plot(
function: Callable[[float], float],
x_range: Sequence[float] = None,
use_vectorized: bool = False,
discontinuities: Sequence[float] = None,
dt: float = 1e-8,
**kwargs
) -> ParametricFunction:
"""
Plot a mathematical function f(x) -> y.
Parameters:
- function: Function to plot, taking x and returning y
- x_range: Domain [x_min, x_max, x_step] (uses axis range if None)
- use_vectorized: Whether function accepts numpy arrays
- discontinuities: x-values where function is discontinuous
- dt: Tolerance around discontinuities
Returns:
- ParametricFunction: Plotted curve object
"""
def plot_parametric_curve(
function: Callable[[float], Sequence[float]],
t_range: Sequence[float] = None,
**kwargs
) -> ParametricFunction:
"""
Plot parametric curve with function(t) -> [x(t), y(t)].
Parameters:
- function: Parametric function taking t, returning [x, y]
- t_range: Parameter domain [t_min, t_max, t_step]
Returns:
- ParametricFunction: Plotted parametric curve
"""
def plot_implicit_curve(
func: Callable[[float, float], float],
min_depth: int = 5,
max_quads: int = 1500,
**kwargs
) -> ImplicitFunction:
"""
Plot implicit curve defined by f(x,y) = 0.
Parameters:
- func: Function f(x,y) defining the curve
- min_depth: Minimum recursive subdivision depth
- max_quads: Maximum number of quadrilaterals for approximation
Returns:
- ImplicitFunction: Plotted implicit curve
"""
def get_graph(
function: Callable[[float], float],
x_range: Sequence[float] = None,
**kwargs
) -> ParametricFunction:
"""Alias for plot() method - plot mathematical function."""
# Grid and reference lines
def get_horizontal_line(
point: np.ndarray,
line_func: Callable = Line,
line_config: dict = None,
**kwargs
) -> Line:
"""
Create horizontal reference line through given point.
Parameters:
- point: Point to draw horizontal line through
- line_func: Line class to use (Line, DashedLine, etc.)
- line_config: Configuration for the line
Returns:
- Line: Horizontal reference line
"""
def get_vertical_line(
point: np.ndarray,
line_func: Callable = Line,
line_config: dict = None,
**kwargs
) -> Line:
"""
Create vertical reference line through given point.
Parameters:
- point: Point to draw vertical line through
- line_func: Line class to use
- line_config: Configuration for the line
Returns:
- Line: Vertical reference line
"""
def get_lines_to_point(
point: np.ndarray,
**kwargs
) -> VGroup:
"""
Get both horizontal and vertical lines to a point.
Parameters:
- point: Target point for reference lines
Returns:
- VGroup: Both horizontal and vertical reference lines
"""
# Axis labels and decorations
def get_x_axis_label(
label: str | Mobject,
edge: np.ndarray = RIGHT,
direction: np.ndarray = DL,
**kwargs
) -> Mobject:
"""
Create label for x-axis.
Parameters:
- label: Label text or mobject
- edge: Which edge of axis to place label
- direction: Direction to offset label from axis
Returns:
- Mobject: Positioned x-axis label
"""
def get_y_axis_label(
label: str | Mobject,
edge: np.ndarray = UP,
direction: np.ndarray = UR,
**kwargs
) -> Mobject:
"""
Create label for y-axis.
Parameters:
- label: Label text or mobject
- edge: Which edge of axis to place label
- direction: Direction to offset label from axis
Returns:
- Mobject: Positioned y-axis label
"""
def get_axis_labels(
x_label: str | Mobject = "x",
y_label: str | Mobject = "y"
) -> VGroup:
"""
Get both x and y axis labels.
Parameters:
- x_label: X-axis label
- y_label: Y-axis label
Returns:
- VGroup: Both axis labels
"""
# Coordinate transformations
def angle_of_tangent(
x: float,
graph: ParametricFunction,
dx: float = 1e-8
) -> float:
"""
Get angle of tangent to graph at x-coordinate.
Parameters:
- x: X-coordinate for tangent
- graph: Function graph to find tangent on
- dx: Small increment for numerical differentiation
Returns:
- float: Tangent angle in radians
"""
def slope_of_tangent(
x: float,
graph: ParametricFunction,
**kwargs
) -> float:
"""
Get slope of tangent to graph at x-coordinate.
Parameters:
- x: X-coordinate for tangent
- graph: Function graph to find tangent on
Returns:
- float: Tangent slope (dy/dx)
"""
def input_to_graph_point(
x: float,
graph: ParametricFunction
) -> np.ndarray:
"""
Get point on graph corresponding to x-coordinate.
Parameters:
- x: Input x-coordinate
- graph: Function graph to sample
Returns:
- np.ndarray: Point [x, f(x), 0] on the graph
"""
# Area and integration visualization
def get_riemann_rectangles(
graph: ParametricFunction,
x_range: Sequence[float] = None,
dx: float = 0.1,
input_sample_type: str = "left",
stroke_width: float = 1,
stroke_color: str = BLACK,
fill_opacity: float = 1,
color: Sequence[str] = (BLUE, GREEN),
show_signed_area: bool = True,
bounded_graph: ParametricFunction = None,
blend: bool = False,
width_scale_factor: float = 1.001
) -> VGroup:
"""
Create Riemann rectangles for numerical integration visualization.
Parameters:
- graph: Function to integrate
- x_range: Integration domain [x_min, x_max]
- dx: Width of each rectangle
- input_sample_type: Sampling method ("left", "right", "center")
- stroke_width: Rectangle border width
- stroke_color: Rectangle border color
- fill_opacity: Rectangle fill opacity
- color: Colors for positive/negative areas
- show_signed_area: Whether to show negative areas differently
- bounded_graph: Lower bound function (default is x-axis)
- blend: Whether to blend colors across rectangles
- width_scale_factor: Rectangle width adjustment
Returns:
- VGroup: Collection of Riemann rectangles
"""
def get_area(
graph: ParametricFunction,
x_range: Sequence[float] = None,
color: str | Sequence[str] = (BLUE, GREEN),
opacity: float = 0.3,
bounded_graph: ParametricFunction = None,
**kwargs
) -> Polygon:
"""
Create filled area under/between curves.
Parameters:
- graph: Upper boundary function
- x_range: Integration domain [x_min, x_max]
- color: Fill color(s)
- opacity: Fill opacity
- bounded_graph: Lower boundary function (default is x-axis)
Returns:
- Polygon: Filled area region
"""
class ThreeDAxes(Axes):
"""
3D Cartesian coordinate system extending 2D axes with z-axis.
Provides full 3D coordinate system with x, y, and z axes for
3D function plotting and spatial visualizations.
"""
def __init__(
x_range: Sequence[float] = (-6, 6, 1),
y_range: Sequence[float] = (-5, 5, 1),
z_range: Sequence[float] = (-4, 4, 1),
x_length: float = config["frame_width"],
y_length: float = config["frame_height"],
z_length: float = 3.0,
z_axis_config: dict = None,
z_normal: np.ndarray = DOWN,
num_axis_pieces: int = 20,
light_source: np.ndarray = 9 * DOWN + 7 * LEFT + 10 * OUT,
**kwargs
) -> None:
"""
Parameters:
- x_range: [x_min, x_max, x_step] for x-axis
- y_range: [y_min, y_max, y_step] for y-axis
- z_range: [z_min, z_max, z_step] for z-axis
- x_length: Physical x-axis length
- y_length: Physical y-axis length
- z_length: Physical z-axis length
- z_axis_config: Configuration specific to z-axis
- z_normal: Normal direction for z-axis display
- num_axis_pieces: Number of pieces for smooth shading
- light_source: Light position for 3D shading
"""
def get_z_axis_label(
label: str | Mobject,
edge: np.ndarray = OUT,
direction: np.ndarray = RIGHT,
**kwargs
) -> Mobject:
"""Create label for z-axis."""
def get_z_range() -> Sequence[float]:
"""Get z-axis range [min, max, step]."""
def get_z_length() -> float:
"""Get physical z-axis length."""Advanced coordinate systems for specific mathematical contexts and specialized visualizations.
class NumberPlane(Axes):
"""
2D coordinate plane with background grid lines and enhanced visual aids.
Extends basic axes with visible grid lines, background coloring,
and enhanced visual feedback for coordinate-based work.
"""
def __init__(
x_range: Sequence[float] = None,
y_range: Sequence[float] = None,
x_length: float = None,
y_length: float = None,
background_line_style: dict = None,
faded_line_style: dict = None,
faded_line_ratio: int = 1,
make_smooth_after_applying_functions: bool = True,
**kwargs
) -> None:
"""
Parameters:
- x_range: X-axis range and step
- y_range: Y-axis range and step
- x_length: Physical width
- y_length: Physical height
- background_line_style: Style for background grid lines
- faded_line_style: Style for fainter grid lines
- faded_line_ratio: Ratio of faded to normal lines
- make_smooth_after_applying_functions: Auto-smooth transformations
"""
def get_lines_parallel_to_axis(
axis: NumberLine,
line_func: Callable = Line,
freq: int = 1,
**line_kwargs
) -> VGroup:
"""
Create grid lines parallel to specified axis.
Parameters:
- axis: Axis to create parallel lines for
- line_func: Type of line to create
- freq: Frequency of lines (every nth tick)
Returns:
- VGroup: Parallel grid lines
"""
def get_coordinate_labels(
x_vals: Sequence[float] = None,
y_vals: Sequence[float] = None,
**kwargs
) -> VDict:
"""
Create coordinate labels for grid intersection points.
Parameters:
- x_vals: X-coordinates to label
- y_vals: Y-coordinates to label
Returns:
- VDict: Coordinate labels indexed by position
"""
class PolarPlane(Axes):
"""
Polar coordinate system with radial and angular grid lines.
Specialized for polar functions r(θ) with circular grid lines
and angular divisions for polar mathematical contexts.
"""
def __init__(
radius_max: float = config["frame_y_radius"],
radius_step: float = 1,
size: float = None,
azimuth_step: float = PI / 12,
azimuth_units: str = "PI",
azimuth_compact_fraction: bool = True,
azimuth_offset: float = 0,
azimuth_direction: str = "CCW",
azimuth_label_buff: float = SMALL_BUFF,
azimuth_label_font_size: float = 20,
radius_config: dict = None,
**kwargs
) -> None:
"""
Parameters:
- radius_max: Maximum radius for polar grid
- radius_step: Step size between radial grid lines
- size: Overall size of polar plane
- azimuth_step: Angular step between radial lines
- azimuth_units: Units for angle labels ("PI", "degrees")
- azimuth_compact_fraction: Whether to use compact fractions
- azimuth_offset: Angular offset for zero direction
- azimuth_direction: Direction of angle increase ("CCW", "CW")
- azimuth_label_buff: Buffer for angle labels
- azimuth_label_font_size: Font size for angle labels
- radius_config: Configuration for radial axis
"""
def polar_to_point(
radius: float,
azimuth: float
) -> np.ndarray:
"""
Convert polar coordinates to Cartesian point.
Parameters:
- radius: Radial distance
- azimuth: Angle in radians
Returns:
- np.ndarray: Cartesian point [x, y, 0]
"""
def point_to_polar(
point: np.ndarray
) -> tuple[float, float]:
"""
Convert Cartesian point to polar coordinates.
Parameters:
- point: Cartesian point
Returns:
- tuple: (radius, azimuth) in polar coordinates
"""
def pr2pt(radius: float, azimuth: float) -> np.ndarray:
"""Alias for polar_to_point."""
def pt2pr(point: np.ndarray) -> tuple[float, float]:
"""Alias for point_to_polar."""
class ComplexPlane(NumberPlane):
"""
Complex number plane with real and imaginary axes.
Specialized coordinate system for complex analysis with
appropriate labeling and visualization for complex functions.
"""
def __init__(
x_range: Sequence[float] = (-4, 4, 1),
y_range: Sequence[float] = (-4, 4, 1),
**kwargs
) -> None:
"""
Parameters:
- x_range: Real axis range
- y_range: Imaginary axis range
"""
def number_to_point(
number: complex | float
) -> np.ndarray:
"""
Convert complex number to point on plane.
Parameters:
- number: Complex number z = a + bi
Returns:
- np.ndarray: Point [Re(z), Im(z), 0]
"""
def point_to_number(
point: np.ndarray
) -> complex:
"""
Convert point on plane to complex number.
Parameters:
- point: Cartesian point
Returns:
- complex: Complex number a + bi
"""
def n2p(number: complex | float) -> np.ndarray:
"""Alias for number_to_point."""
def p2n(point: np.ndarray) -> complex:
"""Alias for point_to_number."""One-dimensional coordinate systems for number representation, intervals, and linear mathematical concepts.
class NumberLine(Line):
"""
One-dimensional number line with ticks, labels, and number positioning.
Fundamental 1D coordinate system for representing real numbers,
intervals, and linear mathematical relationships.
"""
def __init__(
x_range: Sequence[float] = (-8, 8, 1),
length: float = None,
unit_size: float = 1,
include_ticks: bool = True,
tick_size: float = 0.1,
numbers_with_elongated_ticks: Sequence[float] = None,
longer_tick_multiple: float = 2,
exclude_zero_from_default_numbers: bool = False,
numbers_to_show: Sequence[float] = None,
numbers_to_exclude: Sequence[float] = None,
label_direction: np.ndarray = DOWN,
line_to_number_buff: float = MED_SMALL_BUFF,
include_numbers: bool = False,
scaling: _ScaleBase = LinearBase(),
font_size: float = 36,
stroke_width: float = 2,
include_tip: bool = False,
tip_width: float = 0.25,
tip_height: float = 0.25,
decimal_number_config: dict = None,
numbers_config: dict = None,
**kwargs
) -> None:
"""
Parameters:
- x_range: [min, max, step] for number line range
- length: Physical length of number line
- unit_size: Manim units per number line unit
- include_ticks: Whether to show tick marks
- tick_size: Height of tick marks
- numbers_with_elongated_ticks: Numbers with longer ticks
- longer_tick_multiple: Length multiplier for elongated ticks
- exclude_zero_from_default_numbers: Whether to skip zero label
- numbers_to_show: Specific numbers to label
- numbers_to_exclude: Numbers to skip in labeling
- label_direction: Direction to place number labels
- line_to_number_buff: Space between line and labels
- include_numbers: Whether to show number labels
- scaling: Scaling transformation for the line
- font_size: Size of number labels
- stroke_width: Line thickness
- include_tip: Whether to show arrow tip
- tip_width: Arrow tip width
- tip_height: Arrow tip height
- decimal_number_config: Config for decimal number labels
- numbers_config: Config for number label mobjects
"""
def number_to_point(number: float) -> np.ndarray:
"""Convert number to position on the line."""
def point_to_number(point: np.ndarray) -> float:
"""Convert position on line to number."""
def n2p(number: float) -> np.ndarray:
"""Alias for number_to_point."""
def p2n(point: np.ndarray) -> float:
"""Alias for point_to_number."""
def get_number_mobject(
number: float,
**number_config
) -> DecimalNumber:
"""
Create mobject for displaying a number.
Parameters:
- number: Number to display
- **number_config: Configuration for number formatting
Returns:
- DecimalNumber: Formatted number mobject
"""
def get_tick(
x: float,
size: float = None
) -> Line:
"""
Create tick mark at specified position.
Parameters:
- x: Number position for tick
- size: Tick mark height
Returns:
- Line: Tick mark line
"""
def add_ticks() -> Self:
"""Add tick marks to the number line."""
def add_numbers(
*numbers: float,
**kwargs
) -> Self:
"""
Add number labels to the line.
Parameters:
- *numbers: Numbers to label (uses default range if empty)
"""
class UnitInterval(NumberLine):
"""
Number line representing the unit interval [0, 1].
Specialized for probability, unit measurements, and
normalized value representations.
"""
def __init__(
x_range: Sequence[float] = (0, 1, 0.1),
**kwargs
) -> None:
"""
Parameters:
- x_range: Range for unit interval (default [0,1,0.1])
"""Mathematical function visualization with support for parametric, implicit, and standard function plotting with advanced rendering options.
class ParametricFunction(VMobject):
"""
Parametric curve defined by function(t) -> [x(t), y(t), z(t)].
General-purpose curve plotting for parametric equations,
space curves, and complex mathematical paths.
"""
def __init__(
function: Callable[[float], Sequence[float]],
t_range: Sequence[float] = (0, 1, 0.01),
scaling: _ScaleBase = LinearBase(),
use_smoothing: bool = True,
use_vectorized: bool = False,
discontinuities: Sequence[float] = None,
dt: float = 1e-8,
**kwargs
) -> None:
"""
Parameters:
- function: Parametric function t -> [x(t), y(t), z(t)]
- t_range: Parameter domain [t_min, t_max, t_step]
- scaling: Coordinate scaling transformation
- use_smoothing: Whether to smooth the resulting curve
- use_vectorized: Whether function accepts array input
- discontinuities: t-values where function is discontinuous
- dt: Tolerance around discontinuities
"""
class FunctionGraph(ParametricFunction):
"""
Standard function graph y = f(x) with automatic parametrization.
Convenient wrapper for plotting functions of one variable
with domain/range validation and optimization.
"""
def __init__(
function: Callable[[float], float],
x_range: Sequence[float] = (-8, 8, 0.25),
color: str = YELLOW,
**kwargs
) -> None:
"""
Parameters:
- function: Function f(x) -> y
- x_range: Domain [x_min, x_max, x_step]
- color: Graph color
"""
class ImplicitFunction(VMobject):
"""
Implicit curve defined by equation f(x, y) = 0.
Specialized for level curves, implicit equations, and
relationships that cannot be expressed as y = f(x).
"""
def __init__(
func: Callable[[float, float], float],
x_range: Sequence[float] = (-8, 8),
y_range: Sequence[float] = (-4, 4),
min_depth: int = 5,
max_quads: int = 1500,
use_smoothing: bool = True,
joint_type: str = "no_joint",
**kwargs
) -> None:
"""
Parameters:
- func: Implicit function f(x,y) defining curve where f(x,y) = 0
- x_range: X domain [x_min, x_max]
- y_range: Y domain [y_min, y_max]
- min_depth: Minimum subdivision depth for curve tracing
- max_quads: Maximum quadrilaterals for curve approximation
- use_smoothing: Whether to smooth the resulting curve
- joint_type: How to handle curve segment connections
"""from manim import *
class CoordinateExample(Scene):
def construct(self):
# Create 2D axes
axes = Axes(
x_range=[-3, 3, 1],
y_range=[-2, 2, 0.5],
x_length=10,
y_length=6,
axis_config={"color": BLUE},
x_axis_config={"numbers_to_include": np.arange(-3, 4, 1)},
y_axis_config={"numbers_to_include": np.arange(-2, 2.5, 0.5)},
tips=False
)
# Add axis labels
x_label = axes.get_x_axis_label("x")
y_label = axes.get_y_axis_label("y", direction=LEFT)
# Plot function
graph = axes.plot(lambda x: x**2, color=YELLOW)
self.add(axes, x_label, y_label, graph)class FunctionPlotExample(Scene):
def construct(self):
axes = Axes(
x_range=[-4, 4, 1],
y_range=[-2, 8, 1],
x_length=8,
y_length=6
)
# Plot multiple functions
functions = [
(lambda x: x**2, RED, "x²"),
(lambda x: 2**x, BLUE, "2ˣ"),
(lambda x: np.sin(x) + 3, GREEN, "sin(x) + 3")
]
graphs = VGroup()
labels = VGroup()
for func, color, label_text in functions:
graph = axes.plot(func, color=color)
label = MathTex(label_text, color=color).scale(0.7)
graphs.add(graph)
labels.add(label)
# Position labels
labels.arrange(RIGHT, buff=1).to_edge(UP)
self.add(axes, graphs, labels)class ThreeDAxesExample(ThreeDScene):
def construct(self):
# Create 3D axes
axes = ThreeDAxes(
x_range=[-5, 5, 1],
y_range=[-5, 5, 1],
z_range=[-3, 3, 1],
x_length=8,
y_length=8,
z_length=6
)
# Add axis labels
x_label = axes.get_x_axis_label("x")
y_label = axes.get_y_axis_label("y")
z_label = axes.get_z_axis_label("z")
# Plot 3D parametric curve
curve = axes.plot_parametric_curve(
lambda t: [2*np.cos(t), 2*np.sin(t), t/2],
t_range=[0, 4*PI, 0.1],
color=YELLOW
)
# Set camera orientation
self.set_camera_orientation(phi=75*DEGREES, theta=45*DEGREES)
self.add(axes, x_label, y_label, z_label, curve)class PolarExample(Scene):
def construct(self):
# Create polar plane
plane = PolarPlane(
radius_max=4,
radius_step=1,
azimuth_step=PI/6,
azimuth_units="PI"
)
# Plot polar function r = 2 + cos(3θ)
polar_graph = plane.plot_polar_graph(
lambda theta: 2 + np.cos(3*theta),
[0, 2*PI],
color=RED
)
self.add(plane, polar_graph)class AdvancedPlottingExample(Scene):
def construct(self):
axes = Axes(x_range=[-3, 3, 1], y_range=[-1, 3, 1])
# Plot function with area highlighting
func = lambda x: x**2
graph = axes.plot(func, color=BLUE)
# Add Riemann rectangles
riemann_rects = axes.get_riemann_rectangles(
graph,
x_range=[-2, 2],
dx=0.2,
color=[BLUE_D, BLUE_E]
)
# Add area under curve
area = axes.get_area(
graph,
x_range=[-1, 1],
color=YELLOW,
opacity=0.5
)
# Add reference lines
point = axes.coords_to_point(1, 1)
h_line = axes.get_horizontal_line(point, color=GREEN)
v_line = axes.get_vertical_line(point, color=GREEN)
dot = Dot(point, color=RED)
self.add(axes, graph, riemann_rects, area, h_line, v_line, dot)Install with Tessl CLI
npx tessl i tessl/pypi-manim