Repository: yt-project/yt

Issue:
BUG: can't use annotate_timestamp with code units
<!--To help us understand and resolve your issue, please fill out the form to
the best of your ability.-->
<!--You can feel free to delete the sections that do not apply.-->

### Bug report

**Bug summary**

When loading a data set using code units, `p.annotate_timestamp()` fails.

**Code for reproduction**

<!--A minimum code snippet required to reproduce the bug, also minimizing the
number of dependencies required.-->

<!-- If you need to use a data file to trigger the issue you're having, consider
using one of the datasets from the yt data hub (http://yt-project.org/data). If
your issue cannot be triggered using a public dataset, you can use the yt
curldrop (https://docs.hub.yt/services.html#curldrop) to share data
files. Please include a link to the dataset in the issue if you use the
curldrop.-->

```python
import yt
from yt.testing import fake_random_ds

ds = fake_random_ds(64, unit_system="code")
p = yt.SlicePlot(ds,"x",("gas", "density"))
p.annotate_timestamp()
p.save("timestamp.png")
```

**Actual outcome**

```
$ python timestamp.py
yt : [INFO     ] 2022-03-29 16:08:23,834 Parameters: current_time              = 0.0
yt : [INFO     ] 2022-03-29 16:08:23,834 Parameters: domain_dimensions         = [64 64 64]
yt : [INFO     ] 2022-03-29 16:08:23,834 Parameters: domain_left_edge          = [0. 0. 0.]
yt : [INFO     ] 2022-03-29 16:08:23,835 Parameters: domain_right_edge         = [1. 1. 1.]
yt : [INFO     ] 2022-03-29 16:08:23,835 Parameters: cosmological_simulation   = 0
yt : [INFO     ] 2022-03-29 16:08:24,111 xlim = 0.000000 1.000000
yt : [INFO     ] 2022-03-29 16:08:24,111 ylim = 0.000000 1.000000
yt : [INFO     ] 2022-03-29 16:08:24,111 xlim = 0.000000 1.000000
yt : [INFO     ] 2022-03-29 16:08:24,111 ylim = 0.000000 1.000000
yt : [INFO     ] 2022-03-29 16:08:24,112 Making a fixed resolution buffer of (('gas', 'density')) 800 by 800
Traceback (most recent call last):
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_modifications.py", line 2530, in __call__
    un = self.time_unit.latex_representation()
AttributeError: 'Symbol' object has no attribute 'latex_representation'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_window.py", line 1399, in run_callbacks
    callback(cbw)
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_modifications.py", line 41, in _check_geometry
    return func(self, plot)
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_modifications.py", line 2534, in __call__
    raise RuntimeError(
RuntimeError: The time unit str repr didn't match expectations, something is wrong.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "~/Documents/IPAG/ReposDivers/bugs_yt/timestamp.py", line 7, in <module>
    p.save("timestamp.png")
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_container.py", line 109, in newfunc
    args[0]._setup_plots()
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_window.py", line 1265, in _setup_plots
    self.run_callbacks()
  File "~/.pyenv/versions/yt-timestamp/lib/python3.9/site-packages/yt/visualization/plot_window.py", line 1403, in run_callbacks
    raise YTPlotCallbackError(callback._type_name) from e
yt.utilities.exceptions.YTPlotCallbackError: annotate_timestamp callback failed

```

**Version Information**
<!--Please specify your platform and versions of the relevant libraries you are
using:-->
  * Operating System: Debian 5.10.106-1 x86_64 GNU/Linux
  * Python Version: 3.9.9
  * yt version: 4.0.2 (installed through `pip install yt`) and 4.1.dev0 (through `pip install -e .` in cloned repo)

<!--Please tell us how you installed yt and python e.g., from source,
pip, conda. If you installed from conda, please specify which channel you used
if not the default-->



Discussion:
Hi, and welcome to yt!  Thanks for opening your first issue.  We have an issue template that helps us to gather relevant information to help diagnosing and fixing the issue.

Thanks Marc, really appreciate the report !
So unfortunately this seems reminiscent of a bunch of problems we've had in the past with "code" unit system. Here's a summary of what I could find back:
- #2353 (closed by #2354)
- #2432 (closed by #2435)
- other PR without an issue: #2728
- akin to #2913 (closed by #3618)



This bisects to fda512b6701d6590a5c8a83c821b6f4e0e7aa2a3 from #3618, which makes it a regression in yt 4.0.2, so let's target this to yt 4.0.3



Resolving patch:
diff --git a/yt/visualization/plot_modifications.py b/yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -2629,11 +2629,7 @@ def __call__(self, plot):
                 # here the time unit will be in brackets on the annotation.
                 un = self.time_unit.latex_representation()
                 time_unit = r"$\ \ (" + un + r")$"
-            except AttributeError as err:
-                if plot.ds._uses_code_time_unit:
-                    raise RuntimeError(
-                        "The time unit str repr didn't match expectations, something is wrong."
-                    ) from err
+            except AttributeError:
                 time_unit = str(self.time_unit).replace("_", " ")
             self.text += self.time_format.format(time=float(t), units=time_unit)
 


Test patch:
diff --git a/yt/visualization/tests/test_callbacks.py b/yt/visualization/tests/test_callbacks.py
--- a/yt/visualization/tests/test_callbacks.py
+++ b/yt/visualization/tests/test_callbacks.py
@@ -92,6 +92,15 @@ def test_timestamp_callback():
         assert_fname(p.save(prefix)[0])
 
 
+def test_timestamp_callback_code_units():
+    # see https://github.com/yt-project/yt/issues/3869
+    with _cleanup_fname() as prefix:
+        ds = fake_random_ds(2, unit_system="code")
+        p = SlicePlot(ds, "z", ("gas", "density"))
+        p.annotate_timestamp()
+        assert_fname(p.save(prefix)[0])
+
+
 def test_scale_callback():
     with _cleanup_fname() as prefix:
         ax = "z"