manim.mobject.mobject.Mobject

class Mobject(color='#FFFFFF', name=None, dim=3, target=None, z_index=0, **kwargs)[source]

Bases: manim.container.Container

Mathematical Object: base class for objects that can be displayed on screen.

There is a compatibility layer that allows for getting and setting generic attributes with get_* and set_* methods. See set() for more details.

submobjects[source]

The contained objects.

Type

List[Mobject]

points[source]

The points of the objects.

Type

numpy.ndarray

Methods

add

Add mobjects as submobjects.

add_background_rectangle

Add a BackgroundRectangle as submobject.

add_background_rectangle_to_family_members_with_points

add_background_rectangle_to_submobjects

add_n_more_submobjects

add_to_back

Add all passed mobjects to the back of the submobjects.

add_updater

Add an update function to this mobject.

align_data

align_on_border

Direction just needs to be a vector pointing towards side or corner in the 2d plane.

align_points

align_points_with_larger

align_submobjects

align_to

Examples: mob1.align_to(mob2, UP) moves mob1 vertically so that its top edge lines ups with mob2’s top edge.

apply_complex_function

apply_function

apply_function_to_position

apply_function_to_submobject_positions

apply_matrix

apply_over_attr_arrays

apply_points_function

apply_points_function_about_point

apply_to_family

Apply a function to self and every submobject with points recursively.

arrange

Sorts mobjects next to each other on screen.

arrange_in_grid

arrange_submobjects

become

Edit points, colors and submobjects to be identical to another Mobject

center

clear_updaters

Remove every updater.

compute_bounding_box

copy

Create and return an identical copy of the Mobject including all submobjects.

fade

fade_to

family_members_with_points

flip

Flips/Mirrors an mobject about its center.

generate_points

Initializes points and therefore the shape.

generate_target

get_all_points

get_array_attrs

get_bottom

Get bottom coordinates of a box bounding the Mobject

get_boundary_point

get_bounding_box

get_center

Get center coordinates

get_center_of_mass

get_color

get_coord

Meant to generalize get_x, get_y and get_z

get_corner

get_critical_point

Picture a box bounding the Mobject.

get_edge_center

get_end

Returns the point, where the stroke that surrounds the Mobject ends.

get_extremum_along_dim

get_family

get_family_updaters

get_group_class

get_image

get_left

Get left coordinates of a box bounding the Mobject

get_merged_array

get_nadir

get_num_points

get_pieces

get_point_mobject

The simplest Mobject to be transformed to or from self.

get_points_defining_boundary

get_right

Get right coordinates of a box bounding the Mobject

get_start

Returns the point, where the stroke that surrounds the Mobject starts.

get_start_and_end

Returns starting and ending point of a stroke as a tuple.

get_time_based_updaters

Return all updaters using the dt parameter.

get_top

Get top coordinates of a box bounding the Mobject

get_updaters

Return all updaters.

get_x

Returns x coordinate of the center of the Mobject as float

get_y

Returns y coordinate of the center of the Mobject as float

get_z

Returns z coordinate of the center of the Mobject as float

get_z_index_reference_point

get_zenith

has_no_points

has_points

Check if Mobject contains points.

has_time_based_updater

Test if self has a time based updater.

init_colors

Initializes the colors.

init_gl_colors

init_gl_data

init_gl_points

interpolate

Turns this Mobject into an interpolation between mobject1 and mobject2.

interpolate_color

invert

is_off_screen

length_over_dim

Measure the length of an Mobject in a certain direction.

match_color

match_coord

match_depth

match_dim_size

match_height

match_updaters

Match the updaters of the given mobject.

match_width

match_x

match_y

match_z

move_to

Move center of the Mobject to certain coordinate.

next_to

Move this Mobject next to another’s Mobject or coordinate.

nonempty_submobjects

null_point_align

If a Mobject with points is being aligned to one without, treat both as groups, and push the one with points into its own submobjects list.

point_from_proportion

pointwise_become_partial

pose_at_angle

push_self_into_submobjects

put_start_and_end_on

reduce_across_dimension

refresh_bounding_box

remove

Remove submobjects.

remove_updater

Remove an updater.

repeat

This can make transition animations nicer

repeat_submobject

replace

rescale_to_fit

reset_points

Sets points to be an empty array.

restore

Restores the state that was previously saved with save_state().

resume_updating

