From fb9c29e33180af02aa8745e2d5c61c5dae05cd53 Mon Sep 17 00:00:00 2001 From: Jordan Landers Date: Thu, 12 Mar 2026 15:09:35 -0700 Subject: [PATCH 1/2] time unit bug fix Now requires time_unit to be specified and taps tsbase.disambiguate_time_metadata. Also includes a language flag (default to English) --- pyleoclim/utils/datasets.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/pyleoclim/utils/datasets.py b/pyleoclim/utils/datasets.py index a9066ff1..94d275a9 100644 --- a/pyleoclim/utils/datasets.py +++ b/pyleoclim/utils/datasets.py @@ -5,6 +5,8 @@ import pyleoclim as pyleo import yaml import pandas as pd + +from .tsbase import disambiguate_time_metadata from ..utils import jsonutils DATA_DIR = Path(__file__).parents[1].joinpath("data").resolve() @@ -230,7 +232,15 @@ def _localname(term): -def load_ics_chart_to_df(ttl_path_or_url="https://raw.githubusercontent.com/i-c-stratigraphy/chart/refs/heads/main/chart.ttl", time_units='Ma') -> pd.DataFrame: +def load_ics_chart_to_df(ttl_path_or_url="https://raw.githubusercontent.com/i-c-stratigraphy/chart/refs/heads/main/chart.ttl", + time_units='Ma', lang='en') -> pd.DataFrame: + + def _first_lang(iterable, lang=None): + for lit in iterable: + if isinstance(lit, Literal) and (lang is None or lit.language == lang): + return lit + return None + try: from rdflib import Graph, Namespace, URIRef, Literal @@ -285,8 +295,10 @@ def _find_ns_for_local(graph, local): rank_local = _localname(rank_uri) Rank = rank_map.get(rank_local, rank_local) - # Name - name_lit = _first(g.objects(subj, SKOS.prefLabel)) + + name_lit = _first_lang(g.objects(subj, SKOS.prefLabel), lang) + if name_lit is None: + name_lit = _first(g.objects(subj, SKOS.prefLabel)) Name = str(name_lit) if name_lit is not None else "" # Abbrev: skos:notation (typed literal is fine) @@ -354,19 +366,22 @@ def boundary_ma(node_pred): df["Rank"] = pd.Categorical(df["Rank"], categories=type_order + sorted(set(df["Rank"]) - set(type_order)), ordered=True) df = df.sort_values(["Rank", "UpperBoundary"], na_position="last").reset_index(drop=True) - if time_units not in ['Ma', 'Mya', 'My']: - if time_units in ['a', 'ya', 'y', 'yr']: + time_name, time_unit = disambiguate_time_metadata(time_units) + print(f"Time name: {time_name}") + print(f"Time unit: {time_unit}") + if time_unit not in ['Ma']:#['Ma', 'Mya', 'My']: + if time_unit in ['a', 'ya', 'y', 'yr', 'yrs', 'year', 'years']: df['UpperBoundary'] = df['UpperBoundary'] * 1e6 df['LowerBoundary'] = df['LowerBoundary'] * 1e6 - elif time_units in ['ka', 'kya', 'ky', 'kyr']: + elif time_unit in ['ka']:#['ka', 'kya', 'ky', 'kyr']: df['UpperBoundary'] = df['UpperBoundary'] * 1e3 df['LowerBoundary'] = df['LowerBoundary'] * 1e3 print('converted to ka') - elif time_units in ['Ga', 'Gya', 'Gy', 'Gyr']: + elif time_unit in ['Ga']:#['Ga', 'Gya', 'Gy', 'Gyr']: df['UpperBoundary'] = df['UpperBoundary'] * 1e-3 df['LowerBoundary'] = df['LowerBoundary'] * 1e-3 else: - raise ValueError(f"Unsupported time_units '{time_units}'. Supported: 'Ma', 'ka', 'Ga'.") + raise ValueError(f"Unsupported time_units '{time_unit}'. Supported: 'Ma', 'ka', 'Ga'.") return df From 663a14eb90f7f3be8b528327522f072883c70eb4 Mon Sep 17 00:00:00 2001 From: Jordan Landers Date: Thu, 12 Mar 2026 15:10:29 -0700 Subject: [PATCH 2/2] time_unit requirement and langauge now requires time_unit to be specified and label language can be changed --- pyleoclim/utils/plotting.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyleoclim/utils/plotting.py b/pyleoclim/utils/plotting.py index 5433a53e..bd830cf0 100644 --- a/pyleoclim/utils/plotting.py +++ b/pyleoclim/utils/plotting.py @@ -1518,9 +1518,9 @@ def text_loc(fig, ax, rect, label_text, width, yloc): text.remove() return loc -def add_GTS(fig, ax, GTS_df=None, ranks=None, time_units='Ma',location='above', label_pref='full', +def add_GTS(fig, ax, time_units, GTS_df=None, ranks=None, location='above', label_pref='full', allow_abbreviations=True, ax_name='gts', v_offset=0, height=.05, text_color=None, fontsize=None, edgecolor='k', - edgewidth=0, alpha=1,zorder=10,reverse_rank_order=True, + edgewidth=0, alpha=1,zorder=10,reverse_rank_order=True, lang='en', gts_url = "https://raw.githubusercontent.com/i-c-stratigraphy/chart/refs/heads/main/chart.ttl"): ''' @@ -1531,13 +1531,13 @@ def add_GTS(fig, ax, GTS_df=None, ranks=None, time_units='Ma',location='above', The figure object where the GTS will be added. ax : dict The axis where the GTS will be plotted. + time_units : str + Time units of the GTS data. Supported: 'Ma' (default), 'ka', 'Ga'. GTS_df : pd.DataFrame, optional DataFrame containing the GTS data with columns for 'Rank', 'Name', 'Abbrev', 'Color', 'UpperBoundary', 'LowerBoundary'. If None, the function will load the ICS chart from the provided URL. ranks : list of str, optional List of ranks to include (e.g., ['Period', 'Epoch', 'Stage']). If None, defaults to ['Period', 'Epoch', 'Stage']. Ranks are ordered from outer-most to inner-most. - time_units : str, optional - Time units of the GTS data. Supported: 'Ma' (default), 'ka', 'Ga'. location : str, optional Specifies whether to place the GTS above or below the plot. Default is 'above'. label_pref : str, optional @@ -1608,7 +1608,7 @@ def add_GTS(fig, ax, GTS_df=None, ranks=None, time_units='Ma',location='above', assert all(duration >= 0), "GTS_df 'LowerBoundary' must be greater than (further back in time) or equal to 'UpperBoundary (more modern)'" if GTS_df is None: - GTS_df = datasets.load_ics_chart_to_df(gts_url, time_units=time_units) + GTS_df = datasets.load_ics_chart_to_df(gts_url, time_units=time_units, lang=lang) if ranks is None: ranks = ['Period', 'Epoch', 'Stage']