Manim is an animation engine for explanatory math videos.

Overview

An animation engine for explanatory math videos

Manim is an animation engine for explanatory math videos. It's used to create precise animations programmatically, as demonstrated in the videos of 3Blue1Brown.

NOTE: This repository is maintained by the Manim Community, and is not associated with Grant Sanderson or 3Blue1Brown in any way (although we are definitely indebted to him for providing his work to the world). If you would like to study how Grant makes his videos, head over to his repository (3b1b/manim). This fork is updated more frequently than his, and it's recommended to use this fork if you'd like to use Manim for your own projects.

Installation

Manim requires a few dependencies that must be installed prior to using it. If you want to try it out first before installing it locally, you can do so in our online Jupyter environment.

For the local installation, please visit the Documentation and follow the appropriate instructions for your operating system.

Once the dependencies have been installed, run the following in a terminal window:

pip install manim

Usage

Manim is an extremely versatile package. The following is an example Scene you can construct:

from manim import *

class SquareToCircle(Scene):
def construct(self):
circle = Circle()
square = Square()
square.flip(RIGHT)
square.rotate(-3 * TAU / 8)
circle.set_fill(PINK, opacity=0.5)

self.play(Create(square))
self.play(Transform(square, circle))
self.play(FadeOut(square))

In order to view the output of this scene, save the code in a file called example.py. Then, run the following in a terminal window:

manim example.py SquareToCircle -p -ql

You should see your native video player program pop up and play a simple scene in which a square is transformed into a circle. You may find some more simple examples within this GitHub repository. You can also visit the official gallery for more advanced examples.

Manim also ships with a %%manim IPython magic which allows to use it conveniently in JupyterLab (as well as classic Jupyter) notebooks. See the corresponding documentation for some guidance and try it out online.

Command line arguments

The general usage of Manim is as follows:

The -p flag in the command above is for previewing, meaning the video file will automatically open when it is done rendering. The -ql flag is for a faster rendering at a lower quality.

Some other useful flags include:

• -s to skip to the end and just show the final frame.
• -n  to skip ahead to the n'th animation of a scene.
• -f show the file in the file browser.

For a thorough list of command line arguments, visit the documentation.

Documentation

Documentation is in progress at ReadTheDocs.

Help with Manim

If you need help installing or using Manim, feel free to reach out to our Discord Server or Reddit Community. If you would like to submit bug report or feature request, please open an issue.

Contributing

Contributions to Manim are always welcome. In particular, there is a dire need for tests and documentation. For contribution guidelines, please see the documentation.

Most developers on the project use Poetry for management. You'll want to have poetry installed and available in your environment. You can learn more poetry and how to use it at its documentation.

Code of Conduct

Our full code of conduct, and how we enforce it, can be read on our website.

• New repository for documentation examples

Forking the discussion that started in #297 to here.

The problem

In the documentation, there will eventually be a (hopefully) substantial number of examples, both code and output videos/gifs. Git is pretty bad at tracking binary files, and if we keep these in the main repository, it will bloat up and become very clunky. Further, not every user/developer that clones the repository will need to (or want to) interact with the example gifs/movies.

The solution

@kolibril13 suggested that we create a new repository under the ManimCommunity organization. This repo would contain the gif/video files to be included in the documentation, but not the documentation itself. The documentation itself will remain under the main repository. Further, @naveen521kk brought up the fact that using GitHub for hosting is fine, but we should use other solutions for delivery and suggested jsdelivr. The benefits are that it will be much faster, and will be up whenever github is down.

What we need from you

Adding a new repository to the ManimCommunity organization is a fairly big change to the face of the organization, and I would not want to do that without making sure the core team approves. Up to now we have four people in favor (@Aathish04, @naveen521kk, @kolibril13, and myself). We need to hear from at least few more among @kilacoda @yoshiask @eulertour @PgBiel @XorUnison @kilacoda @huguesdevimeux @safinsingh @faielgila. Please feel free to thumbs up or down and/or raise any issues that you want to discuss.

PS: sorry for the multiple mentions in the other issue and this one. I just can't bring myself to make executive decisions on my own without running it by the whole team!

question infrastructure
opened by leotrs 74
• CONFIG dictionaries stuff

We have discussed about the variable CONFIGpreviously on discord. What should we do about it ?

I personally think we should modify at least a little bit of its architecture. it alters the readability a lot. One problem with that would be that in changing CONFIG we would have to review the entire architecture of the code.

What do you think?

enhancement refactor
opened by huguesdevimeux 68

Motivation

Over the past couple of weeks being part of the Manim Discord, I've seen a couple of issues with the SVG renderer. I myself have also had a lot of problems with it, most recently trying to import a map of the US as an SVG file. I think the SVG engine needs more robust functionality, and it looks like this is acknowledged but not an active priority (https://github.com/ManimCommunity/manim/projects/8).

I think SVG support is important to allow videos to go beyond the algebra and geometry constructs that 3b1b has made his bread and butter.

Overview / Explanation for Changes

In short, a rewrite of the SVG engine was needed, along with a fairly comprehensive test suite. Both of these will be addressed.

Oneline Summary of Changes

- Reworked the SVG rendering engine (:pr:915)


Testing Status

New tests have been provided and work effectively.

Full list of changes

SVG changes

• Rewrite of the SVG "path" interpretation code.
• Added multiple SVG unit tests in small hand-created SVG files
• Added multiple SVG system tests based upon SVG images that were provided by members of the Discord.
• SVGMobjects now include the fill and stroke properties of the images they were created from.