Enable updating from updaters and animations.

reverse_points

rotate

Rotates the Mobject about a certain point.

rotate_about_origin

Rotates the Mobject about the ORIGIN, which is at [0,0,0].

rotate_in_place

save_image

save_state

Save the current state (position, color & size).

scale

Scale the size by a factor.

scale_about_point

scale_in_place

scale_to_fit_depth

Scales the Mobject to fit a depth while keeping width/height proportional.

scale_to_fit_height

Scales the Mobject to fit a height while keeping width/depth proportional.

scale_to_fit_width

Scales the Mobject to fit a width while keeping height/depth proportional.

set

Sets attributes.

set_color

Condition is function which takes in one arguments, (x, y, z).

set_color_by_gradient

set_colors_by_radial_gradient

set_coord

set_submobject_colors_by_gradient

set_submobject_colors_by_radial_gradient

set_x

Set x value of the center of the Mobject (int or float)

set_y

Set y value of the center of the Mobject (int or float)

set_z

Set z value of the center of the Mobject (int or float)

set_z_index

Sets the Mobject’s z_index to the value specified in z_index_value.

set_z_index_by_z_coordinate

Sets the Mobject’s z coordinate to the value of z_index.

shift

Shift by the given vectors.

shift_onto_screen

show

shuffle

shuffle_submobjects

sort

sort_submobjects

space_out_submobjects

split

stretch

stretch_about_point

stretch_in_place

stretch_to_fit_depth

Stretches the Mobject to fit a depth, not keeping width/height proportional.

stretch_to_fit_height

Stretches the Mobject to fit a height, not keeping width/depth proportional.

stretch_to_fit_width

Stretches the Mobject to fit a width, not keeping height/depth proportional.

surround

suspend_updating

Disable updating from updaters and animations.

throw_error_if_no_points

to_corner

to_edge

to_original_color

update

Apply all updaters.

wag

Attributes

animate

Used to animate the application of a method.

depth

The depth of the mobject.

height

The height of the mobject.

width

The width of the mobject.

add(*mobjects)[source]

Add mobjects as submobjects.

The mobjects are added to submobjects.

Subclasses of mobject may implement + and += dunder methods.

Parameters

mobjects (manim.mobject.mobject.Mobject) – The mobjects to add.

Returns

self

Return type

Mobject

Raises
  • ValueError – When a mobject tries to add itself.

  • TypeError – When trying to add an object that is not an instance of Mobject.

Notes

A mobject cannot contain itself, and it cannot contain a submobject more than once. If the parent mobject is displayed, the newly-added submobjects will also be displayed (i.e. they are automatically added to the parent Scene).

Examples

>>> outer = Mobject()
>>> inner = Mobject()
>>> outer = outer.add(inner)

Duplicates are not added again:

>>> outer = outer.add(inner)
>>> len(outer.submobjects)
1

Adding an object to itself raises an error:

>>> outer.add(outer)
Traceback (most recent call last):
...
ValueError: Mobject cannot contain self
add_background_rectangle(color='#000000', opacity=0.75, **kwargs)[source]

Add a BackgroundRectangle as submobject.

The BackgroundRectangle is added behind other submobjects.

This can be used to increase the mobjects visibility in front of a noisy background.

Parameters
  • color (manim.utils.color.Colors) – The color of the BackgroundRectangle

  • opacity (float) – The opacity of the BackgroundRectangle

  • kwargs – Additional keyword arguments passed to the BackgroundRectangle constructor

Returns

self

Return type

Mobject

add_to_back(*mobjects)[source]

Add all passed mobjects to the back of the submobjects.

If submobjects already contains the given mobjects, they just get moved to the back instead.

Parameters

mobjects (manim.mobject.mobject.Mobject) – The mobjects to add.

Returns

self

Return type

Mobject

Note

Technically, this is done by adding (or moving) the mobjects to the head of submobjects. The head of this list is rendered first, which places the corresponding mobjects behind the subsequent list members.

add_updater(update_function, index=None, call_updater=False)[source]

Add an update function to this mobject.

Update functions, or updaters in short, are functions that are applied to the Mobject in every frame.

