ManimCommunity / ManimCommunity/manim

Surprising `Axes.__init__` default values

Open
#2,479 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

issue:bug
Dominant language
Python
Stars
40.9k
Forks
3.1k
Avg merge
3d 12h
Merged PRs (30d)
25

Description

## Description of bug / unexpected behavior

When using `Axes`, knowing that the defaults for `x_length` and `y_length` are based upon the values of `config.frame_width` and `config.frame_height`, I set the latter two to a square: 15x15

The resulting `Axes` class had as its defaults values based upon the `config.frame_*` _defaults_, meaning that despite setting these in my code, the parse-time defaults of 14.2 and 8.0 were used.

This is only a "bug" in the sense that the behavior is confusing. I could well be abusing the config system by setting these values in my scripts...

I believe a better behavior would be to test for `None`-ness _inside of init_ so the "current" (from the script's timeline point of view) values of `config.frame_` are used to calculate the defaults.

## Expected behavior

I expected the resulting `Axes.*_length` values to be 13x13 (15-2).

## How to reproduce the issue

Code for reproducing the problem

I changed the `round` calls in the `Axes.__init__` to be `dround` and created a wrapper function that prints the values of `config.frame_*` and added print statements inside of `__init__` to print the values of `self.*_length`. Here are the changes.

Note that this is daf23c9d1031b12d9c119b8f6b7e60727d7f9242 / aka 0.14.0

```diff
$ git diff manim/mobject/coordinate_systems.py
diff --git a/manim/mobject/coordinate_systems.py b/manim/mobject/coordinate_systems.py
index 0a402f26..7083c877 100644
--- a/manim/mobject/coordinate_systems.py
+++ b/manim/mobject/coordinate_systems.py
@@ -12,6 +12,11 @@ __all__ = [
"ComplexPlane",
]

+def dround(value):
+ print("Value of config.frame_height when Axes.__init__ parsed: %s" % config.frame_height)
+ print("Value of config.frame_width when Axes.__init__ parsed: %s" % config.frame_width)
+ return round(value)
+
import fractions as fr
import numbers
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union
@@ -1752,8 +1757,8 @@ class Axes(VGroup, CoordinateSystem, metaclass=ConvertToOpenGL):
self,
x_range: Sequence[float] | None = None,
y_range: Sequence[float] | None = None,
- x_length: float | None = round(config.frame_width) - 2,
- y_length: float | None = round(config.frame_height) - 2,
+ x_length: float | None = dround(config.frame_width) - 2,
+ y_length: float | None = dround(config.frame_height) - 2,
axis_config: dict | None = None,
x_axis_config: dict | None = None,
y_axis_config: dict | None = None,
@@ -1763,6 +1768,9 @@ class Axes(VGroup, CoordinateSystem, metaclass=ConvertToOpenGL):
VGroup.__init__(self, **kwargs)
CoordinateSystem.__init__(self, x_range, y_range, x_length, y_length)

+ print("Value of self.y_length when I actually *call* Axes.__init__: %s" % self.y_length)
+ print("Value of self.x_length when I actually *call* Axes.__init__: %s" % self.x_length)
+
self.axis_config = {
"include_tip": tips,
```

I then ran the following script

```py

print("About to import manim...")
from manim import *
print("...manim has been imported")

config.frame_height = 15
config.frame_width = 15

print("Value of config.frame_height when I use my script: %s" % config.frame_height)
print("Value of config.frame_width when I use my script: %s" % config.frame_width)

axes = Axes()

print("")
print("Value of axes.y_length when I actually *call* Axes.__init__: %s" % axes.y_length)
print("Value of axes.x_length when I actually *call* Axes.__init__: %s" % axes.x_length)
```

Which prints the following:

```
About to import manim...
Value of config.frame_height when Axes.__init__ parsed: 8.0
Value of config.frame_width when Axes.__init__ parsed: 14.222222222222221
Value of config.frame_height when Axes.__init__ parsed: 8.0
Value of config.frame_width when Axes.__init__ parsed: 14.222222222222221
Manim Community v0.14.0

...manim has been imported
Value of config.frame_height when I use my script: 15
Value of config.frame_width when I use my script: 15
Value of self.y_length when I actually *call* Axes.__init__: 6
Value of self.x_length when I actually *call* Axes.__init__: 12

Value of axes.y_length when I actually *call* Axes.__init__: 6
Value of axes.x_length when I actually *call* Axes.__init__: 12
```

(Not sure why only importing causes two passes...)

If I make these changes:

```diff
diff --git a/manim/mobject/coordinate_systems.py b/manim/mobject/coordinate_systems.py
index 0a402f26..66e2d2fb 100644
--- a/manim/mobject/coordinate_systems.py
+++ b/manim/mobject/coordinate_systems.py
@@ -1752,14 +1752,17 @@ class Axes(VGroup, CoordinateSystem, metaclass=ConvertToOpenGL):
self,
x_range: Sequence[float] | None = None,
y_range: Sequence[float] | None = None,
- x_length: float | None = round(config.frame_width) - 2,
- y_length: float | None = round(config.frame_height) - 2,
+ x_length: float | None = None,
+ y_length: float | None = None,
axis_config: dict | None = None,
x_axis_config: dict | None = None,
y_axis_config: dict | None = None,
tips: bool = True,
**kwargs,
):
+ x_length = round(config.frame_width) - 2 if x_length is None else x_length
+ y_length = round(config.frame_width) - 2 if y_length is None else y_length
+
VGroup.__init__(self, **kwargs)
CoordinateSystem.__init__(self, x_range, y_range, x_length, y_length)

```

...then the above script prints...

```
About to import manim...
Manim Community v0.14.0

...manim has been imported
Value of config.frame_height when I use my script: 15
Value of config.frame_width when I use my script: 15

Value of axes.y_length when I actually *call* Axes.__init__: 13
Value of axes.x_length when I actually *call* Axes.__init__: 13
```

## Additional media files

Images/GIFs

## Logs
Terminal output

```
PASTE HERE OR PROVIDE LINK TO https://pastebin.com/ OR SIMILAR
```

## System specifications

System Details

- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)): OSX Big Sur 11.6.2 (20G314)
- RAM:
- Python version (`python/py/python3 --version`): 3.9.9
- Installed modules (provide output from `pip list`):
```
Package Version Editable project location
------------------------------------------------- ------------- ---------------------------
aiohttp 3.8.1
aiosignal 1.2.0
alabaster 0.7.12
apipkg 1.5
appdirs 1.4.4
appnope 0.1.2
asttokens 2.0.5
async-timeout 4.0.1
asynctest 0.13.0
attrs 21.2.0
Babel 2.9.1
backcall 0.2.0
base58 2.1.1
bitarray 1.2.2
black 21.11b1
butterfly 3.2.5
cached-property 1.5.2
cachetools 4.2.4
certifi 2021.10.8
cffi 1.14.6
chardet 4.0.0
charset-normalizer 2.0.9
click 8.0.3
click-default-group 1.2.2
cloup 0.7.1
colorama 0.4.4
colour 0.1.5
commonmark 0.9.1
cryptography 3.4.7
Cython 0.29.26
cytoolz 0.11.2
dataclassy 0.11.1
decorator 5.0.9
docutils 0.17.1
eip712 0.1.0
eth-abi 2.1.1
eth-account 0.5.6
eth-bloom 1.0.4
eth-brownie 1.17.2 /Users/mburr/git/brownie
eth-event 1.2.3
eth-hash 0.3.2
eth-keyfile 0.5.1
eth-keys 0.3.3
eth-rlp 0.2.1
eth-tester 0.6.0b4
eth-typing 2.2.2
eth-utils 1.10.0
execnet 1.9.0
frozenlist 1.2.0
gitdb 4.0.9
GitPython 3.1.26
glcontext 2.3.4
google-api-core 2.3.2
google-auth 2.3.3
google-cloud-texttospeech 2.9.0
googleapis-common-protos 1.54.0
grpcio 1.43.0
grpcio-status 1.43.0
hexbytes 0.2.2
hypothesis 6.27.3
idna 3.3
imagesize 1.3.0
importlib-metadata 4.8.2
inflection 0.5.0
iniconfig 1.1.1
ipdb 0.13.9
ipfshttpclient 0.8.0a2
ipython 7.24.0
ipython-genutils 0.2.0
isosurfaces 0.1.0
jedi 0.18.0
Jinja2 3.0.3
jsonschema 3.2.0
lazy-object-proxy 1.6.0
lru-dict 1.1.7
manim 0.14.0
ManimPango 0.4.0.post0
mapbox-earcut 0.12.11
MarkupSafe 2.0.1
MathChurch 0.0.11 /Users/mburr/git/MathChurch
matplotlib-inline 0.1.2
mnemonic 0.20
moderngl 5.6.4
moderngl-window 2.4.1
mpmath 1.2.1
multiaddr 0.0.9
multidict 5.2.0
multipledispatch 0.6.0
mutagen 1.45.1
mypy-extensions 0.4.3
mythx-models 1.9.1
netaddr 0.8.0
networkx 2.6.3
numpy 1.22.0
packaging 21.3
parsimonious 0.8.1
parso 0.8.2
pathspec 0.9.0
pexpect 4.8.0
pickleshare 0.7.5
Pillow 9.0.0
pip 21.3.1
platformdirs 2.4.0
pluggy 1.0.0
prompt-toolkit 3.0.23
proto-plus 1.19.8
protobuf 3.19.1
psutil 5.8.0
ptyprocess 0.7.0
pudb 2021.1
py 1.11.0
py-ecc 4.1.0
py-evm 0.5.0a1
py-geth 3.7.0
py-solc-ast 1.2.9
py-solc-x 1.1.1
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycairo 1.20.1
pycoin 0.91.20210515
pycparser 2.20
pycrypto 2.6.1
pycryptodome 3.12.0
pydub 0.25.1
pyethash 0.1.27
pyglet 1.5.21
Pygments 2.10.0
pygments-lexer-solidity 0.7.0
PyJWT 1.7.1
pyobjc 8.1
pyobjc-core 8.1
pyobjc-framework-Accessibility 8.1
pyobjc-framework-Accounts 8.1
pyobjc-framework-AddressBook 8.1
pyobjc-framework-AdServices 8.1
pyobjc-framework-AdSupport 8.1
pyobjc-framework-AppleScriptKit 8.1
pyobjc-framework-AppleScriptObjC 8.1
pyobjc-framework-ApplicationServices 8.1
pyobjc-framework-AppTrackingTransparency 8.1
pyobjc-framework-AudioVideoBridging 8.1
pyobjc-framework-AuthenticationServices 8.1
pyobjc-framework-AutomaticAssessmentConfiguration 8.1
pyobjc-framework-Automator 8.1
pyobjc-framework-AVFoundation 8.1
pyobjc-framework-AVKit 8.1
pyobjc-framework-BusinessChat 8.1
pyobjc-framework-CalendarStore 8.1
pyobjc-framework-CallKit 8.1
pyobjc-framework-CFNetwork 8.1
pyobjc-framework-ClassKit 8.1
pyobjc-framework-CloudKit 8.1
pyobjc-framework-Cocoa 8.1
pyobjc-framework-Collaboration 8.1
pyobjc-framework-ColorSync 8.1
pyobjc-framework-Contacts 8.1
pyobjc-framework-ContactsUI 8.1
pyobjc-framework-CoreAudio 8.1
pyobjc-framework-CoreAudioKit 8.1
pyobjc-framework-CoreBluetooth 8.1
pyobjc-framework-CoreData 8.1
pyobjc-framework-CoreHaptics 8.1
pyobjc-framework-CoreLocation 8.1
pyobjc-framework-CoreMedia 8.1
pyobjc-framework-CoreMediaIO 8.1
pyobjc-framework-CoreMIDI 8.1
pyobjc-framework-CoreML 8.1
pyobjc-framework-CoreMotion 8.1
pyobjc-framework-CoreServices 8.1
pyobjc-framework-CoreSpotlight 8.1
pyobjc-framework-CoreText 8.1
pyobjc-framework-CoreWLAN 8.1
pyobjc-framework-CryptoTokenKit 8.1
pyobjc-framework-DeviceCheck 8.1
pyobjc-framework-DictionaryServices 8.1
pyobjc-framework-DiscRecording 8.1
pyobjc-framework-DiscRecordingUI 8.1
pyobjc-framework-DiskArbitration 8.1
pyobjc-framework-DVDPlayback 8.1
pyobjc-framework-EventKit 8.1
pyobjc-framework-ExceptionHandling 8.1
pyobjc-framework-ExecutionPolicy 8.1
pyobjc-framework-ExternalAccessory 8.1
pyobjc-framework-FileProvider 8.1
pyobjc-framework-FileProviderUI 8.1
pyobjc-framework-FinderSync 8.1
pyobjc-framework-FSEvents 8.1
pyobjc-framework-GameCenter 8.1
pyobjc-framework-GameController 8.1
pyobjc-framework-GameKit 8.1
pyobjc-framework-GameplayKit 8.1
pyobjc-framework-ImageCaptureCore 8.1
pyobjc-framework-IMServicePlugIn 8.1
pyobjc-framework-InputMethodKit 8.1
pyobjc-framework-InstallerPlugins 8.1
pyobjc-framework-InstantMessage 8.1
pyobjc-framework-Intents 8.1
pyobjc-framework-IOSurface 8.1
pyobjc-framework-iTunesLibrary 8.1
pyobjc-framework-KernelManagement 8.1
pyobjc-framework-LatentSemanticMapping 8.1
pyobjc-framework-LaunchServices 8.1
pyobjc-framework-libdispatch 8.1
pyobjc-framework-LinkPresentation 8.1
pyobjc-framework-LocalAuthentication 8.1
pyobjc-framework-MapKit 8.1
pyobjc-framework-MediaAccessibility 8.1
pyobjc-framework-MediaLibrary 8.1
pyobjc-framework-MediaPlayer 8.1
pyobjc-framework-MediaToolbox 8.1
pyobjc-framework-Metal 8.1
pyobjc-framework-MetalKit 8.1
pyobjc-framework-MetalPerformanceShaders 8.1
pyobjc-framework-MetalPerformanceShadersGraph 8.1
pyobjc-framework-MLCompute 8.1
pyobjc-framework-ModelIO 8.1
pyobjc-framework-MultipeerConnectivity 8.1
pyobjc-framework-NaturalLanguage 8.1
pyobjc-framework-NetFS 8.1
pyobjc-framework-Network 8.1
pyobjc-framework-NetworkExtension 8.1
pyobjc-framework-NotificationCenter 8.1
pyobjc-framework-OpenDirectory 8.1
pyobjc-framework-OSAKit 8.1
pyobjc-framework-OSLog 8.1
pyobjc-framework-PassKit 8.1
pyobjc-framework-PencilKit 8.1
pyobjc-framework-Photos 8.1
pyobjc-framework-PhotosUI 8.1
pyobjc-framework-PreferencePanes 8.1
pyobjc-framework-PushKit 8.1
pyobjc-framework-Quartz 8.1
pyobjc-framework-QuickLookThumbnailing 8.1
pyobjc-framework-ReplayKit 8.1
pyobjc-framework-SafariServices 8.1
pyobjc-framework-SceneKit 8.1
pyobjc-framework-ScreenSaver 8.1
pyobjc-framework-ScreenTime 8.1
pyobjc-framework-ScriptingBridge 8.1
pyobjc-framework-SearchKit 8.1
pyobjc-framework-Security 8.1
pyobjc-framework-SecurityFoundation 8.1
pyobjc-framework-SecurityInterface 8.1
pyobjc-framework-ServiceManagement 8.1
pyobjc-framework-Social 8.1
pyobjc-framework-SoundAnalysis 8.1
pyobjc-framework-Speech 8.1
pyobjc-framework-SpriteKit 8.1
pyobjc-framework-StoreKit 8.1
pyobjc-framework-SyncServices 8.1
pyobjc-framework-SystemConfiguration 8.1
pyobjc-framework-SystemExtensions 8.1
pyobjc-framework-UniformTypeIdentifiers 8.1
pyobjc-framework-UserNotifications 8.1
pyobjc-framework-UserNotificationsUI 8.1
pyobjc-framework-VideoSubscriberAccount 8.1
pyobjc-framework-VideoToolbox 8.1
pyobjc-framework-Virtualization 8.1
pyobjc-framework-Vision 8.1
pyobjc-framework-WebKit 8.1
pyOpenSSL 20.0.1
pyparsing 3.0.6
PyQt5 5.15.6
PyQt5-Qt5 5.15.2
PyQt5-sip 12.9.0
pyrr 0.10.3
pyrsistent 0.18.0
pysha3 1.0.2
pytest 6.2.5
pytest-forked 1.3.0
pytest-xdist 1.34.0
python-dateutil 2.8.1
python-dotenv 0.16.0
pythx 1.6.1
pyttsx3 2.91 /Users/mburr/git/pyttsx3
pytz 2021.3
PyYAML 5.4.1
regex 2021.11.10
requests 2.26.0
rich 10.16.2
rlp 2.0.1
rsa 4.8
scipy 1.7.3
screeninfo 0.6.7
secp256k1 0.14.0
semantic-version 2.8.5
setuptools 56.0.0
six 1.16.0
skia-pathops 0.7.2
smmap 5.0.0
snowballstemmer 2.2.0
sortedcontainers 2.4.0
Sphinx 4.3.1
sphinx-rtd-theme 1.0.0
sphinxcontrib-applehelp 1.0.2
sphinxcontrib-devhelp 1.0.2
sphinxcontrib-htmlhelp 2.0.0
sphinxcontrib-jsmath 1.0.1
sphinxcontrib-qthelp 1.0.3
sphinxcontrib-serializinghtml 1.1.5
srt 3.5.0
svgwrite 1.4.1
sympy 1.9
toml 0.10.2
tomli 1.2.2
toolz 0.11.2
tornado 6.1
tqdm 4.62.3
traitlets 5.0.5
trie 2.0.0a5
typed-ast 1.5.1
typing-extensions 3.10.0.2
urllib3 1.26.7
urwid 2.1.2
varint 1.0.2
vvm 0.1.0
vyper 0.3.1
watchdog 2.1.6
wcwidth 0.2.5
web3 5.25.0 /Users/mburr/git/web3.py
websockets 9.1
wheel 0.37.0
wrapt 1.13.3
yarl 1.7.2
zipp 3.6.0
```

LaTeX details

+ LaTeX distribution (e.g. TeX Live 2020):
+ Installed LaTeX packages:

FFMPEG

Output of `ffmpeg -version`:

```
PASTE HERE
```

## Additional comments

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in manim/mobject/coordinate_systems.py at Axes.__init__, where the default x_length and y_length values are defined. Reproduce the issue by setting config.frame_width and config.frame_height before creating Axes, then verify that omitted lengths reflect those current values while explicit lengths remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.