Non-SVG changes

• Added .idea to gitignore because I use PyCharm

Reviewer Checklist

• [x] Newly added functions/classes are either private or have a docstring
• [x] Newly added functions/classes have tests added and (optional) examples in the docs
• [ ] The oneline summary has been included in the wiki
opened by markromanmiller 55
• ManimPango should be a plugin

There are a number of problems with our integration with Pango that are detrimental to library's code hygiene. Only one community member understands the code, how to build it, and how to deploy it. It's caused difficulty for installation and development from the time it was first added to as recently as #1075, but more than either than those it just isn't necessary for manim's use.

We developed the plugin system but continually find reasons not to use it, even in instances like this that it was designed for. I'm fine with keeping it in the pypi package, but leaving ManimPango in the main code doesn't make much sense to me.

As an aside, there are a number of additions that we should probably consider moving into plugins as well, such as jupyter integration and (more of) the webgl renderer now that #1075 is merged.

enhancement
opened by eulertour 51

List of Changes

• Change 1

Add a streaming scene that uses its own file writer to override the normal functioning of the original to create a streaming protocol. Then, the original Scene class can use CairoRenderer as a default, until a helper class by the name Stream uses the advantage of renderer initialization for scenes to add a special renderer, that uses a special file writer. Most of the work I've been doing is make this accessible for other scenes. And I can say for sure, totally worth it.

class Stream:
"""This class is really intended for inheritance of the style:

>>> class Streamer(Stream, Scene): # doctest: +SKIP
...     pass
...
>>>

This order is paramount. This :class:Stream class does the switch to
the specialized renderer, which uses the :class:StreamFileWriter to
handle specialized streaming services. That explains the calls to super,
which dig through the MRO of a class instead of using just a single
implementation contained in Scene. Okay, the references in super probably
point to things in the :class:Scene class only, but it's already happened so...

PS: You can probably already tell using this class on its own will bring you
errors.

"""

• Change 2

Use rtp instead of tcp as the streaming protocol. Mainly for no other reason than it's what I understood and coded in that direction. If you think that means I didn't crack Twitch streaming then you are absolutely right. I tried tcp and udp already so feel free to tell me how to open a udp stream without blatant packet errors.

• Change 3

There are two versions of the livestreaming I made. Both do the same thing. The one under the function livestream is the main version and opens up an interactive session. The other one, stream, just returns the streamer. Easy to use for casual on the fly testing like:

>>> from manim import stream, stuff, other, stuff
>>> manim = stream()
>>> manim.play(...)


Nevertheless, both are available in the main library, depending on whether you need 500 objects in your global variables or not.

• Change 4

Any extras were probably made in order to have this working.

Explanation for Changes

I figure that any livestreaming option that was there in the past kind of broke, but the backbone of its capability was continuously carried around like a fossil. So I tried to implement it and it worked.

Testing Status

There's varying amounts of good and bad news here. Let me explain.

• Good

Since this Manim can directly influence camera configurations from the command line, this gives you high quality streaming:

python -m manim --livestream

This gives you medium:

python -m manim -qm --livestream

This gives you IMAX:

python -m manim -qk --livestream

• Good

Ability to use other base scenes for streaming. Really the crux of my implementation detail.

https://user-images.githubusercontent.com/67624028/113116179-dde9fd00-9215-11eb-8d9c-31a412f10628.mp4

• Superb depending on utility

Ability to render pre-made scenes with baked setup and/or construct methods.

https://user-images.githubusercontent.com/67624028/113116280-f78b4480-9215-11eb-8cfa-173b99bf8426.mp4

You can also use the play_scene function to specify a start and end animation, analogous to the -n keyword from the command line. For example: play_scene(scene, start=0, end=4)

If I did my job well the ffplay window should be triggered automatically. But if it doesn't for some reason a command along the lines of this may help:

ffplay -x 640 -y 360 -protocol_whitelist "file,rtp,udp" -i "path\to\manim\media\streams\streams.sdp" -reorder_queue_size 0

ffplay might glitch and show you a lot of red for some reason. Reopening it should fix one of those problems. For example the avai;able open_client(); get_streamer().wait() sequence should open ffplay again and trigger the opening of the window. Also there's something about the last frame of the animation not showing, but it's just one frame. You can close the window and run open_client() to restart the window, if this is the beginning of further glitching.

• Good

If it works though, expect something like this:

https://user-images.githubusercontent.com/67624028/113116436-1b4e8a80-9216-11eb-8a3f-712f0a8a47ed.mp4

• From StreamCairoRenderer
"""I wish there was another way to have a renderer that uses the
file writer created for the purpose. However, I can't do that without
the original code being aware of the extra implementation, which is probably
undesirable style.
"""

• When using get_streamer, it is technically possible to use multiple classes to inherit more methods. The argument syntax clearly supports it yet its main use is to generates the tuple of the passed scene automatically. Multiple inheritance would be delicate and would only work if the classes after the first merely add more methods than override base ones. For example MovingCameraScene, LinearTransformationScene is a tempting concoction but unstable. For one, naming them in reverse is already an error, courtesy of the assertion in MovingCameraScene. Also, the latter adds attributes used in its methods from __init__, which wouldn't be called thanks to strict initialization minus super() proxies. Then again, multiple inheritance of scenes was always a delicate matter in Manim.

Acknowledgement

*half true ***70 of the commits don't count, I was learning

enhancement new feature
opened by NeoPlato 48
• Configparser setup: figuring out config.py, constants.py, dirs.py, CLI arguments, and more [WIP]

