"""Text-related formatting functions."""
import itertools
import math
import os
import string
from ..calc import spatial_mean
from ..exceptions import ArgumentError
__all__ = (
"all_sim_file_label",
"cube_minmeanmax_str",
"fmt_lonlat",
"subplot_label_generator",
"tex2cf_units",
"unit_format",
)
[docs]
def all_sim_file_label(sims):
"""Make a shorter label for a list of labels with a common prefix."""
pref = os.path.commonprefix(sims)
return f"{pref}_{'_'.join([i.removeprefix(pref) for i in sims])}"
[docs]
def cube_minmeanmax_str(
cube,
sep=" | ",
eq_sign="=",
fmt="auto",
weight=True,
labels=None,
**kw_unit_format,
):
"""Return min, mean and max of an iris cube as a string."""
# Compute the stats
if labels is None:
labels = ["min", "mean", "max"]
_min = float(cube.data.min())
if weight:
_mean = float(spatial_mean(cube).data)
else:
_mean = float(cube.data.mean())
_max = float(cube.data.max())
# Assemble a string
txts = []
for label, num in zip(labels, [_min, _mean, _max]):
if fmt == "auto":
if (math.log10(abs(_mean)) < 0) or (math.log10(abs(_mean)) > 5):
_str = f"{label}{eq_sign}{num:.0e}"
else:
_str = f"{label}{eq_sign}{round(num):.0f}"
elif fmt == "pretty":
_str = f"{label}{eq_sign}{unit_format(num, **kw_unit_format)}"
else:
_str = f"{label}{eq_sign}{num:{fmt}}"
txts.append(_str)
return sep.join(txts)
[docs]
def fmt_lonlat(value, lon_or_lat, degree=False):
r"""
Convert longitude or latitude value to string with a hemisphere identifier.
Parameters
----------
value: int
Value of longitude or latitude.
Note that this function is only for integer values.
lon_or_lat: str
Longitude or latitude
degree: bool, optional
If true, a TeX degree symbol is included
Returns
-------
str
Examples
--------
>>> fmt_lonlat(-25, "lon")
'25W'
>>> fmt_lonlat(89, "lat", degree=True)
'89$^\\degree$N'
>>> fmt_lonlat(0, "lon")
'0'
"""
from LatLon23 import Latitude, Longitude # noqa
if lon_or_lat.lower().startswith("lat"):
res = Latitude(value)
elif lon_or_lat.lower().startswith("lon"):
res = Longitude(value)
else:
raise ArgumentError(
"2nd arg or the function should start with `lon` or `lat`"
)
out = res.to_string("%d%H")
if degree:
out = out[:-1] + r"$^\degree$" + out[-1]
if value == 0:
out = out[:-1]
return out
[docs]
def subplot_label_generator():
"""Return generator of alphabetic labelling of subplots."""
for i in itertools.count(1):
for p in itertools.product(string.ascii_lowercase, repeat=i):
yield "".join(p)
[docs]
def tex2cf_units(unit_str):
"""Convert a TeX string to a string that can be used in cf_units."""
return (
unit_str.replace("$", "")
.replace("{", "")
.replace("}", "")
.replace("^", "**")
)