TL;DR: you almost certainly have a local file named matplotlib.py or animation.py that shadows the real library. Find it and rename it, then the import works.

## The error
```text
ImportError: cannot import name 'animation' from partially initialized module 'matplotlib'
```

## Fix it
1. Find the shadowing file. From the directory where the error happens:
   ```
   ls matplotlib.py animation.py 2>/dev/null; python -c "import matplotlib; print(matplotlib.__file__)"
   ```
   Expected: either ls finds a local matplotlib.py/animation.py, or the printed path points at your own file instead of site-packages.
2. Rename the shadowing file to something that does not collide, e.g. my_animation.py. Also delete any matching .pyc or __pycache__ entries.
3. Verify:
   ```
   python -c "from matplotlib import animation; print('ok')"
   ```
   Expected: prints ok.

## When this applies
Use this when the error says partially initialized module 'matplotlib' and mentions a circular import.

## When it does not apply
If no local file shadows matplotlib, check sys.path for a stray directory containing a matplotlib folder. Genuine matplotlib-internal circular imports are rare and would be a bug in matplotlib itself.

## Compatibility
All Python and matplotlib versions; this is a filename collision, not a version issue.

## Root cause
Python resolves imports against the current directory first. A script or module named matplotlib.py (or a folder named matplotlib) in your working directory gets picked up instead of the installed package, so the real package never finishes initializing.

## Edge cases
Jupyter notebooks run with the notebook directory on sys.path, so a notebook-adjacent matplotlib.py breaks every notebook in that folder. The same class of bug hits any package name you reuse locally (random.py, email.py, and statistics.py are classic repeat offenders).