Ok y'all, this is a doozy. I've been working on this and there's a few things that we need to decide as an organization. I'm going to try to make my points clearly and I'll bold the points at which I need y'all's input.

Rationale

The current repo is very badly disorganized and needs a good cleanup. One of the sources of this is the fact that there are different ways of manipulating what manim does as a whole:

1. constants.py sets some global variables (most of which are actually constant, but some of which are not).
2. config.py parses the CLI arguments, uses it to set camera_config among other things. It also initializes directories.
3. HOWEVER, there is also a dirs.py file that allowed you to set default output directories. config.py reads that in as well as the CLI arguments.

As a result, I think it's quite the hurdle for a user to figure out where to get or set the value of a particular variable that determines how manim works. If I want to change a directory, should I use dirs.py, or a CLI argument? Which has precedence over the other? If I want to change the resolution, should I do it in constants.py, by CLI argument, or in the CONFIG of my Scene objects?

The main purpose of this PR is to provide a single default source of global truth for configuring how manim works. (And, in the event that there is more than one possibility to set the value of a particular variable, the precedence between those possibilities should be very clear and documented.)

The proposal

The main way to do this is as follows. This PR makes it so that there is one single place to write/determine/set how manim works, and one single place to read/check/get those configurations once they are in place.

• Write: The user can now use an optional manim.cfg file to tweak the default behavior. Note this is a file that the user can have on their machine without touching the manim codebase at all. We will also ship a default config file so the user doesn't need to have such a file, but can have one if they want it.
• Read: once all configuration variables, directories, and CLI arguments have been parsed/processed, there is one single place where all of the configuration lives in for the rest of the execution: the global config dictionary that can now be imported by doing from .config import config (if within the library codebase) or by from manim import config (if importing the library as end user).

The constants.py file still exists, but as much as possible, it should not contain configuration variables, only constants. (more on this later).

How it works

I want to explain the main workflow of how this works. For this, note that there are two different ways of using manim: importing it as a library (to have access to Scene, Mobjects and so on), and as a command line script (to actually render a video).

If being imported as a library, this is what's going to happen. The user will type from manim import * at the top of their file. This executes the contents of __init__.py, which in turn imports/executes config.py before anything else. config.py defines and exports the config dictionary by parsing the manim.cfg file. This config will now contain all configuration needed for the end user (and indeed for internal purposes as well). Finally, config.py will also setup some directories (more on this later). (Note that this is a very odd way of using manim, like for example if you open a python interpreter and type import manim. Importantly, this will also be the case during testing. In most cases, manim will be used in the other way, in the next paragraph.)

If being used from the command line, for example as python -m manim ... or as manim ... or as manimcm ..., the file that gets executed first is __main__.py. This file also imports/executes config.py as the first order of business. In this case, config.py will recognize it's being used from the command line and, after parsing manim.cfg first, it will also parse the CLI arguments. The CLI arguments will override the default settings defined in manim.cfg. At the end, the global config dictionary will contain all configuration that correctly corresponds to the defaults in the .cfg file as well as the CLI arguments.

The result

