Quick Start#
It’s easy as 1 - 2 - 3!
1 - import package#
The standard is to abbreviate ahlive
as ah
.
[1]:
import ahlive as ah
2 - load data#
Here, CO2 concentrations data is fetched.
[2]:
df = ah.open_dataset("annual_co2", names=["year", "co2", "uncertainty"], verbose=True)
display(df)
ANNUAL CO2
Source: NOAA ESRL
https://www.esrl.noaa.gov/
Description: The carbon dioxide data on Mauna Loa constitute the longest record of direct measurements of CO2 in the atmosphere. They were started by C. David Keeling of the Scripps Institution of Oceanography in March of 1958 at a facility of the National Oceanic and Atmospheric Administration [Keeling, 1976]. NOAA started its own CO2 measurements in May of 1974, and they have run in parallel with those made by Scripps since then [Thoning, 1989].
Data: https://www.esrl.noaa.gov/gmd/webdata/ccgg/trends/co2/co2_annmean_mlo.txt
year | co2 | uncertainty | |
---|---|---|---|
0 | 1959 | 315.98 | 0.12 |
1 | 1960 | 316.91 | 0.12 |
2 | 1961 | 317.64 | 0.12 |
3 | 1962 | 318.45 | 0.12 |
4 | 1963 | 318.99 | 0.12 |
... | ... | ... | ... |
59 | 2018 | 408.72 | 0.12 |
60 | 2019 | 411.66 | 0.12 |
61 | 2020 | 414.24 | 0.12 |
62 | 2021 | 416.45 | 0.12 |
63 | 2022 | 418.56 | 0.12 |
64 rows × 3 columns
3 - generate animation#
Simply input the dataframe, df
and map the dataframe’s column names to the plot’s axes, xs
and ys
.
[3]:
ah.DataFrame(
df,
xs="year",
ys="co2",
).render()
gifsicle: warning: trivial adaptive palette (only 234 colors in source)
[3]:
add refinements#
In just three steps, an animation was output, but don’t stop there! Take advantage of the features supported in ahlive, conveniently accessible by keywords!
[4]:
import ahlive as ah
df, meta = ah.open_dataset(
"annual_co2",
names=["year", "co2", "uncertainty"],
index_col="year",
return_meta=True
)
df_cummax = df.cummax()
ah.DataFrame(
df,
# map columns to axes
xs="year",
ys="co2",
# add dynamic labels
inline_labels="co2",
state_labels="year",
# add static labels
title=meta["label"].title(),
ylabel="CO2 Concentrations [PPM]",
note=meta["base_url"],
caption=meta["description"].split("\n")[0].title(),
# adjust dynamic limits
ylim1s="fixed",
xlim1s="explore_5",
# adjust figure
figsize=(13, 7),
ymargins=0.1
).reference(
y0s=df_cummax["co2"],
inline_labels=df_cummax["co2"],
inline_locs=1000
).remark(
"Intergovernmental Panel on Climate Change (IPCC) is established",
xs=1988
).remark(
"CO2 levels surpasses 400 PPM for the first time in recorded history",
xs=2016 # based off Scripp's records
).config(**{
"ref_inline": dict(prefix="Record max of ", suffix=" PPM", ha="center"),
"inline": dict(suffix=" PPM"),
"caption": dict(width=120)
}).render()
/home/docs/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/easing.py:193: FutureWarning: In the future `np.object` will be defined as the corresponding NumPy scalar.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[4], line 48
3 df, meta = ah.open_dataset(
4 "annual_co2",
5 names=["year", "co2", "uncertainty"],
6 index_col="year",
7 return_meta=True
8 )
9 df_cummax = df.cummax()
11 ah.DataFrame(
12 df,
13 # map columns to axes
14 xs="year",
15 ys="co2",
16
17 # add dynamic labels
18 inline_labels="co2",
19 state_labels="year",
20
21 # add static labels
22 title=meta["label"].title(),
23 ylabel="CO2 Concentrations [PPM]",
24 note=meta["base_url"],
25 caption=meta["description"].split("\n")[0].title(),
26
27 # adjust dynamic limits
28 ylim1s="fixed",
29 xlim1s="explore_5",
30
31 # adjust figure
32 figsize=(13, 7),
33 ymargins=0.1
34 ).reference(
35 y0s=df_cummax["co2"],
36 inline_labels=df_cummax["co2"],
37 inline_locs=1000
38 ).remark(
39 "Intergovernmental Panel on Climate Change (IPCC) is established",
40 xs=1988
41 ).remark(
42 "CO2 levels surpasses 400 PPM for the first time in recorded history",
43 xs=2016 # based off Scripp's records
44 ).config(**{
45 "ref_inline": dict(prefix="Record max of ", suffix=" PPM", ha="center"),
46 "inline": dict(suffix=" PPM"),
47 "caption": dict(width=120)
---> 48 }).render()
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/animation.py:1998, in Animation.render(self)
1997 def render(self):
-> 1998 self_copy = self.finalize()
1999 try:
2000 data = self_copy.data
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/data.py:1417, in Data.finalize(self)
1415 ds = self_copy._precompute_base(ds, chart) # must be after config chart
1416 ds = self_copy._add_geo_tiles(ds) # before interp
-> 1417 ds = self_copy._interp_dataset(ds)
1418 ds = self_copy._add_geo_transforms(ds, chart) # after interp
1419 ds = self_copy._add_geo_features(ds)
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/data.py:1115, in Data._interp_dataset(self, ds)
1114 def _interp_dataset(self, ds):
-> 1115 ds = ds.map(self.interpolate, keep_attrs=True)
1117 if "s" in ds:
1118 ds["s"] = fillna(ds["s"].where(ds["s"] >= 0), how="both")
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/xarray-2023.4.2-py3.11.egg/xarray/core/dataset.py:5964, in Dataset.map(self, func, keep_attrs, args, **kwargs)
5962 if keep_attrs is None:
5963 keep_attrs = _get_keep_attrs(default=False)
-> 5964 variables = {
5965 k: maybe_wrap_array(v, func(v, *args, **kwargs))
5966 for k, v in self.data_vars.items()
5967 }
5968 if keep_attrs:
5969 for k, v in variables.items():
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/xarray-2023.4.2-py3.11.egg/xarray/core/dataset.py:5965, in <dictcomp>(.0)
5962 if keep_attrs is None:
5963 keep_attrs = _get_keep_attrs(default=False)
5964 variables = {
-> 5965 k: maybe_wrap_array(v, func(v, *args, **kwargs))
5966 for k, v in self.data_vars.items()
5967 }
5968 if keep_attrs:
5969 for k, v in variables.items():
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/easing.py:79, in Easing.interpolate(self, da, name)
77 array_dtype = array.dtype
78 if name in ["duration", "remark", "xerr", "yerr"] and not is_errorbar_morph:
---> 79 result = self._interp_first(
80 array, num_states, num_steps, num_items, num_result, name
81 )
82 elif interp == "fill" or name.endswith(
83 ("zoom", "discrete_trail", "morph_trail", "tick_label", "bar_label")
84 ):
85 result = self._interp_fill(array, num_states, num_steps, name)
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/ahlive-1.0.4.post1+dirty-py3.11.egg/ahlive/easing.py:193, in Easing._interp_first(self, array, num_states, num_steps, num_items, num_result, name)
191 if is_str(array):
192 fill = ""
--> 193 dtype = np.object
194 else:
195 fill = 0.0
File ~/checkouts/readthedocs.org/user_builds/ahlive/conda/latest/lib/python3.11/site-packages/numpy/__init__.py:305, in __getattr__(attr)
300 warnings.warn(
301 f"In the future `np.{attr}` will be defined as the "
302 "corresponding NumPy scalar.", FutureWarning, stacklevel=2)
304 if attr in __former_attrs__:
--> 305 raise AttributeError(__former_attrs__[attr])
307 # Importing Tester requires importing all of UnitTest which is not a
308 # cheap import Since it is mainly used in test suits, we lazy import it
309 # here to save on the order of 10 ms of import time for most users
310 #
311 # The previous way Tester was imported also had a side effect of adding
312 # the full `numpy.testing` namespace
313 if attr == 'testing':
AttributeError: module 'numpy' has no attribute 'object'.
`np.object` was a deprecated alias for the builtin `object`. To avoid this error in existing code, use `object` by itself. Doing this will not modify any behavior and is safe.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
explore datasets#
See, it’s that easy to get started. Don’t have a dataset readily available? No worries!
ahlive has a bunch of built-in datasets ready to use; learn more at Fetching.