Skip to content

Number lines

The film's code
import manimgx as m


class NumberLinesHero(m.Scene):
    def construct(self) -> None:
        line = m.NumberLine(x_range=[-3, 3, 1], length=10, include_numbers=True)
        dot = m.Dot(line.n2p(-2), radius=0.12, color=m.YELLOW)
        interval = m.UnitInterval(length=8, include_numbers=True).shift(2 * m.DOWN)
        self.play(m.Create(line))
        self.play(m.GrowFromCenter(dot))
        self.play(dot.animate.move_to(line.n2p(2.5)), run_time=2)
        self.play(m.Create(interval))
        self.wait()

A number line is a line with a number at each of its points. Its range, [start, end, step], gives its first and last numbers and the step between its ticks; its length is in the frame's units. n2p turns a number into its point on the line, to put anything at a number.

Axes are number lines too: each axis of Axes is one, and takes the keywords below.

NumberLine

NumberLineExample
Code
import manimgx as m


class NumberLineExample(m.Scene):
    def construct(self) -> None:
        lines = m.VGroup(
            m.NumberLine(x_range=[-5, 5, 1], length=12, include_numbers=True),
            m.NumberLine(
                x_range=[0, 2, 0.25],
                length=12,
                include_numbers=True,
                font_size=28,
                color=m.BLUE,
            ),
            m.NumberLine(
                x_range=[-10, 10, 2],
                length=12,
                numbers_with_elongated_ticks=[-10, 0, 10],
                include_tip=True,
                include_numbers=True,
                label_direction=m.UP,
                color=m.YELLOW,
            ),
        ).arrange(m.DOWN, buff=1)
        self.add(lines)

A number line: a line with ticks at every step of its range, numbers if asked for, and a map between numbers and points; white, with a stroke 2 wide, unless styled.

Its range, [x_min, x_max, x_step], runs from its left end to its right end: the line is length long, in scene units, or unit_size per unit, and it is centered on the scene's origin (then turned through rotation). Its ticks are x_step apart, counted from 0 when the range contains it (from x_min otherwise); a tip at its end takes the place of the last tick. number_to_point and point_to_number convert between numbers and points; add_numbers and add_labels write on it. A scaling spaces the numbers otherwise: with LogBase, the range is of exponents, and the line's numbers are powers.

Initial length, rotation, tip dimensions and which ticks/numbers to draw are construction inputs, not retained attributes. The line keeps its drawing and the defaults used by later tick and label methods; the numbers to exclude and those with elongated ticks are kept as the lists they were when it was made.

m.NumberLine(x_range=None, length=None, unit_size=1, include_ticks=True, tick_size=0.1, numbers_with_elongated_ticks=None, longer_tick_multiple=2, exclude_origin_tick=False, rotation=0, include_tip=False, tip_width=DEFAULT_ARROW_TIP_LENGTH, tip_height=DEFAULT_ARROW_TIP_LENGTH, tip_shape=None, include_numbers=False, font_size=36, label_direction=DOWN, label_constructor=MathTex, scaling=_AXIS_LINEAR, line_to_number_buff=MED_SMALL_BUFF, decimal_number_config=None, numbers_to_exclude=None, numbers_to_include=None, **kwargs)
x_range

The range, [x_min, x_max, x_step], or [x_min, x_max] for a step of 1; None for [-7, 7, 1].

length

The line's length, in scene units; None for unit_size per unit.

unit_size

The length of one unit, in scene units, when length is None.

include_ticks

Whether to draw the ticks.

tick_size

How far each tick reaches on either side of the line, in scene units: half its length.

numbers_with_elongated_ticks

The numbers whose ticks are longer; None for none.

longer_tick_multiple

How many times longer those ticks are.

exclude_origin_tick

Whether to leave out the tick at 0.

rotation

The angle the line is turned through about its center, in radians, counterclockwise.

include_tip

Whether the line ends in an arrow tip, at its end.

tip_width

The tip's width, in scene units.

tip_height

The tip's length, along the line, in scene units.

tip_shape

The class of the tip; None for ArrowTriangleFilledTip.

include_numbers

Whether to number the ticks (see add_numbers).