When manim is being used as a library, there is no visible change other than the fact that some imports of the type from manim.constants import SOME_VAR and then using SOME_VAR will become import manim.config as config and then using config['SOME_VAR'], because some variables (that weren't constants) have been moved from constants.py into the config dictionary. More on this later (see discussion points).

When manim is being used from the command line to actually generate scenes, the changes are as follows. All the command line arguments are still in place. BUT, now the user may set the defaults by using their own manim.cfg file. For example, the -p (or --preview) flag is turned off by default so if the user wants the movie to play after it's rendered, currently they need to always specify -p. After this PR, the user can create a new manim.cfg file with the line PREVIEW = TRUE. If they do so, running manim without the -p flag will still show the video once it's rendered. This has the advantage that if a user needs a particularly long CLI command with lots of flags to render their scenes, they can just dump all of those flags into the manim.cfg file and just run manim myfile.py. The manim.cfg file currently allows to set default values for each command line argument.

The discussion points

I'm just going to dump a bunch of issues here in no particular order. I'll do my best to be brief and to point exactly what needs to be answered/discussed/decided in bold.

1. The main problem here is that we are still conflating constants along with configuration variables, in the following way. The PIXEL_WIDTH (previously called DEFAULT_PIXEL_WIDTH) variable can be set in command line via the -l, -m, -e, -r flags. So it is not a constant, and it should live inside config, not in constants.py. This PR makes it so. Now, there are other values, for example FRAME_WIDTH, that directly depend on the value of PIXEL_WIDTH, thus they are also not constant. HOWEVER, the configparser library that parses .cfg files does not support arithmetic operations. So right now there is no easy way to only set PIXEL_WIDTH once and have FRAME_WIDTH and related variables update their values as well. Right now, in this PR this is being done in the constants.py file: it is loading the config dictionary, which contains PIXEL_WIDTH and defines the other variables accordingly. I very much don't think this should be merged as is, but I wanted to ask what is the best way to solve this, knowing that this cannot happen in the .cfg file? My suggestion is that this happens inside config.py, with a special function that defines those variables such as FRAME_WIDTH once PIXEL_WIDTH is set. However, this means that the user can set only the latter and the former will always be tied to it in the same hard-coded way. EDIT: I think a good example to fix this issue is to consider the question, where do we define TOP? Currently, it is defined in constants.py, with the line TOP = FRAME_Y_RADIUS * UP. Now, I think UP is a true constant and it should stay in constants.py. But FRAME_Y_RADIUS depends on FRAME_HEIGHT, which is not constant and is set by CLI argument in config.py. If we adhere to the strict view that only true constants must remain in constants.py, then TOP must go elsewhere.

2. Due to the above (some configuration variables are being loaded into constants.py), I converted all configs and constants to ALL_CAPS. Accordingly, the CONFIG dictionary of Scenes and Mobjects were also turned to ALL_CAPS. I think this is ugly as hell and hope this changes in the future. Fixing the issue of constants vs config variables should make this go away.

3. For the problem of importing config.py before anything else, see #26. I think we are in the clear here.

4. The current version does not work with python -m manim ... (see definition of prog in config.py). This is because it is actually very difficult to determine if the library is being imported or run from the command line (at least from the config.py file). I need suggestions for how to fix this.

5. This is a pretty big change so if there is anything that you can think of, please bring it up here.

6. Currently, all of the keys in SceneFileWriter.CONFIG are keys of the global config dict. Does SceneFileWriter really need a copy of each? Pinging @PgBiel here who is working on attrs.

7. Yes, this has been tested and renders scenes well. I have by no means ran an exhaustive test suite of all constants/configs/CLI flags yet.

List of changes

I'll list some of the minor changes made that are not big-picture issues. Please comment on these too if you have anything to say.

1. start_at_animation_number is now FROM_ANIMATION_NUMBER. Similarly, end_at_animation_number is now UPTO_ANIMATION_NUMBER. These are shorter and have the same meaning. (I don't like the ALL_CAPS, but that's a different issue touched upon above.)
2. dirs.py has been eliminated. Instead of dirs.video_dir, now you have to do config['VIDEO_DIR']. This will require changing from dirs import video_dir to from config import config and using config['VIDEO_DIR']. If we don't want to have to load the whole global config just for the one directory name, we can package the directories in a separate dict, also defined in config.py and load it as from config import dirs.
3. input_file_path has changed to INPUT_FILE, and file_name has changed to OUTPUT_FILE. The original names were just confusing.
4. The default configuration file is now packaged with the rest of the code, as seen in in setup.py.
5. DEFAULT_PIXEL_WIDTH, DEFAULT_PIXEL_HEIGHT, and DEFAULT_FRAME_RATE have been changed to PIXEL_WIDTH, PIXEL_HEIGHT, and FRAME_RATE. The reason is that once the config is read and the CLI arguments parsed, they are no longer a 'default' value, but possibly a value set by the user, so the names were misleading. The new names are also shorter.
6. PRODUCTION_QUALITY_CAMERA_CONFIG is now just the default config['CAMERA_CONFIG']. Also, note that config['CAMERA_CONFIG'] is changed by the *-quality flags (low-quality, medium-quality, high-quality) and by the --resolution flag.
7. The scene_names CLI argument is now --scene_names for easier parsing.
8. Changed open_video_upon_completion to PREVIEW so it has the same name as its corresponding CLI flag. It is also way shorter.
9. Removed the ignore_waits option which was never used and was set to the value of args.preview.
10. Most CLI flags have been changed to have no default value. For example, -p was by default False, but will now default to None. This is done that we can easily determine whether the user actually specified this flag by comparing it to None. If the flag is None, we read the default value from the manim.cfg file instead. Importantly, this is a subtle change in the code (see comments inside _parse_cli() in config.py if you are interested.
11. The way everything is setup right now, passing only the -s flag will also write a movie (since WRITE_TO_MOVIE is True by default in manim.cfg). See #41.

List of standing or future issues

While working on this, I realized there is a number of other things that I would also like to change, but I'm not sure if they should be part of this PR or a separate one.

1. I think there are a bunch of variables/constants that have DEFAULT_ in the name but that should not have it.
2. The output directories are being created during initialization (when config.py is read). I think the directories should be created at the last possible minute. If I run manim and it crashes before writing the scene, the directories will be created but empty.

PS

Mostly for my sanity: this interacts with #65, #81, #77, #151 so I'll get back to those when this is merged.

enhancement help wanted pr:deprecation refactor
opened by leotrs 48
• Move to Poetry

In this PR

• Changed links in the Readme file to use Github Url instead of a relative path. ( Required for Publishing Package )

What is Poetry?

Poetry is a dependency manager as well as help us publish packages to Pypi. Refer to their website for more info https://python-poetry.org/.

But even here, pycairo creates a problem. Well, we should need to think about it. (Now it is fixed)

See https://github.com/python-poetry/poetry#installation for installation on your PC. Also, don't forget to read the documentation.

Also, according to https://www.python.org/dev/peps/pep-0518/ adding a pyproject.toml is necessary.

One thing which should be done.

• [x] Wait for new Pycairo release
enhancement infrastructure new feature
opened by naveen521kk 46

Motivation

Closes #452

This is a refactor which moves Manim away from argparse and towards click in order to allow future developers to easily add future subcommands, options, and arguments.

Changelog / Overview

This change breaks the CLI API to organize the structure of Manim Community's commands, options, and arguments.

To be more in line with POSIX compliant CLI conventions, options for commands are given BEFORE their arguments. In Argparse: manim basic.py -p -ql With Click: manim -p -ql basic.py

Although this is primarily a refactor and most of the common options are still there, some options have been added/removed. Use the manim command's -h, --help option, or simply run the command without providing options/arguments to view the help page with the full list of subcommands/options/arguments.

• Added a --fps/--frame_rate option which allows for custom fps that don't have to be integer (i.e. 29.97, 23.98, etc.). Users no longer have to specify the FPS from within a config file. Additionally, the --webgl_renderer_fps option has been removed. Use --fps or --frame_rate instead.
• Added a --renderer option which you can use to select your choice of renderer (e.g. --renderer=opengl). There are currently THREE renderers to choose from!
• Removed the --background_color option. Reassigned the --background_color option's shorthand -c to --config_file.
• Removed the --leave_progress_bars option. Use --progress_bars=leave instead.
• Removed the deprecated render quality flags, in particular: -l, -m, -h, -k.
• Removed the --sound option. It lost support long ago with the removal of SoX.

By default, the manim group calls the manim render subcommand through some decorator magic (i.e. manim -pql basic.py is a shorthand for manim render -pql basic.py). All of the subcommands and their options are contained within the manim/cli directory which is where the focus of the code should go. Most testcases that involve using the CLI had to be refactored as well to accomodate the new method of providing options before arguments ( arguments being the file/scene(s) ).

Testing Status

All test cases are currently pass on all OSs in our CI!

There will be some refactoring in future commits to this PR, particularly documentation of the functions. This is a successful first draft though.

The intent is to eventually redo the ManimConfig object as well using a similar decorator style approach to easily add config options with customized validation logic.

The new CLI structure is as follows:

manim [Defaults to: render*]
|- options
|---render
|- options
|-file, scenes
|---cfg
|---export
|- options
|---show
|---write
|-options
|---plugins
|-options


If you're curious to see the new help messages without adding my remote:

manim -h

manim -h

Usage: manim [OPTIONS] COMMAND [ARGS]...

Animation engine for explanatory math videos

Options:
--version   Show the version and exit.
-h, --help  Show this message and exit.

Commands:
render*  Render SCENE(S) from the input FILE.
cfg      Manages Manim configuration files.
plugins  Manages Manim plugins.

Made with <3 by Manim Community developers.


manim render -h

manim render -h

Usage: manim render [OPTIONS] [FILE] [SCENES]... COMMAND [ARGS]...

Render SCENE(S) from the input FILE.

FILE is the file path of the script.

SCENES is an optional list of scenes in the file.

Options:
Global options:
-c, --config_file FILENAME    Specify the configuration file to use for
render settings.

--custom_folders              Use the folders defined in the
[custom_folders] section of the config file
to define the output folder structure.

--disable_caching             Disable the use of the cache (still
generates cache files).

--flush_cache                 Remove cached partial movie files.
--tex_template FILENAME       Specify a custom TeX template file.
-v, --verbose [DEBUG|INFO|WARNING|ERROR|CRITICAL]
Verbosity of CLI output. Changes ffmpeg log
level unless 5+.

Output options:
-o, --output TEXT             Specify the filename(s) of the rendered
scene(s).

--media_dir PATH              Path to store rendered videos and latex.
--log_dir PATH                Path to store render logs.
--log_to_file                 Log terminal output to file  [default: True]
Render Options:
-n, --from_animation_number TEXT
Start rendering from n_0 until n_1. If n_1
is left unspecified, renders all scenes
after n_0.

-a, --write_all TEXT          Render all scenes in the input file.
-f, --format [png|gif|mp4]
-s, --save_last_frame
-q, --quality [l|m|h|p|k]     Render quality at the follow resolution
framerates, respectively: 854x480 30FPS,
1280x720 30FPS, 1920x1080 60FPS, 2560x1440
60FPS, 3840x2160 60FPS

-r, --resolution TEXT         Resolution in (W,H) for when 16:9 aspect
ratio isn't possible.

--fps FLOAT                   Render at this frame rate.  [default: 30]
--webgl_renderer PATH         Render scenes using the WebGL frontend.
Requires a path to the WebGL frontend.

-t, --transparent             Render scenes with alpha channel.
-c, --background_color TEXT   Render scenes with background color.
[default: #000000]

Ease of access options:
--progress_bar [display|leave|none]
Display progress bars and/or keep them
displayed.  [default: display]

-p, --preview                 Preview the rendered file(s) in default
player.

-f, --show_in_file_browser    Show the output file in the file browser.
--sound                       Play a success/failure sound.
-h, --help                      Show this message and exit.

Made with <3 by Manim Community developers.


manim cfg -h

manim cfg -h

Usage: manim cfg [OPTIONS] COMMAND [ARGS]...

Manages Manim configuration files.

Options:
-h, --help  Show this message and exit.

Commands:
export
show
write

Made with <3 by Manim Community developers.


manim cfg export -h

Usage: manim cfg export [OPTIONS]

Options:
-d, --dir TEXT
-h, --help      Show this message and exit.


manim cfg show -h

Usage: manim cfg show [OPTIONS]

Options:
-h, --help  Show this message and exit


manim cfg write -h

Usage: manim cfg write [OPTIONS]

Options:
-l, --level [user|cwd]  Specify if this config is for user or the working
directory.

-o, --open
-h, --help              Show this message and exit.


manim plugins -h

manim plugins -h

Usage: manim plugins [OPTIONS]

Manages Manim plugins.

Options:
-l, --list  List available plugins
-h, --help  Show this message and exit.

Made with <3 by Manim Community developers


Reviewer Checklist

• [ ] Newly added functions/classes are either private or have a docstring
• [ ] Newly added functions/classes have tests added and (optional) examples in the docs
• [ ] The oneline summary has been included in the wiki
breaking changes highlight
opened by jsonvillanueva 44

Motivation

Manim doesn't render animations completely. For a video rendering library, this should be priority 1 right now. See #183 for @huguesdevimeux's excellent report. In short, the animation

class MyScene(Scene):
def construct(self):
self.play(ShowCreation(Square()))


generates a video whose last frame is this:

You can see that the square has not been rendered fully, there is still a bit of the animation left to play (see open top left corner).

After discussion in #183, the way to solve this seems to be to simply add the last frame manually at the end of the video. With the mess that is scene file writer, scene, renderer, caching, etc, it was not obvious to me how to do this correctly. Luckily, thanks to all the good work put it by the dev team recently, I was finally able to figure it out, I think.

Explanation for Changes

The way things currently work:

1. Each call to play opens a new FFMPEG pipe.
2. Each frame is fed into the pipe.
3. When animation ends, the pipe is closed.

The way I'm proposing we do things:

1. Each call to play closes a previous FFMPEG pipe, if one exists.
2. Open a new pipe.
3. Feed each frame into the new pipe.
4. Leave the pipe open.

After all frames are fed, one of two things can happen: (a) play is called with a new animation (in which case it would close the currently open pipe in step 1.), or (b) the video ends. If the video ends, Renderer.finish() is called, which now takes care of writing the last frame (this is the bug fix! :tada:) and closing the open pipe, so no pipes are ever left unattended. This is basically what you see in the diff in renderer/cairo_renderer.py.

There is only one sticking point: the first call to play will try to close an (unexisting) pipe, so I added a quick check for that in scene/scene_file_writer.py

Testing Status

The tests currently do not pass, because this fix will change some tests. However before further work I wanted to hear what everyone thinks. Mainly, this bug will make it so that a manim script with a single 1s animation will render a video that is longer than 1s. I believe this should be fixable by tweaking the last call to ffmpeg somehow, but I'm not sure how.

I believe #618 should be addressed only after merging this (or else fixing #183)

This is a pretty big change and it will break user space so thoughts appreciated @ManimCommunity/core

pr:bugfix test requested
opened by leotrs 39
• Moving Core Renderer to a new Project

This was discussed in yesterday's meeting that the Manim Core should be small and easily understandable, and shouldn't contain complicated code. As in it should only contain Renderer, Scene, Camera, File Writer and basic Mobject structures.

My thoughts on this:

• Create a new project, call it manim-core and move all the Renderers, Camera, Scene and anything we consider important. Let it have the same module name, manim and I have seen that this works. This repository will have a dependency on the other and published as a separate PyPI package.
• manim-core would only have as much as it is useless without other parts of the library, with no other extra dependencies like ManimPango, NetworkX.
• Make this project, manim a collection of curated plugins by the community, while this doesn't affect the core library.
• Making parts of library optional to install, for example, one could be able to just get geometric Mobjects + Core renderer.
help wanted refactor Suggestion
opened by naveen521kk 38

Motivation

The three methods seem to create some confusion for beginners, its not really a breaking change, just making things more intuitive.

Overview / Explanation for Changes

Before:

set_fill(), set_stroke() - Changes fill/stroke color, doesn't affect opacity if not mentioned set_color() - just calls the above two methods together

Problem:

The default fill color has 0 opacity, as a result doing this:

Circle().set_stroke(BLUE) - a BLUE outlined circle
Circle().set_fill(BLUE) - a default colored outlined circle
Circle().set_color(BLUE) - a BLUE outlined circle


Isn't that confusing because the default fill is transparent?

After:

set_fill(), set_stroke() - Called on transparent object and opacity not mentioned? then set opacity to 1 set_color() - works exactly the same. just added optional opacity parameter if you want to adjust fill.stroke opacities together

Circle().set_stroke(BLUE) - a BLUE outlined circle # same as above
Circle().set_fill(BLUE) - a default colored outlined + blue filled circle # opacity altered here with this change
Circle().set_color(BLUE) - a BLUE outlined circle # same as above
Circle().set_color(BLUE, opacity=1) - a BLUE outlined circle + filled circle # new feature/parameter


And this looks much more intuitive and better. Also set_color_only() function is added which doesn't affect these opacities, (to make FadeToColor animation work as intended) Added docs to some functions

Oneline Summary of Changes

- set_fill() and set_stroke() improved, set_color() optional opacity parameter added (:pr:956)


Reviewer Checklist

• [ ] Newly added functions/classes are either private or have a docstring
• [ ] Newly added functions/classes have tests added and (optional) examples in the docs
• [ ] The oneline summary has been included in the wiki
opened by sparshg 38

Motivation and Explanation: Why and how do your changes improve the library?

docker.io/ is often skipped, but it is not the only image registry. Some software or setups do not have it as default.

Reviewer Checklist

• [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
• [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
• [ ] If applicable: newly added functions and classes are tested
opened by frafra 0

Description of bug / unexpected behavior

Shouldn't the method ~.get_axis_labels() work for both Axes and ThreeDAxes? At the moment it only works for Axes and returns an error when trying to use with ThreeDAxes. This doesn't make sense, it should work for both.

Expected behavior

The method ~.get_axis_labels() should work the same for both Axes and ThreeDAxes.

How to reproduce the issue

Code for reproducing the problem
class Test(ThreeDScene):
def construct(self):
axes = ThreeDAxes()
axes_labels = axes.get_axis_labels(Tex("x"), Tex("y"), Tex("z"))


Logs

Terminal output
Manim Community v0.15.2

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/cli/render/commands.py:118 in render │
│                                                                                                  │
│   115 │   │   for SceneClass in scene_classes_from_file(file):                                   │
│   116 │   │   │   try:                                                                           │
│   117 │   │   │   │   scene = SceneClass()                                                       │
│ ❱ 118 │   │   │   │   scene.render()                                                             │
│   119 │   │   │   except Exception:                                                              │
│   120 │   │   │   │   error_console.print_exception()                                            │
│   121 │   │   │   │   sys.exit(1)                                                                │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/scene/scene.py:222 in render         │
│                                                                                                  │
│    219 │   │   """                                                                               │
│    220 │   │   self.setup()                                                                      │
│    221 │   │   try:                                                                              │
│ ❱  222 │   │   │   self.construct()                                                              │
│    223 │   │   except EndSceneEarlyException:                                                    │
│    224 │   │   │   pass                                                                          │
│    225 │   │   except RerunSceneException as e:                                                  │
│                                                                                                  │
│ /home/alexlembcke/video.py:877 in construct                     │
│                                                                                                  │
│   874 class Test(ThreeDScene):                                                                   │
│   875 │   def construct(self):                                                                   │
│   876 │   │   axes = ThreeDAxes()                                                                │
│ ❱ 877 │   │   axes_labels = axes.get_axis_labels(Tex("x"), Tex("y"), Tex("z"))                  │
│   878 │   │   self.add(VGroup(axes, axes_labels))                                                │
│   879                                                                                            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: CoordinateSystem.get_axis_labels() takes from 1 to 3 positional arguments but 4 were given


System specifications

System Details
• OS (with version, e.g., Windows 10 v2004 or macOS 10.15 (Catalina)):
• RAM:
• Python version (python/py/python3 --version):
• Installed modules (provide output from pip list):
PASTE HERE

LaTeX details
• LaTeX distribution (e.g. TeX Live 2020):
• Installed LaTeX packages:
FFMPEG

Output of ffmpeg -version:

PASTE HERE


opened by alembcke 2

Description of proposed feature

This feature will allow you to wait until the scene has run for a specific duration.
Lots of people overlay audio onto their videos and this will make it easier to sync audio and animation.

How can the new feature be used?

# play animations
self.wait_upto(60)
# scene has run for 1 minute

# play more animations
self.wait_upto(90)
# another 30 seconds have passed


I've been using it in my own projects and would be happy to implement it and submit a PR when if that's fine. I just want to get a go-ahead and any comments about things I might not have thought of.

new feature
opened by George-Ogden 2
• New example to graph.py documentation

Example scene of rendering a linear neural network using partite graph

Overview: What does this pull request change?

• Added an example to the mobject.graph doc using the partite layout to render an linear neural network

Motivation and Explanation: Why and how do your changes improve the library?

• Easy copy and paste example that saves time if rendering machine learning-related animations

• Example renders only last frame

Reviewer Checklist

• [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
• [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
• [ ] If applicable: newly added functions and classes are tested
opened by Tsukalos 0

Overview: What does this pull request change?

The graph's updater now uses the underlying _set_start_and_end_attrs method of Line-based mobjects so that it respects the boundaries of the start/end mobjects.

Before:

https://user-images.githubusercontent.com/63877260/175780272-67605e57-7d61-47ae-a06a-af90fd61d56f.mp4

After:

https://user-images.githubusercontent.com/63877260/175780277-537a99d5-ba48-40c7-ba3c-09ed2139e443.mp4

For the snippet

class Testing(Scene):
def construct(self):
g = Graph([0, 1], [(0, 1)], edge_type=Arrow, labels=True)
self.wait()
self.play(g.animate.shift(DOWN))


Motivation and Explanation: Why and how do your changes improve the library?

While temporarily calling clear_updaters() helps, in any cases where there are moving vertices the animation must currently still not be continuous because while the constructor respects the start/end mobjects' boundaries, the updater doesn't. This fix makes everything 'smooth' and continuous (and also, respect the mobjects' boundaries which is more visually pleasing).

Closes #2843.

• Unfortunately, this breaks edge cases where the edge_type doesn't have a _set_start_and_end_attrs method (which is possible only if it doesn't inherit from Line)
• Therefore, it might make sense to abstract the _set_start_and_end_attrs into another place, and perhaps even rename it.

Reviewer Checklist

• [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
• [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
• [ ] If applicable: newly added functions and classes are tested
opened by noamzaks 3

Overview: What does this pull request change?

This was very handy for me when trying to swap two parts of an equation around without them getting muddled together first. Thus, I want it to be more clear how to use the path_arc feature of Transform, so I added an example showing how the different angles change the movement path.

Transform Page

https://user-images.githubusercontent.com/6819944/175700022-efb9c6b3-d278-4905-8bc1-85c8c093c19a.mp4

Reviewer Checklist

• [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
• [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
• [ ] If applicable: newly added functions and classes are tested
opened by kjlubick 3
Releases(v0.15.2)
Editor and Presenter for Manim Generated Content.

Editor and Presenter for Manim Generated Content. Take a look at the Working Example. More information can be found on the documentation. These Browse

114 Jun 23, 2022
Collection of scripts for making high quality beautiful math-related posters.

Poster Collection of scripts for making high quality beautiful math-related posters. The poster can have as large printing size as 3x2 square feet wit

3 Jun 9, 2022
A simple script that displays pixel-based animation on GitHub Activity

GitHub Activity Animator This project contains a simple Javascript snippet that produces an animation on your GitHub activity tracker. The project als

16 Nov 15, 2021
Animation engine for explanatory math videos

Manim is an engine for precise programatic animations, designed for creating explanatory math videos. Note, there are two versions of manim. This repo

45.5k Jun 27, 2022
An animation engine for explanatory math videos

Powered By: An animation engine for explanatory math videos Hi there, I'm Zheer ?? I'm a Software Engineer and student!! ?? I’m currently learning eve

2 Nov 4, 2021
Cairo-math-64x61 - Fixed point 64.61 math library for Cairo / Starknet

Cairo Math 64x61 A fixed point 64.61 math library for Cairo & Starknet Signed 64

35 Jun 18, 2022
Code for the manim-generated scenes used in 3blue1brown videos

This project contains the code used to generate the explanatory math videos found on 3Blue1Brown. This almost entirely consists of scenes generated us

3.6k Jun 28, 2022
Tool for live presentations using manim

manim-presentation Tool for live presentations using manim Install pip install manim-presentation opencv-python Usage Use the class Slide as your sce

115 Jun 22, 2022

ManimCE Animations Animations made using manim-ce The code turned out to be a bit complicated than expected.. It can be greatly simplified, will work

13 Apr 6, 2022
Seeing if I can put together an interactive version of 3b1b's Manim in Streamlit

streamlit-manim Seeing if I can put together an interactive version of 3b1b's Manim in Streamlit Installation I had to install pango with sudo apt-get

6 Nov 8, 2021
Editor and Presenter for Manim Generated Content.

Editor and Presenter for Manim Generated Content. Take a look at the Working Example. More information can be found on the documentation. These Browse

114 Jun 23, 2022
ManimML is a project focused on providing animations and visualizations of common machine learning concepts with the Manim Community Library.

ManimML ManimML is a project focused on providing animations and visualizations of common machine learning concepts with the Manim Community Library.

78 Jun 25, 2022
The MATH Dataset

Measuring Mathematical Problem Solving With the MATH Dataset This is the repository for Measuring Mathematical Problem Solving With the MATH Dataset b

224 Jun 19, 2022
a simple proof system I made to learn math without any mistakes

math_up a simple proof system I made to learn math without any mistakes 0. Short Introduction test yourself, enjoy your math! math_up is an NBG-based,

5 Jun 4, 2021
Code for Graph-to-Tree Learning for Solving Math Word Problems (ACL 2020)

Graph-to-Tree Learning for Solving Math Word Problems PyTorch implementation of Graph based Math Word Problem solver described in our ACL 2020 paper G

60 May 25, 2022
A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, celery and redis.

Django Channels Websocket Chatbot A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, c

9 May 20, 2022
A Python package for floating-point binary fractions. Do math in base 2!

An implementation of a floating-point binary fractions class and module in Python. Work with binary fractions and binary floats with ease!

8 Apr 12, 2022
emoji-math computes the given python expression and returns either the value or the nearest 5 emojis as measured by cosine similarity.

emoji-math computes the given python expression and returns either the value or the nearest 5 emojis as measured by cosine similarity.

12 Feb 13, 2022
An application that maps an image of a LaTeX math equation to LaTeX code.

Convert images of LaTex math equations into LaTex code.

1.1k Jun 26, 2022
MWPToolkit is a PyTorch-based toolkit for Math Word Problem (MWP) solving.

MWPToolkit is a PyTorch-based toolkit for Math Word Problem (MWP) solving. It is a comprehensive framework for research purpose that integrates popular MWP benchmark datasets and typical deep learning-based MWP algorithms.

85 Jun 21, 2022
Interactive deep learning book with multi-framework code, math, and discussions. Adopted at 200 universities.

D2L.ai: Interactive Deep Learning Book with Multi-Framework Code, Math, and Discussions Book website | STAT 157 Course at UC Berkeley | Latest version

13.8k Jun 30, 2022
Course Materials for Math 340

UBC Math 340 Materials This repository aims to be the one repository for which you can find everything you about Math 340. Lecture Notes Lecture Notes

2 Nov 25, 2021
CLI/GUI Math commands based on python 3

PyMath Commands Syntax Installation Commands: pymath add: usage: pymath add 12.5 12.5 sub: usage: pymath sub 25 12.5 div: usage: pymath div 144 12 mul

0 Nov 22, 2021
It's a repo for Cramer's rule, which is some math crap or something idk

It's a repo for Cramer's rule, which is some math crap or something idk (just a joke, it's not crap; don't take that seriously, math teachers)

1 Nov 20, 2021
Collection of scripts for making high quality beautiful math-related posters.

Poster Collection of scripts for making high quality beautiful math-related posters. The poster can have as large printing size as 3x2 square feet wit

3 Jun 9, 2022
Simple and easy to use python API for the COVID registration booking system of the math department @ unipd (torre archimede)

Simple and easy to use python API for the COVID registration booking system of the math department @ unipd (torre archimede). This API creates an interface with the official browser, with more useful functionalities.

4 Dec 24, 2021
Minimal API for the COVID Booking System of the Offices at the UniPD Math Dep

Simple and easy to use python BOT for the COVID registration booking system of the math department @ unipd (torre archimede). This API creates an interface with the official website, with more useful functionalities.

4 Dec 24, 2021
Gives you more advanced math in python.

AdvancedPythonMath Gives you more advanced math in python. Functions .simplex(args: {number}) .circ(args: {raidus}) .pytha(args: {leg_a + leg_2}) .slo

1 Dec 25, 2021
Function-Plotter - GUI Application to plot math Functions

Function Plotter GUI Application to plot a user given function How to run instal

1 May 5, 2022