Parameters
  • update_function (Union[Callable[[Mobject], None], Callable[[Mobject, float], None]]) – The update function to be added. Whenever update() is called, this update function gets called using self as the first parameter. The updater can have a second parameter dt. If it uses this parameter, it gets called using a second value dt, usually representing the time in seconds since the last call of update().

  • index (Optional[int]) – The index at which the new updater should be added in self.updaters. In case index is None the updater will be added at the end.

  • call_updater (bool) – Wheather or not to call the updater initially. If True, the updater will be called using dt=0.

Returns

self

Return type

Mobject

Examples

NextToUpdater
class NextToUpdater(Scene):
    def construct(self):
        def dot_position(mobject):
            mobject.set_value(dot.get_center()[0])
            mobject.next_to(dot)

        dot = Dot(RIGHT*3)
        label = DecimalNumber()
        label.add_updater(dot_position)
        self.add(dot, label)

        self.play(Rotating(dot, about_point=ORIGIN, angle=TAU, run_time=TAU, rate_func=linear))
DtUpdater
class DtUpdater(Scene):
    def construct(self):
        line = Square()

        #Let the line rotate 90° per second
        line.add_updater(lambda mobject, dt: mobject.rotate(dt*90*DEGREES))
        self.add(line)
        self.wait(2)
align_on_border(direction, buff=0.5)[source]

Direction just needs to be a vector pointing towards side or corner in the 2d plane.

align_to(mobject_or_point, direction=array([0.0, 0.0, 0.0]), alignment_vect=array([0.0, 1.0, 0.0]))[source]

Examples: mob1.align_to(mob2, UP) moves mob1 vertically so that its top edge lines ups with mob2’s top edge.

mob1.align_to(mob2, alignment_vect = RIGHT) moves mob1 horizontally so that it’s center is directly above/below the center of mob2

Parameters

mobject_or_point (Union[Mobject, numpy.ndarray, List]) –

property animate[source]

Used to animate the application of a method.

Warning

Passing multiple animations for the same Mobject in one call to play() is discouraged and will most likely not work properly. Instead of writing an animation like

self.play(my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI))

make use of method chaining for animate, meaning:

self.play(my_mobject.animate.shift(RIGHT).rotate(PI))

Keyword arguments that can be passed to Scene.play() can be passed directly after accessing .animate, like so:

self.play(my_mobject.animate(rate_func=linear).shift(RIGHT))

This is especially useful when animating simultaneous .animate calls that you want to behave differently:

self.play(
    mobject1.animate(run_time=2).rotate(PI),
    mobject2.animate(rate_func=there_and_back).shift(RIGHT),
)

Examples

AnimateExample
class AnimateExample(Scene):
    def construct(self):
        s = Square()
        self.play(Create(s))
        self.play(s.animate.shift(RIGHT))
        self.play(s.animate.scale(2))
        self.play(s.animate.rotate(PI / 2))
        self.play(Uncreate(s))
AnimateChainExample
class AnimateChainExample(Scene):
    def construct(self):
        s = Square()
        self.play(Create(s))
        self.play(s.animate.shift(RIGHT).scale(2).rotate(PI / 2))
        self.play(Uncreate(s))
AnimateWithArgsExample
class AnimateWithArgsExample(Scene):
    def construct(self):
        s = Square()
        c = Circle()

        VGroup(s, c).arrange(RIGHT, buff=2)
        self.add(s, c)

        self.play(
            s.animate(run_time=2).rotate(PI / 2),
            c.animate(rate_func=there_and_back).shift(RIGHT),
        )
apply_to_family(func)[source]

Apply a function to self and every submobject with points recursively.

Parameters

func (Callable[[Mobject], None]) – The function to apply to each mobject. func gets passed the respective (sub)mobject as parameter.

Returns

self

Return type

Mobject

See also

family_members_with_points()

arrange(direction=array([1.0, 0.0, 0.0]), buff=0.25, center=True, **kwargs)[source]

Sorts mobjects next to each other on screen.

Examples

../_images/Example-2.png
Example
class Example(Scene):
    def construct(self):
        s1 = Square()
        s2 = Square()
        s3 = Square()
        s4 = Square()
        x = VGroup(s1, s2, s3, s4).set_x(0).arrange(buff=1.0)
        self.add(x)
Parameters

direction (Union[numpy.ndarray, List]) –

become(mobject, copy_submobjects=True)[source]

Edit points, colors and submobjects to be identical to another Mobject

Examples

