Unexpected scaling behavior (especially complicated VGroup object)
Description of bug / unexpected behavior
When using VGroup.scale(), some unexpected behavior emerges. The stroke width gets funny. I know there's a "scale_stroke" parameter which does the trick, but the result is quite undesired when it comes to SVGMobject and it's derivatives (e.g. Text, MathTex, Tex...) I'll provide a detailed example below.
Example
Recently, I drew an Arduino UNO using manim. It looks like this:
However, when I wanted to shrink it... I wrote:
from manim import *
class ArduinoUNO(Scene):
def construct(self):
#Code to construct the whole thing
board.scale(0.3)
self.add(board)So, the stoke width looks horrible. Later, I learned that setting scale_stroke=True does the trick. So...
from manim import *
class ArduinoUNO(Scene):
def construct(self):
#Code to construct the whole thing
board.scale(0.3,scale_stroke=True)
self.add(board)Yes, almost everyting's okay... except Text, MathTex and Tex. The texts looked as if they were set bold.
Conclusion:
- scale(): texts are okay, others are not
- scale(scale_stroke): texts are not okay, others are
- so I need a function that scales everything correctly.
Repairing
So, after a bit of work I managed to solve the issue. I created a new function, and I merged it into VGroup.
class MixGroup:
def proportional_scale(self,factor,**kwargs):
self.scale(factor)
for mob in self.get_family():
if not (isinstance(mob,SVGMobject) or isinstance(mob,VDict) or isinstance(mob,VGroup)):
w = mob.get_stroke_width()
if w > 0:
mob.set_stroke(width=abs(factor) * w)
mob.set_stroke(
width=abs(factor) * mob.get_stroke_width(background=True),
background=True,
)
return self
class VGroup(MixGroup,VGroup): passfrom manim import *
class ArduinoUNO(Scene):
def construct(self):
#Code to construct the whole thing
board.proportional_scale(scale_stroke=True)
self.add(board)
Explanation: this newly created proportional_scale works by treating SVGMobject and other objects differently. It first scales everything, and then it fixes the stroke width of non-SVGMobjects.
So far, everything behaves as expected.
System specifications
System Details- OS: Zorin OS 17 (Linux lenovo-xiaoxinair-14iml-2019-linux 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 x86_64 x86_64 GNU/Linux)
- RAM: 12 GB
- Python version (
python/py/python3 --version): Python 3.10.12 - Installed modules (provide output from
pip list):
Package Version
----------------------- ----------------------
aiohappyeyeballs 2.6.1
aiohttp 3.13.3
aioquic 1.2.0
aiosignal 1.4.0
apturl 0.5.2
asgiref 3.8.1
async-timeout 5.0.1
attrs 25.3.0
av 13.1.0
Babel 2.8.0
bcrypt 3.2.0
beautifulsoup4 4.14.2
blinker 1.9.0
Brlapi 0.8.3
Brotli 1.1.0
bsddb3 6.2.9
certifi 2026.1.4
cffi 1.17.1
chardet 4.0.0
charset-normalizer 3.4.4
click 8.1.8
cloup 3.0.8
colorama 0.4.4
command-not-found 0.3
cryptography 44.0.3
cupshelpers 1.0
dbus-python 1.2.18
decorator 5.2.1
defer 1.0.6
distro 1.7.0
distro-info 1.1+ubuntu0.2
dnspython 2.1.0
duplicity 0.8.21
edge-tts 7.2.7
evdev 1.4.0
fasteners 0.14.1
Flask 3.1.0
fleep 1.0.1
folder-color 0.2.0
frozenlist 1.8.0
fusepy 3.0.1
future 0.18.2
glcontext 3.0.0
h11 0.14.0
h2 4.1.0
hpack 4.1.0
httplib2 0.20.2
hyperframe 6.0.1
icoextract 0.1.2
idna 3.3
ifaddr 0.2.0
importlib-metadata 4.6.4
isosurfaces 0.1.2
itsdangerous 2.2.0
jeepney 0.7.1
Jinja2 3.1.6
kaitaistruct 0.10
keyring 23.5.0
language-selector 0.1
launchpadlib 1.10.16
lazr.restfulclient 0.14.4
lazr.uri 1.0.6
ldap3 2.9.1
libarchive-c 5.3
lockfile 0.12.2
louis 3.20.0
macaroonbakery 1.3.1
Mako 1.1.3
manim 0.19.1
ManimPango 0.6.1
mapbox_earcut 1.0.3
markdown-it-py 4.0.0
MarkupSafe 3.0.2
mdurl 0.1.2
mitmproxy 11.0.2
mitmproxy_rs 0.10.7
moderngl 5.12.0
moderngl-window 3.1.1
monotonic 1.6
more-itertools 8.10.0
msgpack 1.1.0
multidict 6.7.0
mutagen 1.47.0
netifaces 0.11.0
networkx 3.4.2
numpy 2.2.6
oauthlib 3.2.0
olefile 0.46
paramiko 2.9.3
passlib 1.7.4
pefile 2021.9.3
pexpect 4.8.0
pillow 12.0.0
pip 22.0.2
pip-autoremove 0.10.0
propcache 0.4.1
protobuf 3.12.4
psutil 5.9.0
ptyprocess 0.7.0
publicsuffix2 2.20191221
pyasn1 0.6.1
pyasn1_modules 0.4.2
PyAudio 0.2.11
pycairo 1.20.1
pycparser 2.22
pycups 2.0.1
pydub 0.25.1
pyelftools 0.27
pygame 2.6.1
pyglet 2.1.11
pyglm 2.8.2
Pygments 2.19.2
PyGObject 3.42.1
pyinotify 0.9.6
PyJWT 2.3.0
pylsqpack 0.3.22
pymacaroons 0.13.0
PyNaCl 1.5.0
pynput 1.8.1
pyOpenSSL 24.3.0
pyparsing 2.4.7
pyperclip 1.9.0
pyRFC3339 1.1
python-apt 2.4.0-ubuntu4.1-zorin1
python-dateutil 2.8.1
python-debian 0.1.43+ubuntu1.1
python-dotenv 0.21.1
python-slugify 8.0.4
python-xlib 0.33
pytz 2022.1
pyxdg 0.27
PyYAML 5.4.1
reportlab 3.6.8
requests 2.32.5
requests-toolbelt 0.9.1
rich 14.1.0
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.12
scipy 1.15.3
screen-resolution-extra 0.0.0
screeninfo 0.8.1
SecretStorage 3.3.1
service-identity 24.2.0
setuptools 59.6.0
simplejson 3.17.6
six 1.16.0
skia-pathops 0.8.0.post2
sortedcontainers 2.4.0
soupsieve 2.8
sox 1.5.0
srt 3.5.3
svgelements 1.9.6
tabulate 0.9.0
text-unidecode 1.3
tornado 6.4.2
tqdm 4.67.1
typing_extensions 4.15.0
ubuntu-drivers-common 0.0.0
ufw 0.36.1
unattended-upgrades 0.1
urllib3 1.26.5
urwid 2.6.16
vboxapi 1.0
wadllib 1.3.6
watchdog 6.0.0
wcwidth 0.2.13
Werkzeug 3.1.3
wheel 0.37.1
wsproto 1.2.0
xdg 5
xkit 0.0.0
yarl 1.22.0
zeroconf 0.147.2
zipp 1.0.0
zorin-appearance 5.3
zorin-connect 1.2
zorin-exec-guard 1.5
zstandard 0.23.0Source: ManimCommunity/manim