font_size

The numbers' font size.

label_direction

The side of the line the numbers go on, as a direction: DOWN for below.

label_constructor

The class the numbers and labels are typeset with: MathTex, MathTypst, ….

scaling

How numbers are spaced along the line: evenly, with LinearBase, or by their logarithms, with LogBase (its numbers are then written as powers).

line_to_number_buff

The gap between the line and its numbers, in scene units.

decimal_number_config

The numbers' number keywords; None for as many decimal places as x_step has.

numbers_to_exclude

Numbers not to write, when the ticks are numbered; None for none.

numbers_to_include

The numbers to write, instead of the ticks': given, they are written even without include_numbers. None for the ticks'.

color

The color of both fill and stroke (default white; a Circle's is red); None for the class's default.

tip_length

The length of the tips add_tip makes, in scene units (default 0.35; an Arrow's may be shorter).

normal_vector

The normal of the plane the path lies in (default OUT). Accepted for Manim compatibility; ignored and not retained.

tip_style

Style keywords for the tips the path makes (default None: none). A tip's fill_color and stroke_color are the path's color unless given here.

fill_color

The fill's color; color if not given. Several colors make a gradient along sheen_direction.

fill_opacity

The fill's opacity, from 0 to 1 (default 0: no fill).

stroke_color

The stroke's color; color if not given. Several colors make a gradient.

stroke_opacity

The stroke's opacity, from 0 to 1 (default 1).

stroke_width

The stroke's width, in hundredths of a scene unit (default 4; 0: no stroke).

background_stroke_color

The color of an outline drawn behind the fill (default black).

background_stroke_opacity

The outline's opacity, from 0 to 1 (default 1).

background_stroke_width

The outline's width, in hundredths of a scene unit (default 0: none).

sheen_factor

How much the colors lighten toward sheen_direction, from -1 to 1 (default 0); a negative factor darkens.

sheen_direction

The direction the colors lighten toward (default UL).

joint_type

How the stroke is joined where its path turns: round, beveled or mitered, as a two-dimensional scene draws it (see LineJointType; default AUTO: mitered).

cap_style

How the stroke ends, at each end it shows (an open path's, a dash's): round, butt or square, as a two-dimensional scene draws it (see CapStyleType; default AUTO: butt).

shade_in_3d

Whether a three-dimensional scene's light shades the mobject.

material

How its surface reflects the scene's lights in a three-dimensional scene (see Material); None: Manim's shading (default).

name

A name for the mobject; its class's name if not given.

z_index

Its place in the drawing order: a higher index is drawn over a lower one (default 0).

target

The state MoveToTarget moves the mobject to.

It also takes the tip keywords.

Source

src/manimgx/mobjects/plotting.py

def __init__(
    self,
    x_range: Sequence[float] | None = None,
    length: float | None = None,
    unit_size: float = 1,
    include_ticks: bool = True,
    tick_size: float = 0.1,
    numbers_with_elongated_ticks: Iterable[float] | None = None,
    longer_tick_multiple: int = 2,
    exclude_origin_tick: bool = False,
    rotation: float = 0,
    include_tip: bool = False,
    tip_width: float = DEFAULT_ARROW_TIP_LENGTH,
    tip_height: float = DEFAULT_ARROW_TIP_LENGTH,
    tip_shape: type[ArrowTip] | None = None,
    include_numbers: bool = False,
    font_size: float = 36,
    label_direction: Vector3DLike = DOWN,
    label_constructor: type[ManimTextLabel] = MathTex,
    scaling: _ScaleBase = _AXIS_LINEAR,
    line_to_number_buff: float = MED_SMALL_BUFF,
    decimal_number_config: DecimalNumberOptions | None = None,
    numbers_to_exclude: Iterable[float] | None = None,
    numbers_to_include: Iterable[float] | None = None,
    **kwargs: Unpack[Tipped],
):
    # values, as they are given: what the line keeps is its own
    numbers_to_exclude = (
        [] if numbers_to_exclude is None else list(numbers_to_exclude)
    )
    numbers_with_elongated_ticks = (
        []
        if numbers_with_elongated_ticks is None
        else list(numbers_with_elongated_ticks)
    )
    if x_range is None:
        x_range = [
            round(-config.frame_x_radius),
            round(config.frame_x_radius),
            1,
        ]
    elif len(x_range) == 2:
        x_range = [*x_range, 1]
    if decimal_number_config is None:
        decimal_number_config = {
            "num_decimal_places": self._decimal_places_from_step(x_range[2])
        }
    self.x_range = np.array(x_range, dtype=float)
    """The line's range, `[x_min, x_max, x_step]`, as given: of exponents, on a
    logarithmic line."""
    self.x_min: float
    """The line's number at its start: the first of its range, scaled (10⁰ = 1 for
    a range from 0, on a logarithmic line)."""
    self.x_max: float
    """The line's number at its end: the second of its range, scaled."""
    self.x_step: float
    """The step of its range, scaled."""
    self.x_min, self.x_max, self.x_step = scaling.function(self.x_range)
    self.unit_size = unit_size
    """The length of one unit, in scene units, as the line was made; see
    [get_unit_size][manimgx.NumberLine.get_unit_size] for its length now."""
    self.tick_size = tick_size
    self.numbers_with_elongated_ticks = numbers_with_elongated_ticks
    self.longer_tick_multiple = longer_tick_multiple
    self.exclude_origin_tick = exclude_origin_tick
    self.include_tip = include_tip
    self.font_size = font_size
    self.label_direction = label_direction
    self.label_constructor = label_constructor
    self.line_to_number_buff = line_to_number_buff
    self.decimal_number_config = decimal_number_config
    self.numbers_to_exclude = numbers_to_exclude
    self.scaling = scaling
    """How the line's numbers are spaced along it."""
    super().__init__(self.x_range[0] * RIGHT, self.x_range[1] * RIGHT, **kwargs)
    if length:
        self.set_length(length)
        self.unit_size = self.get_unit_size()
    else:
        self.scale(self.unit_size)
    self.center()
    if self.include_tip:
        self.add_tip(
            tip_length=tip_height,
            tip_width=tip_width,
            tip_shape=tip_shape,
        )
        self.tip.set_stroke(self.stroke_color, self.stroke_width)
    if include_ticks:
        self.add_ticks()
    self.rotate(rotation)
    if include_numbers or numbers_to_include is not None:
        if self.scaling.custom_labels:
            tick_range = self.get_tick_range()
            custom_labels = self.scaling.get_custom_labels(
                tick_range,
                unit_decimal_places=decimal_number_config.get(
                    "num_decimal_places", 0
                ),
            )
            self.add_labels(dict(zip(tick_range, custom_labels, strict=True)))
        else:
            self.add_numbers(
                x_values=numbers_to_include, excluding=self.numbers_to_exclude
            )

x_range

The line's range, [x_min, x_max, x_step], as given: of exponents, on a logarithmic line.

x_min

The line's number at its start: the first of its range, scaled (10⁰ = 1 for a range from 0, on a logarithmic line).

x_max

The line's number at its end: the second of its range, scaled.

x_step

The step of its range, scaled.

unit_size

The length of one unit, in scene units, as the line was made; see get_unit_size for its length now.

scaling

How the line's numbers are spaced along it.

rotate_about_zero

Turn the line about the point of its number 0.

number_line.rotate_about_zero(angle, axis=OUT)
angle

The angle, in radians, counterclockwise about axis.

axis

The axis of the turn: OUT turns it in the plane of the screen.

Source

src/manimgx/mobjects/plotting.py

def rotate_about_zero(self, angle: float, axis: Vector3DLike = OUT) -> Self:
    """Turn the line about the point of its number 0.

    Args:
        angle: The angle, in radians, counterclockwise about `axis`.
        axis: The axis of the turn: OUT turns it in the plane of the screen.
    """
    return self.rotate_about_number(0, angle, axis)

rotate_about_number

Turn the line about the point of one of its numbers.

number_line.rotate_about_number(number, angle, axis=OUT)
number

The number whose point stays fixed.

angle

The angle, in radians, counterclockwise about axis.

axis

The axis of the turn: OUT turns it in the plane of the screen.

Source

src/manimgx/mobjects/plotting.py

def rotate_about_number(
    self, number: float, angle: float, axis: Vector3DLike = OUT
) -> Self:
    """Turn the line about the point of one of its numbers.

    Args:
        number: The number whose point stays fixed.
        angle: The angle, in radians, counterclockwise about `axis`.
        axis: The axis of the turn: OUT turns it in the plane of the screen.
    """
    return self.rotate(angle, axis, about_point=self.n2p(number))

number_to_point

Code
import manimgx as m


class NumberLineNumberToPointExample(m.Scene):
    def construct(self) -> None:
        line = m.NumberLine(
            x_range=[-4, 4, 1], length=12, include_numbers=True
        )
        dot = m.Dot(line.n2p(-3), radius=0.15, color=m.YELLOW)
        self.add(line, dot)
        self.play(dot.animate.move_to(line.n2p(2.5)))

Convert a number to its point on the line, or numbers to their points.

A number outside the range is on the line extended past its ends.

number_line.number_to_point(number)
number

The number; or an array of numbers, of any shape.

Returns The point, in scene coordinates; for an array, the points, with the coordinates last (the array's shape, then 3).

Source

src/manimgx/mobjects/plotting.py

def number_to_point(self, number: float | np.ndarray) -> np.ndarray:
    """Convert a number to its point on the line, or numbers to their points.

    A number outside the range is on the line extended past its ends.

    Args:
        number: The number; or an array of numbers, of any shape.

    Returns:
        The point, in scene coordinates; for an array, the points, with the
        coordinates last (the array's shape, then 3).

    Examples:
        ```python
        import manimgx as m


        class NumberLineNumberToPointExample(m.Scene):
            def construct(self) -> None:
                line = m.NumberLine(
                    x_range=[-4, 4, 1], length=12, include_numbers=True
                )
                dot = m.Dot(line.n2p(-3), radius=0.15, color=m.YELLOW)
                self.add(line, dot)
                self.play(dot.animate.move_to(line.n2p(2.5)))
        ```
    """
    number = self.scaling.inverse_function(np.asarray(number, dtype=float))
    alphas = (number - self.x_range[0]) / (self.x_range[1] - self.x_range[0])
    start, end = self.get_start(), self.get_end()
    a = np.asarray(alphas)[..., None]
    return (1 - a) * start + a * end

point_to_number

Convert a point to the number at its projection on the line: the inverse of number_to_point for points on the line.

number_line.point_to_number(point)
point

The point, in scene coordinates.

Source

src/manimgx/mobjects/plotting.py

def point_to_number(self, point: Point3DLike) -> float:
    """Convert a point to the number at its projection on the line: the inverse of
    [number_to_point][manimgx.NumberLine.number_to_point] for points on the line.

    Args:
        point: The point, in scene coordinates.
    """
    point = np.asarray(point, dtype=float)
    start, end = self.get_start(), self.get_end()
    unit_vect = normalize(end - start)
    proportion: float = np.dot(point - start, unit_vect) / np.dot(
        end - start, unit_vect
    )
    # along the range, then through the scale, as number_to_point goes back
    return self.scaling.function(
        interpolate(self.x_range[0], self.x_range[1], proportion)
    )

n2p

Convert a number to its point on the line: number_to_point, by a shorter name.

number_line.n2p(number)
number

The number; or an array of numbers, of any shape.

Returns The point, in scene coordinates; or the points.

Source

src/manimgx/mobjects/plotting.py

def n2p(self, number: float | np.ndarray) -> Point3D:
    """Convert a number to its point on the line:
    [number_to_point][manimgx.NumberLine.number_to_point], by a shorter name.

    Args:
        number: The number; or an array of numbers, of any shape.

    Returns:
        The point, in scene coordinates; or the points.
    """
    return self.number_to_point(number)

get_unit_size

The length of one unit of the line: its length over its range.

number_line.get_unit_size()

Returns The length, in scene units (of one unit of exponent, on a logarithmic line).

Source

src/manimgx/mobjects/plotting.py

def get_unit_size(self) -> float:
    """The length of one unit of the line: its length over its range.

    Returns:
        The length, in scene units (of one unit of exponent, on a logarithmic
        line).
    """
    val: float = self.get_length() / (self.x_range[1] - self.x_range[0])
    return val

get_unit_vector

The line's direction, one unit long: the vector from its start toward its end, as long as the unit the line was made with (its unit_size).

number_line.get_unit_vector()

Returns The vector, in scene units.

Source

src/manimgx/mobjects/plotting.py

def get_unit_vector(self) -> Vector3D:
    """The line's direction, one unit long: the vector from its start toward its
    end, as long as the unit the line was made with (its `unit_size`).

    Returns:
        The vector, in scene units.
    """
    return super().get_unit_vector() * self.unit_size

get_number_mobject

Make a number, written beside its point on the line.

It is a DecimalNumber in the line's number style (its decimal_number_config and font_size), with number_config over it. A negative number written straight below or above the line is shifted so its digits, not its minus sign, are centered on the point.

number_line.get_number_mobject(x, direction=None, buff=None, label_constructor=None, **number_config)
x

The number.

direction

The side of the line it goes on; None for the line's label_direction.

buff

The gap between the line and the number, in scene units; None for the line's line_to_number_buff.

label_constructor

The class it is typeset with; None for the line's.

It also takes the DecimalNumber keywords.

Returns A new number, not added to the line.

Source

src/manimgx/mobjects/plotting.py

def get_number_mobject(
    self,
    x: float,
    direction: Vector3DLike | None = None,
    buff: float | None = None,
    label_constructor: type[ManimTextLabel] | None = None,
    **number_config: Unpack[DecimalNumberOptions],
) -> VMobject:
    """Make a number, written beside its point on the line.

    It is a [DecimalNumber][manimgx.DecimalNumber] in the line's number style (its
    `decimal_number_config` and `font_size`), with `number_config` over it. A
    negative number written straight below or above the line is shifted so its
    digits, not its minus sign, are centered on the point.

    Args:
        x: The number.
        direction: The side of the line it goes on; None for the line's
            `label_direction`.
        buff: The gap between the line and the number, in scene units; None for the
            line's `line_to_number_buff`.
        label_constructor: The class it is typeset with; None for the line's.
        **number_config: [Number keywords][manimgx.DecimalNumber],
            over the line's.

    Returns:
        A new number, not added to the line.
    """
    options = self.decimal_number_config | number_config
    options.setdefault("font_size", self.font_size)
    options["mob_class"] = label_constructor or self.label_constructor
    num_mob = DecimalNumber(x, **options)
    num_mob.next_to(
        self.number_to_point(x),
        direction=self.label_direction if direction is None else direction,
        buff=self.line_to_number_buff if buff is None else buff,
    )
    if x < 0 and self.label_direction[0] == 0:
        num_mob.shift(num_mob[0].width * LEFT / 2)
    return num_mob

add_numbers

NumberLineAddNumbersExample
Code
import manimgx as m


class NumberLineAddNumbersExample(m.Scene):
    def construct(self) -> None:
        ticks = m.NumberLine(x_range=[0, 10, 1], length=12).add_numbers()
        chosen = m.NumberLine(x_range=[0, 10, 1], length=12, color=m.BLUE)
        chosen.add_numbers(
            [0, 2.5, 5, 7.5, 10], num_decimal_places=1, color=m.BLUE
        )
        self.add(m.VGroup(ticks, chosen).arrange(m.DOWN, buff=1.5))

Number the line: write numbers beside the points of the given values, or of its ticks.

Each number is written as get_number_mobject writes it. The numbers are a group added to the line, and kept as its numbers.

number_line.add_numbers(x_values=None, excluding=None, label_constructor=None, **kwargs)
x_values

The numbers to write; None for the ticks' numbers.

excluding

Numbers not to write; None for the line's numbers_to_exclude.

label_constructor

The class they are typeset with; None for the line's.

It also takes the DecimalNumber keywords.

Source

src/manimgx/mobjects/plotting.py

def add_numbers(
    self,
    x_values: Iterable[float] | None = None,
    excluding: Iterable[float] | None = None,
    label_constructor: type[ManimTextLabel] | None = None,
    **kwargs: Unpack[DecimalNumberOptions],
) -> Self:
    """Number the line: write numbers beside the points of the given values, or of
    its ticks.

    Each number is written as
    [get_number_mobject][manimgx.NumberLine.get_number_mobject] writes it. The
    numbers are a group added to the line, and kept as its `numbers`.

    Args:
        x_values: The numbers to write; None for the ticks' numbers.
        excluding: Numbers not to write; None for the line's `numbers_to_exclude`.
        label_constructor: The class they are typeset with; None for the line's.
        **kwargs: [Number keywords][manimgx.DecimalNumber],
            over the line's: `font_size`, `num_decimal_places`, `color`, ….

    Examples:
        ```python
        import manimgx as m


        class NumberLineAddNumbersExample(m.Scene):
            def construct(self) -> None:
                ticks = m.NumberLine(x_range=[0, 10, 1], length=12).add_numbers()
                chosen = m.NumberLine(x_range=[0, 10, 1], length=12, color=m.BLUE)
                chosen.add_numbers(
                    [0, 2.5, 5, 7.5, 10], num_decimal_places=1, color=m.BLUE
                )
                self.add(m.VGroup(ticks, chosen).arrange(m.DOWN, buff=1.5))
        ```
    """
    if x_values is None:
        x_values = self.get_tick_range()
    excluded = list(self.numbers_to_exclude if excluding is None else excluding)
    numbers = VGroup()
    for x in x_values:
        if x in excluded:
            continue
        numbers.add(
            self.get_number_mobject(
                x, label_constructor=label_constructor, **kwargs
            )
        )
    self.add(numbers)
    self.numbers = numbers
    return self

add_labels

NumberLineAddLabelsExample
Code
import manimgx as m


class NumberLineAddLabelsExample(m.Scene):
    def construct(self) -> None:
        line = m.NumberLine(x_range=[0, m.TAU, m.PI / 2], length=12)
        line.add_labels(
            {
                0: "0",
                m.PI / 2: m.MathTex(r"\frac{\pi}{2}"),
                m.PI: m.MathTex(r"\pi"),
                3 * m.PI / 2: m.MathTex(r"\frac{3\pi}{2}"),
                m.TAU: m.MathTex(r"2\pi"),
            },
            font_size=44,
        )
        self.add(line)

Label the line: put each label beside the point of its number.

A string is typeset as text with Tex when the constructor is MathTex (as by default), and with the constructor otherwise; a number is written with the constructor. A mobject is used as it is, and must be typeset (a Typst mobject: Text, Tex, MathTex, …) or a DecimalNumber: another raises an exception. Every label is set to font_size. The labels are a group added to the line, and kept as its labels.

number_line.add_labels(dict_values, direction=None, buff=None, font_size=None, label_constructor=None)
dict_values

The labels, by number.

direction

The side of the line they go on, as a direction; None for the line's label_direction.

buff

The gap between the line and the labels, in scene units; None for the line's line_to_number_buff.

font_size

The labels' font size; None for the line's.

label_constructor

The class strings and numbers are typeset with; None for the line's.

Source

src/manimgx/mobjects/plotting.py

def add_labels(
    self,
    dict_values: Mapping[float, Label],
    direction: Point3DLike | None = None,
    buff: float | None = None,
    font_size: float | None = None,
    label_constructor: type[ManimTextLabel] | None = None,
) -> Self:
    r"""Label the line: put each label beside the point of its number.

    A string is typeset as text with [Tex][manimgx.Tex] when the constructor is
    [MathTex][manimgx.MathTex] (as by default), and with the constructor otherwise;
    a number is written with the constructor. A mobject is used as it is, and must
    be typeset (a [Typst][manimgx.Typst] mobject: [Text][manimgx.Text],
    [Tex][manimgx.Tex], [MathTex][manimgx.MathTex], …) or a
    [DecimalNumber][manimgx.DecimalNumber]: another raises an exception. Every label
    is set to `font_size`. The labels are a group added to the line, and kept as its
    `labels`.

    Args:
        dict_values: The labels, by number.
        direction: The side of the line they go on, as a direction; None for the
            line's `label_direction`.
        buff: The gap between the line and the labels, in scene units; None for the
            line's `line_to_number_buff`.
        font_size: The labels' font size; None for the line's.
        label_constructor: The class strings and numbers are typeset with; None for
            the line's.

    Examples:
        ```python
        import manimgx as m


        class NumberLineAddLabelsExample(m.Scene):
            def construct(self) -> None:
                line = m.NumberLine(x_range=[0, m.TAU, m.PI / 2], length=12)
                line.add_labels(
                    {
                        0: "0",
                        m.PI / 2: m.MathTex(r"\frac{\pi}{2}"),
                        m.PI: m.MathTex(r"\pi"),
                        3 * m.PI / 2: m.MathTex(r"\frac{3\pi}{2}"),
                        m.TAU: m.MathTex(r"2\pi"),
                    },
                    font_size=44,
                )
                self.add(line)
        ```
    """
    direction = self.label_direction if direction is None else direction
    buff = self.line_to_number_buff if buff is None else buff
    font_size = self.font_size if font_size is None else font_size
    if label_constructor is None:
        label_constructor = self.label_constructor
    labels = VGroup()
    for x, label in dict_values.items():
        if isinstance(label, str):
            if label_constructor is MathTex:
                label = Tex(label)
            else:
                label = self._create_label_tex(label, label_constructor)
        else:
            label = self._create_label_tex(label, label_constructor)
        if not isinstance(
            label, (Typst, DecimalNumber)
        ):  # its type size can be set
            raise AttributeError(f"{label} is not compatible with add_labels.")
        label.font_size = font_size
        label.next_to(self.number_to_point(x), direction=direction, buff=buff)
        labels.add(label)
    self.labels = labels
    self.add(labels)
    return self

UnitInterval

Code
import manimgx as m


class UnitIntervalExample(m.Scene):
    def construct(self) -> None:
        interval = m.UnitInterval(include_numbers=True, font_size=28)
        dot = m.Dot(interval.n2p(0.25), radius=0.12, color=m.YELLOW)
        self.add(interval, dot)
        self.play(dot.animate.move_to(interval.n2p(0.8)))

The unit interval: a number line from 0 to 1, with a tick every tenth; 10 units long, its ticks at 0 and 1 longer, unless told otherwise.

Its numbers, when it has them, have one decimal place.

m.UnitInterval(**kwargs)

It also takes the NumberLine keywords.

Source

src/manimgx/mobjects/plotting.py

def __init__(self, **kwargs: Unpack[NumberLineOptions]):
    kwargs.setdefault("unit_size", 10)
    kwargs.setdefault("numbers_with_elongated_ticks", [0, 1])
    kwargs.setdefault("decimal_number_config", {"num_decimal_places": 1})
    super().__init__(x_range=(0, 1, 0.1), **kwargs)

Scales

A line's scale places its numbers: evenly, or by their logarithms. Give it as scaling.

LinearBase

LinearBaseExample
Code
import manimgx as m


class LinearBaseExample(m.Scene):
    def construct(self) -> None:
        plain = m.NumberLine(
            x_range=[-3, 3, 1], length=10, include_numbers=True
        )
        doubled = m.NumberLine(
            x_range=[-3, 3, 1],
            length=10,
            include_numbers=True,
            scaling=m.LinearBase(scale_factor=2),
            color=m.BLUE,
        )
        self.add(m.VGroup(plain, doubled).arrange(m.DOWN, buff=1.5))

An even scale for a number line: its numbers evenly spaced along it, the numbers of its range times scale_factor.

It is a number line's default scale, and with a factor of 1 its numbers are those of its range. With another factor, the line keeps its length and its ticks, and its numbers are multiplied: with 2, a range [-2, 2, 1] is numbered from -4 to 4 in steps of 2, and n2p places 4 at its end. Give it as a number line's scaling, or an axis's in an axis config.

m.LinearBase(scale_factor=1.0)
scale_factor

The factor from the numbers of the range to the numbers of the line.

Source

src/manimgx/mobjects/plotting.py

def __init__(self, scale_factor: float = 1.0):
    super().__init__()
    self.scale_factor = scale_factor
    """The factor from the numbers of the range to the numbers of the line."""

scale_factor

The factor from the numbers of the range to the numbers of the line.

function

The number of the axis at a value of its range: 10² for 2, on a logarithmic axis.

linear_base.function(value)
value

The value of the range; or an array of values.

Returns The number; or the numbers, an array of the same shape.

Source

src/manimgx/mobjects/plotting.py

def function(self, value: float | np.ndarray) -> float | np.ndarray:
    """The number of the axis at a value of its range: 10² for 2, on a logarithmic
    axis.

    Args:
        value: The value of the range; or an array of values.

    Returns:
        The number; or the numbers, an array of the same shape.
    """
    return self._function(value)

inverse_function

The value of the axis's range at one of its numbers: 2 for 100, on a logarithmic axis; the inverse of function.

linear_base.inverse_function(value)
value

The number; or an array of numbers.

Returns The value of the range; or the values, an array of the same shape.

Source

src/manimgx/mobjects/plotting.py

def inverse_function(self, value: float | np.ndarray) -> float | np.ndarray:
    """The value of the axis's range at one of its numbers: 2 for 100, on a
    logarithmic axis; the inverse of `function`.

    Args:
        value: The number; or an array of numbers.

    Returns:
        The value of the range; or the values, an array of the same shape.
    """
    return self._inverse_function(value)

LogBase

LogBaseExample
Code
import manimgx as m


class LogBaseExample(m.Scene):
    def construct(self) -> None:
        ax = m.Axes(
            x_range=[0, 10, 1],
            y_range=[-2, 6, 1],
            x_length=11,
            y_length=6.5,
            tips=False,
            axis_config={"include_numbers": True, "font_size": 28},
            y_axis_config={"scaling": m.LogBase()},
        )
        exponential = ax.plot(lambda x: 0.01 * 10 ** (0.8 * x), color=m.BLUE)
        square = ax.plot(lambda x: x**2, x_range=[0.1, 10], color=m.YELLOW)
        self.add(ax, exponential, square)

A logarithmic scale for a number line: its range is of exponents, and its numbers are powers of base, spaced by their logarithms.

With base 10, a range [0, 3, 1] runs from 1 to 1000, a tick at each power of 10, and n2p places 100 two thirds of the way along. Its numbers are all positive: 0 and negative numbers have no place on it. Give it as a number line's scaling, or an axis's in an axis config; then plot samples a function over the powers, and add_coordinates writes the axis's numbers as powers.

m.LogBase(base=10, custom_labels=True)
base

The base of the powers.

custom_labels

Whether the line's numbers are written as powers (10², 10³, …), rather than as decimals.

Source

src/manimgx/mobjects/plotting.py

def __init__(self, base: float = 10, custom_labels: bool = True):
    super().__init__()
    self.base = base
    """The base of the powers."""
    self.custom_labels = custom_labels
    """Whether the line's numbers are written as powers of the base."""

base

The base of the powers.

custom_labels

Whether the line's numbers are written as powers of the base.

function

The number of the axis at a value of its range: 10² for 2, on a logarithmic axis.

log_base.function(value)
value

The value of the range; or an array of values.

Returns The number; or the numbers, an array of the same shape.

Source

src/manimgx/mobjects/plotting.py

def function(self, value: float | np.ndarray) -> float | np.ndarray:
    """The number of the axis at a value of its range: 10² for 2, on a logarithmic
    axis.

    Args:
        value: The value of the range; or an array of values.

    Returns:
        The number; or the numbers, an array of the same shape.
    """
    return self._function(value)

inverse_function

The value of the axis's range at one of its numbers: 2 for 100, on a logarithmic axis; the inverse of function.

log_base.inverse_function(value)
value

The number; or an array of numbers.

Returns The value of the range; or the values, an array of the same shape.

Source

src/manimgx/mobjects/plotting.py

def inverse_function(self, value: float | np.ndarray) -> float | np.ndarray:
    """The value of the axis's range at one of its numbers: 2 for 100, on a
    logarithmic axis; the inverse of `function`.

    Args:
        value: The number; or an array of numbers.

    Returns:
        The value of the range; or the values, an array of the same shape.
    """
    return self._inverse_function(value)