BecomeScene
class BecomeScene(Scene):
    def construct(self):
        circ = Circle(fill_color=RED)
        square = Square(fill_color=BLUE)
        self.add(circ)
        self.wait(0.5)
        circ.become(square)
        self.wait(0.5)
Parameters
clear_updaters(recursive=True)[source]

Remove every updater.

Parameters

recursive (bool) – Whether to recursively call clear_updaters on all submobjects.

Returns

self

Return type

Mobject

copy()[source]

Create and return an identical copy of the Mobject including all submobjects.

Returns

The copy.

Return type

Mobject

Note

The clone is initially not visible in the Scene, even if the original was.

property depth[source]

The depth of the mobject.

Returns

Return type

float

flip(axis=array([0.0, 1.0, 0.0]), **kwargs)[source]

Flips/Mirrors an mobject about its center.

Examples

../_images/FlipExample-1.png
FlipExample
class FlipExample(Scene):
    def construct(self):
        s= Line(LEFT, RIGHT+UP).shift(4*LEFT)
        self.add(s)
        s2= s.copy().flip()
        self.add(s2)
generate_points()[source]

Initializes points and therefore the shape.

Gets called upon creation. This is an empty method that can be implemented by subclasses.

get_bottom()[source]

Get bottom coordinates of a box bounding the Mobject

Return type

numpy.ndarray

get_center()[source]

Get center coordinates

Return type

numpy.ndarray

get_coord(dim, direction=array([0.0, 0.0, 0.0]))[source]

Meant to generalize get_x, get_y and get_z

get_critical_point(direction)[source]

Picture a box bounding the Mobject. Such a box has 9 ‘critical points’: 4 corners, 4 edge center, the center. This returns one of them, along the given direction.

sample = Arc(start_angle=PI/7, angle = PI/5)

# These are all equivalent
max_y_1 = sample.get_top()[1]
max_y_2 = sample.get_critical_point(UP)[1]
max_y_3 = sample.get_extremum_along_dim(dim=1, key=1)
get_end()[source]

Returns the point, where the stroke that surrounds the Mobject ends.

get_left()[source]

Get left coordinates of a box bounding the Mobject

Return type

numpy.ndarray

get_point_mobject(center=None)[source]

The simplest Mobject to be transformed to or from self. Should by a point of the appropriate type

get_right()[source]

Get right coordinates of a box bounding the Mobject

Return type

numpy.ndarray

get_start()[source]

Returns the point, where the stroke that surrounds the Mobject starts.

get_start_and_end()[source]

Returns starting and ending point of a stroke as a tuple.

get_time_based_updaters()[source]

Return all updaters using the dt parameter.

The updaters use this parameter as the input for difference in time.

Returns

The list of time based updaters.

Return type

List[Callable]

get_top()[source]

Get top coordinates of a box bounding the Mobject

Return type

numpy.ndarray

get_updaters()[source]

Return all updaters.

Returns

The list of updaters.

Return type

List[Callable]

get_x(direction=array([0.0, 0.0, 0.0]))[source]

Returns x coordinate of the center of the Mobject as float

Return type

numpy.float64

get_y(direction=array([0.0, 0.0, 0.0]))[source]

Returns y coordinate of the center of the Mobject as float

Return type

numpy.float64

get_z(direction=array([0.0, 0.0, 0.0]))[source]

Returns z coordinate of the center of the Mobject as float

Return type

numpy.float64

has_points()[source]

Check if Mobject contains points.

has_time_based_updater()[source]

Test if self has a time based updater.

Returns

classTrue if at least one updater uses the dt parameter, False otherwise.

Return type

bool

property height[source]

The height of the mobject.

Returns

Return type

float

Examples

HeightExample
class HeightExample(Scene):
    def construct(self):
        decimal = DecimalNumber().to_edge(UP)
        rect = Rectangle(color=BLUE)
        rect_copy = rect.copy().set_stroke(GRAY, opacity=0.5)

        decimal.add_updater(lambda d: d.set_value(rect.height))

        self.add(rect_copy, rect, decimal)
        self.play(rect.animate.set(height=5))
        self.wait()
init_colors()[source]

Initializes the colors.

Gets called upon creation. This is an empty method that can be implemented by subclasses.

interpolate(mobject1, mobject2, alpha, path_func=<function straight_path>)[source]

Turns this Mobject into an interpolation between mobject1 and mobject2.

Examples

