Repository: matplotlib/matplotlib
Pull request: Improve deleted Animation warning
Closes #20909.


Problem statement:
[Bug]: Animation error message
### Bug summary

once I executed my code by matplotlib.animation,  The programe response this without any animation: D:\Program Files\Python\Python38\lib\site-packages\matplotlib\animation.py:973: UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.


### Code for reproduction

```python
import matplotlib.animation
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
import pandas as pd
from matplotlib.animation import FuncAnimation


def update(date):
    # ax.clear()
    # dg = df[["Country", date]].sort_values(by=date, ascending=True).tail(10)
    ax.barh(range(10), df[date])


# 创建画布和初始参数
fig, ax = plt.subplots(figsize=(10, 5.625), dpi=100)

# 准备数据
df = pd.read_csv(r".\csv_test.csv")

date_list = df.columns[1:].unique().tolist()
# print(date_list)

a = FuncAnimation(fig=fig, func=update, frames=date_list, interval=50)
```


### Actual outcome

"D:\Program Files\Python\Python38\python.exe" "D:/pyCharm Project/Bar_chart_race/Barchart_race.py"
['2020/4/8', '2020/4/9', '2020/4/10', '2020/4/11', '2020/4/12']
3.4.3
D:\Program Files\Python\Python38\lib\site-packages\matplotlib\animation.py:973: UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.

Process finished with exit code 0

### Expected outcome

a live plot

### Operating system

Windows

### Matplotlib Version

3.4.3

### Matplotlib Backend

_No response_

### Python version

3.8.10

### Jupyter version

_No response_

### Other libraries

_No response_

### Installation

_No response_

### Conda channel

_No response_

Hints from issue discussion:
I beleive you are running this as `python my_script.py` or similar via an IDE?

If that is the case, then you either need to call `plt.show()` (which will bring up a blocking window to show your animation) or do `a.save('out.mp4')` (or similar) to save the animation to file.

What is happening is that after you last line you make `a`, but there is no more code to be run so Python says "right, my job is done!" and shuts the process down.  As part of shutting down the interpreter Python tears down all of the objects that you created, including the `Animation` object, which in turn notes that you created it and never used it (prior to us adding that warning your Python process would have just quietly and successfully exited!).

I suspect the action here is to make the waning message clearer about _how_ you would go about using the animation object (either calling `plt.show()` to get a window or `a.save`).
You have to output the animation. Either to screen (`plt.show()`) or to a file (`a.save(...)`).
@tacaswell I did not explicitly remove the documentation and Good first issue tags. It seems we've been simultaneously trying to tag and that confuses github 😏 .
The warning message here was tailored to the error case where the Animation object is not stored in a variable and immediately deleted after being created, e.g.
```
FuncAnimation(...)
plt.show()
```
We can't distinguish between this case and the case of no show/save. So the error message would have to cover both.

Commit message: Improve deleted Animation warning

Closes #20909.

Patch to review:
diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py
index 985181a574c6..846c7e18b04c 100644
--- a/lib/matplotlib/animation.py
+++ b/lib/matplotlib/animation.py
@@ -888,9 +888,9 @@ def __del__(self):
         if not getattr(self, '_draw_was_started', True):
             warnings.warn(
                 'Animation was deleted without rendering anything. This is '
-                'most likely unintended. To prevent deletion, assign the '
-                'Animation to a variable that exists for as long as you need '
-                'the Animation.')
+                'most likely not intended. To prevent deletion, assign the '
+                'Animation to a variable `anim` that exists until you have '
+                'outputted the Animation using `plt.show()` or `anim.save()`.')
 
     def _start(self, *args):
         """


Code review comments:
diff_hunk: @@ -888,9 +888,9 @@ def __del__(self):
         if not getattr(self, '_draw_was_started', True):
             warnings.warn(
                 'Animation was deleted without rendering anything. This is '
-                'most likely unintended. To prevent deletion, assign the '
-                'Animation to a variable that exists for as long as you need '
-                'the Animation.')
+                'most likely not intended. To prevent deletion, assign the '
+                'Animation to a variable `anim` that exists until you have '
path: lib/matplotlib/animation.py
text: @user1:
```suggestion
                'Animation to a variable that exists until you have '
```

@user1:
I think having a specific variable name is potentially confusing and unnecessary. 

@author:
I've introduced it to have context for the `anim.save()` below. Otherwise, IMHO it's hard to explain that.

We could say "to a variable, e.g. `anim`, that exists..."

@user2:
```suggestion
                'Animation to a variable, e.g. `anim`, that exists until you have '
```

I think adding the `e.g.` is the best option here.  I agree we do not want to give the impression that `anim` is a "special" name, but also want to make it clear what `anim` is when we use it later in the error message.