../_images/DotInterpolation-1.png
DotInterpolation
class DotInterpolation(Scene):
    def construct(self):
        dotL = Dot(color=DARK_GREY)
        dotL.shift(2 * RIGHT)
        dotR = Dot(color=WHITE)
        dotR.shift(2 * LEFT)

        dotMiddle = VMobject().interpolate(dotL, dotR, alpha=0.3)

        self.add(dotL, dotR, dotMiddle)
length_over_dim(dim)[source]

Measure the length of an Mobject in a certain direction.

match_updaters(mobject)[source]

Match the updaters of the given mobject.

Parameters

mobject (manim.mobject.mobject.Mobject) – The mobject whose updaters get matched.

Returns

self

Return type

Mobject

Note

All updaters from submobjects are removed, but only updaters of the given mobject are matched, not those of it’s submobjects.

move_to(point_or_mobject, aligned_edge=array([0.0, 0.0, 0.0]), coor_mask=array([1, 1, 1]))[source]

Move center of the Mobject to certain coordinate.

next_to(mobject_or_point, direction=array([1.0, 0.0, 0.0]), buff=0.25, aligned_edge=array([0.0, 0.0, 0.0]), submobject_to_align=None, index_of_submobject_to_align=None, coor_mask=array([1, 1, 1]))[source]

Move this Mobject next to another’s Mobject or coordinate.

Examples

../_images/GeometricShapes-1.png
GeometricShapes
class GeometricShapes(Scene):
    def construct(self):
        d = Dot()
        c = Circle()
        s = Square()
        t = Triangle()
        d.next_to(c, RIGHT)
        s.next_to(c, LEFT)
        t.next_to(c, DOWN)
        self.add(d, c, s, t)
null_point_align(mobject)[source]

If a Mobject with points is being aligned to one without, treat both as groups, and push the one with points into its own submobjects list.

Parameters

mobject (manim.mobject.mobject.Mobject) –

Return type

manim.mobject.mobject.Mobject

remove(*mobjects)[source]

Remove submobjects.

The mobjects are removed from submobjects, if they exist.

Subclasses of mobject may implement - and -= dunder methods.

Parameters

mobjects (manim.mobject.mobject.Mobject) – The mobjects to remove.

Returns

self

Return type

Mobject

See also

add()

remove_updater(update_function)[source]

Remove an updater.

If the same updater is applied multiple times, every instance gets removed.

Parameters

update_function (Union[Callable[[Mobject], None], Callable[[Mobject, float], None]]) – The update function to be removed.

Returns

self

Return type

Mobject

repeat(count)[source]

This can make transition animations nicer

Parameters

count (int) –

reset_points()[source]

Sets points to be an empty array.

restore()[source]

Restores the state that was previously saved with save_state().

resume_updating(recursive=True)[source]

Enable updating from updaters and animations.

Parameters

recursive (bool) – Whether to recursively enable updating on all submobjects.

Returns

self

Return type

Mobject

rotate(angle, axis=array([0.0, 0.0, 1.0]), **kwargs)[source]

Rotates the Mobject about a certain point.

rotate_about_origin(angle, axis=array([0.0, 0.0, 1.0]), axes=[])[source]

Rotates the Mobject about the ORIGIN, which is at [0,0,0].

save_state()[source]

Save the current state (position, color & size). Can be restored with restore().

scale(scale_factor, **kwargs)[source]

Scale the size by a factor.

Default behavior is to scale about the center of the mobject.

Parameters
  • scale_factor (float) – The scaling factor. Values 0 < |`scale_factor`| < 1 will shrink the mobject, 1 < |`scale_factor`| will increase it’s size. A `scale_factor`<0 resuls in additionally flipping by 180°.

  • kwargs – Additional keyword arguments passed to apply_points_function_about_point().

Returns

self

Return type

Mobject

See also

move_to()

scale_to_fit_depth(depth, **kwargs)[source]

Scales the Mobject to fit a depth while keeping width/height proportional.

scale_to_fit_height(height, **kwargs)[source]

Scales the Mobject to fit a height while keeping width/depth proportional.

Returns

self

Return type

Mobject

Examples

>>> from manim import *
>>> sq = Square()
>>> sq.width
2.0
>>> sq.scale_to_fit_height(5)
Square
>>> sq.height
5.0
>>> sq.width
5.0
scale_to_fit_width(width, **kwargs)[source]

Scales the Mobject to fit a width while keeping height/depth proportional.

Returns

self

Return type

Mobject

Examples

>>> from manim import *
>>> sq = Square()
>>> sq.height
2.0
>>> sq.scale_to_fit_width(5)
Square
>>> sq.width
5.0
>>> sq.height
5.0
set(**kwargs)[source]

Sets attributes.

Mainly to be used along with animate to animate setting attributes.

In addition to this method, there is a compatibility layer that allows get_* and set_* methods to get and set generic attributes. For instance:

>>> mob = Mobject()
>>> mob.set_foo(0)
Mobject
>>> mob.get_foo()
0
>>> mob.foo
0

This compatibility layer does not interfere with any get_* or set_* methods that are explicitly defined.

Warning

This compatibility layer is for backwards compatibility and is not guaranteed to stay around. Where applicable, please prefer getting/setting attributes normally or with the set() method.

Parameters

**kwargs – The attributes and corresponding values to set.

Returns

self

Return type

Mobject

Examples

>>> mob = Mobject()
>>> mob.set(foo=0)
Mobject
>>> mob.foo
0
set_color(color='#FFFF00', family=True)[source]

Condition is function which takes in one arguments, (x, y, z). Here it just recurses to submobjects, but in subclasses this should be further implemented based on the the inner workings of color

Parameters
  • color (colour.Color) –

  • family (bool) –

set_x(x, direction=array([0.0, 0.0, 0.0]))[source]

Set x value of the center of the Mobject (int or float)

set_y(y, direction=array([0.0, 0.0, 0.0]))[source]

Set y value of the center of the Mobject (int or float)

set_z(z, direction=array([0.0, 0.0, 0.0]))[source]

Set z value of the center of the Mobject (int or float)

set_z_index(z_index_value)[source]

Sets the Mobject’s z_index to the value specified in z_index_value.

Parameters

z_index_value (Union[int, float]) – The new value of z_index set.

Returns

The Mobject itself, after z_index is set. (Returns self.)

Return type

Mobject

set_z_index_by_z_coordinate()[source]

Sets the Mobject’s z coordinate to the value of z_index.

Returns

The Mobject itself, after z_index is set. (Returns self.)

Return type

Mobject

shift(*vectors)[source]

Shift by the given vectors.

Parameters

vectors (numpy.ndarray) – Vectors to shift by. If multiple vectors are given, they are added together.

Returns

self

Return type

Mobject

See also

move_to()

stretch_to_fit_depth(depth, **kwargs)[source]

Stretches the Mobject to fit a depth, not keeping width/height proportional.

stretch_to_fit_height(height, **kwargs)[source]

Stretches the Mobject to fit a height, not keeping width/depth proportional.

Returns

self

Return type

Mobject

Examples

>>> from manim import *
>>> sq = Square()
>>> sq.width
2.0
>>> sq.stretch_to_fit_height(5)
Square
>>> sq.height
5.0
>>> sq.width
2.0
stretch_to_fit_width(width, **kwargs)[source]

Stretches the Mobject to fit a width, not keeping height/depth proportional.

Returns

self

Return type

Mobject

Examples

>>> from manim import *
>>> sq = Square()
>>> sq.height
2.0
>>> sq.stretch_to_fit_width(5)
Square
>>> sq.width
5.0
>>> sq.height
2.0
suspend_updating(recursive=True)[source]

Disable updating from updaters and animations.

Parameters

recursive (bool) – Whether to recursively suspend updating on all submobjects.

Returns

self

Return type

Mobject

update(dt=0, recursive=True)[source]

Apply all updaters.

Does nothing if updating is suspended.

Parameters
  • dt (float) – The parameter dt to pass to the update functions. Usually this is the time in seconds since the last call of update.

  • recursive (bool) – Whether to recursively update all submobjects.

Returns

self

Return type

Mobject

property width[source]

The width of the mobject.

Returns

Return type

float

Examples

WidthExample
class WidthExample(Scene):
    def construct(self):
        decimal = DecimalNumber().to_edge(UP)
        rect = Rectangle(color=BLUE)
        rect_copy = rect.copy().set_stroke(GRAY, opacity=0.5)

        decimal.add_updater(lambda d: d.set_value(rect.width))

        self.add(rect_copy, rect, decimal)
        self.play(rect.animate.set(width=7))
        self.wait()