tdfs4ds.plotting¶
tdfs4ds.plotting
¶
In-database plotting with TD_PLOT.
The chart is drawn inside Teradata by the UAF function TD_PLOT: the data
never leaves the database, only the image does (a PNG of some tens of kB, whatever
the number of points - 200,000 points were drawn in 0.5 s on Vantage 20).
How a plot is made (one session, nothing permanent is created):
- Count the points of the request (
SELECT COUNT(*)): an empty request is said so, and a request abovetdfs4ds.PLOT_MAX_POINTSis refused when that setting is a number (defaultNone: TD_PLOT draws any size, and a failure comes back as its whole message). - Stage them in a volatile table with three columns
x/y/id(id= the series).TABLE_NAME(...)of a UAF call cannot hold a sub-query, and a volatile table needs no CREATE right (teradataml's ownDataFrame.plotwrites a permanentml__view instead). - Keep the first
tdfs4ds.PLOT_MAX_SERIESseries (a legend of 300 entries is unreadable); the result says how many were left out. EXECUTE FUNCTION TD_PLOT(SERIES_SPEC(...), FUNC_PARAMS(...))returns one row whoseIMAGEcolumn holds the picture.- When the request is small (at most
tdfs4ds.PLOT_INTERACTIVE_MAX_POINTSpoints) the staged rows are also read back and drawn as an interactive Plotly chart. Above that, only the image exists: the data stays in the database. - The volatile tables are dropped.
Facts measured on Vantage 20 that shape the SQL below:
- the axis is
TIMECODEfor a date/timestamp column (cast toTIMESTAMP(0)) andSEQUENCEfor a number (a FLOAT axis is accepted); - dates are printed only with
XFORMAT('YYYY-MM-DD')- a%Y-%m-%dformat is Error 9153 "Invalid label format", and without a format the axis shows 1, 2, 3; TD_PLOTcannot label a categorical axis: a bar chart by category is drawn over positions 1..k with the names in the axis label (and on the interactive version), because one series per category makes the bars unreadable;IMAGE('png' | 'jpg' | 'svg'); a volatile table is a validTABLE_NAME.
Public functions: :func:plot_in_database (any table, view or query),
:func:plot_feature (a feature's stored values) and :func:plot_dataset (a
dataset view). Each returns a dict (see :func:plot_in_database);
:func:plot_features (several features, one panel each) and :func:plot_panels
(any panels in one image: one SERIES_SPEC per panel, LAYOUT(columns, rows),
CELL(column, row)). :func:plot_html turns a result into a small HTML page and
:func:show_plot displays it in a notebook.
SERIES_ORDERS
module-attribute
¶
LEGEND_LOCATIONS
module-attribute
¶
LEGEND_LOCATIONS = ('best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center')
_TWO_ROWS
module-attribute
¶
_TWO_ROWS = '(SELECT 1 AS k FROM (SELECT 1 AS d) a UNION ALL SELECT 2 AS k FROM (SELECT 1 AS d) b) stp'
_FOUR_ROWS
module-attribute
¶
_FOUR_ROWS = '(SELECT 1 AS k FROM (SELECT 1 AS d) a UNION ALL SELECT 2 AS k FROM (SELECT 1 AS d) b UNION ALL SELECT 3 AS k FROM (SELECT 1 AS d) c UNION ALL SELECT 4 AS k FROM (SELECT 1 AS d) e) p4'
_REBASE_WORDS
module-attribute
¶
_PAIR_TOKENS
module-attribute
¶
_VALID_END_OR_NOW
module-attribute
¶
_VALID_END_OR_NOW = "(CASE WHEN ValidEnd > CURRENT_TIMESTAMP(0) THEN CURRENT_TIMESTAMP(0) ELSE ValidEnd END) - INTERVAL '1' SECOND"
_LAYOUT_OVERRIDES
module-attribute
¶
quote_ident
¶
Return name as a Teradata identifier, quoting it only if required.
Idempotent: an already-quoted name is returned unchanged rather than being
wrapped a second time. Embedded quotes are escaped as "".
Parameters¶
name : str
The raw object/database name.
force : bool, default False
Quote even when the name does not need it. Use only at the few sites
that have always emitted unconditional quotes and whose exact output is
already baked into persisted DDL (see
feature_store/feature_query_retrieval.py) — elsewhere forcing would
change the SQL of existing stores for no reason.
qualified
¶
Build db.obj with each part quoted only as needed.
qualified('TDB', 'FS_X') == 'TDB.FS_X' (unchanged for ordinary names);
qualified('SVC@CORP', 'FS_X') == '"SVC@CORP".FS_X'. An empty/None
database yields the bare object name, so unqualified callers keep working.
force=True quotes both parts unconditionally — only for the sites that
have always emitted quotes and whose exact text is already persisted (dataset
view DDL, returned volatile-table names).
split_qualified
¶
Split db.obj into (database, object), both de-quoted.
Quote-aware, so a dot inside a quoted part does not split the name:
split_qualified('"DEINF.CARLOSN"."FS_X"') == ('DEINF.CARLOSN', 'FS_X').
The naive rsplit('.', 1) this replaces returns ('"DEINF.CARLOSN"',
'"FS_X"') only by luck and ('"DEINF', 'CARLOSN"."FS_X"') in the
split('.') variant.
An unqualified name returns ('', name).
sql_literal
¶
Escape value for use inside a single-quoted SQL string literal.
For the DBC probes and catalog predicates that compare a name as data
(WHERE DatabaseName = '…'). The caller supplies the surrounding quotes.
_max_points
¶
tdfs4ds.PLOT_MAX_POINTS, or None (the default): no limit before TD_PLOT.
legend_plan
¶
legend_plan(n_series: int, label_chars: int, *, numeric_x: bool, x_range=None, width: int = 900, height: int = 450, layout=(1, 1)) -> dict
Where the legend of a panel goes, and the image size it needs.
Up to tdfs4ds.PLOT_LEGEND_INLINE_MAX series: LEGEND('best'), nothing
changes. Above tdfs4ds.PLOT_LEGEND_MAX: no legend (it would be taller than
the chart and unreadable). In between, TD_PLOT cannot put the legend outside
the plot, so room is made inside it: the image grows taller until every entry
fits and, on a numeric x axis, the x range is extended on the right by the
legend's width, which then sits in empty space ('upper right'). A time
axis takes no XRANGE (Error 3706) and no empty point (NULL payload refused),
so there the legend stays 'best' in the taller image.
Returns {"legend": False | location, "width", "height", "xrange", "note"}.
_text
¶
A TD_PLOT string argument: quoted, apostrophes doubled, no line breaks, at
most TD_PLOT_TEXT_MAX characters (cut with "...").
td_plot_multi_sql
¶
td_plot_multi_sql(panels: list, *, layout=(1, 1), title=None, width: int = 900, height: int = 450, image: str = 'png', dpi: int = 100) -> str
One TD_PLOT over several staged tables, one panel each.
panels: dicts with table, axis, kind, title, xlabel,
ylabel, xformat, legend and cell = (column, row). One
SERIES_SPEC per panel, in order; the panel's ID(i) is its position.
layout is (columns, rows). Verified live: line and bar panels mix.
td_plot_sql
¶
td_plot_sql(table: str, *, axis: str = 'timecode', kind: str = 'line', title=None, xlabel=None, ylabel=None, xformat=None, legend: bool = True, width: int = 900, height: int = 450, image: str = 'png', dpi: int = 100) -> str
The EXECUTE FUNCTION TD_PLOT statement over one staged x/y/id table.
axis is 'timecode' (date/timestamp x) or 'sequence' (numeric x).
kind is a TD_PLOT type: line, scatter or bar (a histogram is a
bar chart over bin centres, see :func:histogram_staging_sql).
_source_clause
¶
FROM target: a query is wrapped as a derived table, a name is used as is.
A temporal qualifier does not belong in source (inside a derived table it is
refused): pass it as qualifier=; it then opens the whole statement and
applies to every temporal table the statement reads.
staging_sql
¶
staging_sql(name: str, source: str, x: str, y: str, series: Optional[str] = None, *, x_is_time: bool = True, where: Optional[str] = None, qualifier: Optional[str] = None, step_end: Optional[str] = None, clip=None, y_select: Optional[str] = None, x_known: bool = False) -> str
CREATE VOLATILE TABLE <name> with x / y / id from source.
x, y and series are SQL expressions over the source's columns (quote
identifiers with :func:tdfs4ds.utils.identifiers.quote_ident). Rows with a
NULL x or y are left out: a gap is not a point. y_select replaces y in
the SELECT only (a window function, such as :func:rebased, cannot be in
the WHERE). x_known: the source never gives a NULL x, so no test on it -
a test on an expression of a time column is pushed into the source and costs
a PTI its time-range read (measured: all-rows scan instead).
periods_staging_sql
¶
periods_staging_sql(name: str, source: str, start: str, end: Optional[str], series: Optional[str] = None, *, where: Optional[str] = None, qualifier: Optional[str] = None, clip=None) -> str
Periods drawn as pulses: y = 1 while a period holds, 0 outside.
Each row gives four points from a four-row cross join: (start, 0),
(start + 1 s, 1), (end - 1 s, 1), (end, 0). The one-second ramps are inside
the period, so two adjacent periods (one ends where the next starts) meet at
the same point at 0 - with ramps outside, their points had no order at one x
and the line went back and forth. A missing end, or an end after now (an
open period, UNTIL_CHANGED), is drawn up to now. clip (lo, hi) (SQL
literals) cuts the periods at the edges of a zoom window.
rebase_mode
¶
None (no index) or the reference of the index: 'first' (True),
'mean' or 'median' of each curve.
rebase_update_sql
¶
Statements turning the staged y of every curve (id) of table
into an index: 100 at the curve's mean or median, over everything staged
for it (the whole extracted series).
Run on the staging table, after it is filled. Teradata has MEDIAN as an
aggregate only, and not in a sub-query either (MEDIAN(...) OVER is Error
3707, MEDIAN in a derived table Error 3706, both measured), so the
reference of each curve is grouped once into its own volatile table
(<table>_ref, dropped by the last statement) and joined back. A curve
whose reference is 0 or NULL cannot be indexed and is removed (TD_PLOT
refuses a NULL value).
rebased
¶
y as an index: 100 at the series' first point (in the window drawn), or at its first point at or after from_x (0 = the start of an aligned period).
Series of different levels then start from the same origin and their moves compare directly. A first value of 0 gives no point.
histogram_staging_sql
¶
histogram_staging_sql(name: str, source: str, value: str, *, bins: int = 20, where: Optional[str] = None, qualifier: Optional[str] = None) -> str
A histogram of value: x = bin centre, y = number of rows in the bin.
Bins are equal-width between the minimum and the maximum (WIDTH_BUCKET);
the upper bound is nudged so the maximum falls in the last bin. A constant
column yields one bin.
category_staging_sql
¶
category_staging_sql(name: str, source: str, category: str, value: Optional[str], *, agg: str = 'avg', where: Optional[str] = None, qualifier: Optional[str] = None) -> str
One bar per category: x = position 1..k (alphabetical), y = the aggregate.
One series (id is constant: a series per category draws unreadable bars);
the category name is in lbl, which TD_PLOT does not read, for the axis
label and the interactive version.
count_sql
¶
count_sql(source: str, x: Optional[str], y: Optional[str], where: Optional[str] = None, qualifier: Optional[str] = None) -> str
The number of points a request would stage (before staging anything).
cap_series_sql
¶
Keep max_series series of a staged table, chosen by order.
alphabetical - the first names; largest / smallest - by the value at
the series' last x (the latest value of a history); most_points - the
series with the most points.
_plot_unavailable
¶
TD_PLOT (UAF) missing on this system: an unknown function, not a bad request.
_bound
¶
A SQL literal for one end of a window, or None.
Time: anything :func:tdfs4ds.serve.store_consistency.normalise_as_of
reads (no offset = UTC), plus YYYY-MM (the month's first day; as an upper
bound, the next month's first day, so "to 2023-06" includes June).
window_predicate
¶
Rows inside an x window (low, high); either end may be None.
A step (a value held over a period) is kept when its period overlaps the window, not only when it starts inside it.
panel
¶
panel(source: str, x: Optional[str] = None, y: Optional[str] = None, *, series: Optional[str] = None, kind: str = 'line', x_is_time: Optional[bool] = None, agg: str = 'avg', bins: int = 20, where: Optional[str] = None, qualifier: Optional[str] = None, title: Optional[str] = None, xlabel: Optional[str] = None, ylabel: Optional[str] = None, xformat: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, step_end: Optional[str] = None, xlim=None, ylim=None, rebase=False, rebase_from=None, x_known: bool = False) -> dict
One panel of a chart: what to read and how to draw it (validated, not run).
rebase: each series as an index, so curves of different levels are
superimposed. True / 'first': 100 at its first point in the window
(at or after rebase_from when given, :func:rebased); 'mean' /
'median': 100 at the mean / median of the whole curve drawn
(:func:rebase_update_sql).
xlim (low, high) zooms on the x axis: the rows are filtered to the
window in SQL (TD_PLOT refuses XRANGE on a time axis, Error 3706, and
filtering gives the database more points to draw in the window); on a
numeric axis XRANGE is set too. For a histogram the window is on the
values. ylim (low, high) sets YRANGE.
See :func:plot_in_database for the arguments; a list of panels is drawn by
:func:plot_panels.
default_layout
¶
(columns, rows) for n panels: stacked up to 3, then two columns.
_time_format
¶
(XFORMAT, xlabel) for a time axis, from the span of the staged rows.
TD_PLOT accepts YYYY-MM-DD, YYYY-MM, DD/MM/YYYY and HH:MI but
no date and time together (Error 9153, measured): within one day the ticks
are hours and the date goes in the axis label; over about 13 months, months.
_stage_panel
¶
Count, stage and cap one panel; returns its drawing parameters (or an error).
plot_panels
¶
plot_panels(panels: list, *, title: Optional[str] = None, layout=None, width: Optional[int] = None, height: Optional[int] = None, image: str = 'png', interactive='auto') -> dict
Draw several panels in one image, in the database (one TD_PLOT call).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
panels
|
list
|
:func: |
required |
title
|
Optional[str]
|
the title over all panels. |
None
|
layout
|
|
None
|
|
width, height
|
pixels; default from the layout. |
required | |
interactive
|
as for :func: |
'auto'
|
Returns the dict of :func:plot_in_database, plus panels (one entry per
panel: its title, points, series, staging SQL and error). A panel with nothing
to draw is left out and named in notes; the call fails only when no
panel is left.
_svg_copy
¶
The same chart as SVG (a vector image: sharp at any zoom), for a request of
at most tdfs4ds.PLOT_SVG_MAX_POINTS points - an SVG holds every point, so
a large one weighs megabytes. None when skipped or refused.
plot_in_database
¶
plot_in_database(source: str, x: Optional[str] = None, y: Optional[str] = None, *, series: Optional[str] = None, kind: str = 'line', x_is_time: Optional[bool] = None, agg: str = 'avg', bins: int = 20, where: Optional[str] = None, qualifier: Optional[str] = None, title: Optional[str] = None, xlabel: Optional[str] = None, ylabel: Optional[str] = None, xformat: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, xlim=None, ylim=None, width: int = 900, height: int = 450, image: str = 'png', interactive='auto') -> dict
Draw a chart in the database with TD_PLOT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
a qualified table or view name, or a SELECT (it becomes a derived table). A temporal qualifier goes in qualifier, never in the query. |
required |
x
|
Optional[str]
|
SQL expression of the x axis. |
None
|
y
|
Optional[str]
|
SQL expression of the value (for |
None
|
series
|
Optional[str]
|
SQL expression of the series (one line/colour each), or |
None
|
kind
|
str
|
|
'line'
|
x_is_time
|
Optional[bool]
|
|
None
|
agg
|
str
|
for a categorical |
'avg'
|
bins
|
int
|
for |
20
|
where
|
Optional[str]
|
an extra predicate on the source. |
None
|
qualifier
|
Optional[str]
|
a temporal qualifier opening every statement ( |
None
|
series_order
|
Optional[str]
|
which series are kept when there are more than
max_series: |
None
|
max_series
|
Optional[int]
|
how many series to draw (default |
None
|
xlim
|
zoom on x, |
None
|
|
ylim
|
|
None
|
|
interactive
|
|
'auto'
|
Returns:
| Type | Description |
|---|---|
dict
|
dict with |
dict
|
|
dict
|
|
dict
|
|
dict
|
database error; raises |
_plotlyjs_mode
¶
tdfs4ds.PLOT_PLOTLYJS: 'cdn' (default) or 'inline'.
Inline, plotly.js makes each page ~4.8 MB, and a chat answer travels in the
conversation memory: the interactive version loads it from its CDN instead.
Without network the TD_PLOT image is still there; 'inline' for offline use.
plot_html
¶
A self-contained HTML page: the TD_PLOT image, and the interactive version behind a toggle when there is one. No external request.
_toolbar
¶
Download PNG / SVG and an actual-size toggle. The chat frame is sandboxed
with allow-downloads; the files are built from the page itself.
save_plot
¶
Write a plot result to path: .png / .jpg (the TD_PLOT image),
.svg (the SVG copy, made for requests of at most
tdfs4ds.PLOT_SVG_MAX_POINTS points) or .html (the page shown in the
chat). Returns the path.
_inline_plotly
¶
The body of a Plotly page (its scripts included), to embed in another page.
chart_payload
¶
{"title", "html", "height"} for the chat (the shape MCP charts use).
show_plot
¶
Display a plot result in a notebook (the image, else the interactive chart).
column_types
¶
{column: type code} from HELP COLUMN (works for views, unlike DBC.ColumnsV).
values_filter
¶
A predicate keeping the rows whose entity matches one of values.
A value matches the whole key (a | b for a composite entity) or any one of
its columns - "Travel" selects every series of the Travel category.
_matching_values
¶
_matching_values(source: str, columns, candidates, *, where=None, qualifier=None, limit: int = 60, case_insensitive: bool = False) -> list
Which candidates are values of columns in source (one query per column).
case_insensitive: "nvda" finds the stored "NVDA", and the stored spelling is returned (the filter that follows compares exact values).
dataset_columns
¶
(entity columns, feature columns) of a registered dataset, from its catalog.
([], []) when the view is not registered or the catalog cannot be read: the
caller then falls back on the column types alone.
_ts0_text
¶
A timestamp of any precision as TIMESTAMP(0), through its text.
CAST(<TIMESTAMP(6)> AS TIMESTAMP(0)) is refused (Error 7454, precision
reduction, seen with DELTA_T periods); the text keeps the seconds. A value
with a time zone is read in UTC first.
period_bounds
¶
(start, end) SQL expressions (TIMESTAMP(0)) of a PERIOD column, or
None for a PERIOD of times of day (no date: not a time axis).
start_end_pairs
¶
[(start column, end column)]: two date/timestamp columns named as the
bounds of one period (X_START / X_END, ValidStart / ValidEnd,
BEGIN_X / END_X).
_periods_of
¶
The periods a table or view holds: PERIOD columns, then start/end pairs.
[{"label", "start", "end", "columns"}], start / end being SQL.
_end_or_now
¶
A period's end, or now when it is still open, one second early (see
_VALID_END_OR_NOW): the end of a step.
describe_dataset
¶
{database, view, columns: {name: type}, entity, features, periods} of a view or table.
periods lists its PERIOD columns and start/end column pairs (see
:func:start_end_pairs): a value over a period is drawn as a step, and the
periods themselves can be drawn (kind='periods').
_find_period
¶
The period a name designates: its label or its PERIOD column (not a start column alone: that one stays a plain time axis unless the default picks it).
dataset_entity_values
¶
The candidates that are entity values of the dataset (the agent passes the words of the question; only real values come back).
dataset_panels
¶
dataset_panels(dataset: str, y=None, *, x: Optional[str] = None, series=None, kind: Optional[str] = None, agg: str = 'avg', bins: int = 20, where: Optional[str] = None, entity_values=None, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, xlim=None, ylim=None)
The panels :func:plot_dataset draws, and a description of what they read.
_periods_panels
¶
One kind='periods' panel over a view's period (see :func:dataset_panels).
plot_dataset
¶
plot_dataset(dataset: str, y=None, *, x: Optional[str] = None, series=None, kind: Optional[str] = None, agg: str = 'avg', bins: int = 20, where: Optional[str] = None, entity_values=None, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, layout=None, xlim=None, ylim=None, **kwargs) -> dict
Plot columns of a dataset view in the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
str
|
|
required |
y
|
the value column (a feature), or a list of columns: one panel each (same x, series and kind). Default: the first numeric feature of the dataset (from its catalog), else the first numeric non-entity column. |
None
|
|
x
|
Optional[str]
|
the x column. Default: the first date/timestamp column ( |
None
|
series
|
a column or a list of columns (one line each). Default: the dataset's entity columns that are not dates (else its text columns). |
None
|
|
kind
|
Optional[str]
|
|
None
|
entity_values
|
keep only these entity values (a value matches the whole key or any one of its columns). |
None
|
|
series_order, max_series
|
which series are drawn (see :func: |
required | |
layout
|
|
None
|
|
xlim, ylim
|
zoom, see :func: |
required |
_feature_rows
¶
Current feature-catalog rows for a name (all domains unless one is given).
resolve_feature
¶
The one feature a name designates, or ValueError naming the candidates.
_feature_storage
¶
(table, entity columns, column types, feature id, version, notes).
feature_entity_values
¶
The candidates that are entity values of the feature's stored rows.
feature_panel
¶
feature_panel(feature: str, *, kind: str = 'distribution', entity=None, data_domain=None, entity_values=None, process_id: Optional[str] = None, as_of=None, bins: int = 20, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, xlim=None, ylim=None)
The panel :func:plot_feature draws, and a description of what it reads.
_history_version_notes
¶
A note when the stored history was computed by several process versions (the SQL beneath the process changed, 0.3.3.12). Fail-open: [] otherwise.
plot_feature
¶
plot_feature(feature: str, *, kind: str = 'distribution', entity=None, data_domain=None, entity_values=None, process_id: Optional[str] = None, as_of=None, bins: int = 20, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, xlim=None, ylim=None, **kwargs) -> dict
Plot a feature's stored values in the database (its FS_T_* storage table).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature
|
str
|
the feature name (with |
required |
kind
|
str
|
|
'distribution'
|
entity_values
|
keep only these entity values (a value matches the whole key or any one of its columns). |
None
|
|
series_order, max_series
|
which entity values a history shows when there
are more than max_series (default: the 12 with the largest latest
value; |
required | |
process_id
|
Optional[str]
|
the producing process ( |
None
|
as_of
|
valid time for |
None
|
|
xlim, ylim
|
zoom (a time window for a history, a value range for a
distribution), see :func: |
required |
plot_features
¶
plot_features(features, *, kind: str = 'distribution', entity=None, data_domain=None, entity_values=None, as_of=None, bins: int = 20, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, layout=None, xlim=None, ylim=None, **kwargs) -> dict
Several features in one image, one panel each (each keeps its own scale).
features is a list of names, or of dicts with feature and any argument of
:func:plot_feature (kind, entity, data_domain, entity_values,
process_id) to vary per panel. The other arguments apply to every panel.
A feature that cannot be drawn is left out and named in notes.
using_layout
¶
Draw table with layout inside the with block, whatever its
DEEP_LAYOUT section says (or when it has none).
historian_layout
¶
(database, table, layout) of a historian (deep) table, from its
documented DEEP_LAYOUT (see tdfs4ds.set_deep_table_documentation),
or from :func:using_layout.
The layout names the id columns, the tag column (which signal a row holds), the payload column (its value) and the timestamp column.
historian_tags
¶
The tags a historian table holds (distinct values of its tag column).
historian_panels
¶
historian_panels(table: str, tags, *, id_values=None, xlim=None, ylim=None, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, rebase=False)
The panels :func:plot_historian draws, and a description of what they read.
One panel per tag (tags carry different units): x = the timestamp column,
y = the payload, one line per id (the id columns), rows of that tag only.
Tags and id values are matched case-insensitively against the table; an
unknown one is a ValueError naming what exists.
plot_historian
¶
plot_historian(table: str, tags, *, id_values=None, xlim=None, ylim=None, title: Optional[str] = None, series_order: Optional[str] = None, max_series: Optional[int] = None, extra_panels=None, layout=None, rebase=False, **kwargs) -> dict
Plot tags of a historian (deep) table as time series, in the database.
A historian table holds one row per (ids, timestamp, tag) with the value in a payload column; its documented layout says which column is which. Each tag is drawn in its own panel, one line per id value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
str
|
|
required |
tags
|
a tag or a list of tags ( |
required | |
id_values
|
keep these ids ( |
None
|
|
xlim
|
a time window |
None
|
|
extra_panels
|
more :func: |
None
|
|
rebase
|
superimpose the series: each one as an index, 100 at its first
point in the window ( |
False
|
|
series_order, max_series, ylim, layout
|
see :func: |
required |
_counterpart
¶
The other bound of a start/end name (last_stress_start <->
last_stress_end), or None.
feature_bounds
¶
(start feature row, end feature row or None) for a period feature or
either bound of a start/end pair of time features; ValueError otherwise.
feature_window
¶
feature_window(feature: str, entity_values=None, *, entity=None, data_domain=None, as_of=None) -> dict
The time window a feature's stored period gives, for one entity value.
feature is a PERIOD feature, or either bound of a pair of date/timestamp
features (last_stress_start / last_stress_end: either name works). The
value is read at the current valid time, or at as_of. A missing end means
the period is still open (up to now).
Returns {"xlim": (start, end or None), "entity_value", "features",
"as_of"}; ValueError when the feature holds a value for several entity
values and none was named; LookupError when nothing is stored.
feature_periods_panel
¶
feature_periods_panel(feature: str, entity_values=None, *, entity=None, data_domain=None, xlim=None, title: Optional[str] = None, max_series: Optional[int] = None) -> tuple
Every period a feature has held over its history, drawn as pulses.
A feature that holds a period (last_stress_start / last_stress_end,
or a PERIOD feature) changes as its process runs over business dates: its
history keeps each distinct period (every stress episode). Returns
(panel, source); draw it with :func:plot_panels or as an
extra_panels of :func:plot_historian.
_feature_periods_inner
¶
(sql, entity key columns, matched entity values, start row, end row):
every distinct period a feature has held (p_start / p_end, with the
entity key), read NONSEQUENCED VALIDTIME. The SQL is meant to sit inside
a derived table.
feature_periods
¶
[(start, end)] (text, oldest first): the distinct periods of
:func:_feature_periods_inner, an open end read as now. One small read, so
the series query can carry each period as literals.
aligned_source_sql
¶
aligned_source_sql(source: str, layout: dict, tag: str, periods, *, margin_days: int = 0, id_values=None) -> str
The rows of one tag, around each period, with the days from its start.
One UNION ALL branch per period, each with literal time bounds: a
historian table is often a PTI or partitioned on time, and it reads a time
range only for literal bounds (bounds from a join or a sub-query read the
whole table - measured). The tag and ids are compared without TRIM so
their predicates stay usable by an index. A row near two periods belongs to
both curves.
aligned_periods_panels
¶
aligned_periods_panels(table: str, tags, period_feature: str, *, period_values=None, id_values=None, margin_days: int = 0, rebase=True, title: Optional[str] = None, max_series: Optional[int] = None, per_id: bool = False)
The panels :func:plot_aligned_periods draws, and what they read.
plot_aligned_periods
¶
plot_aligned_periods(table: str, tags, period_feature: str, *, period_values=None, id_values=None, margin_days: int = 0, rebase=True, title: Optional[str] = None, max_series: Optional[int] = None, per_id: bool = False, layout=None, **kwargs) -> dict
Superimpose the periods a feature has held, on a historian series.
Each period (every distinct one in the feature's history, e.g. every stress
episode) becomes one curve; the x axis is the number of days from the
period's start, so periods months apart overlay; with rebase (default)
the values are an index, 100 at the start. Every id and every period share
ONE chart per tag (a curve = an id and a period); per_id=True draws one
panel per id instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
str
|
the historian table (its documented layout gives the columns). |
required |
tags
|
the tag(s) drawn. |
required | |
period_feature
|
str
|
a PERIOD feature or either bound of a start / end pair. |
required |
period_values
|
the feature's entity values whose periods are used. |
None
|
|
id_values
|
the historian ids drawn (default: all). |
None
|
|
margin_days
|
int
|
days kept before the start and after the end of each period. |
0
|
rebase
|
values as an index: |
True
|
|
per_id
|
bool
|
one panel per id value instead of one chart holding them all. |
False
|
correlation_staging_sql
¶
correlation_staging_sql(name: str, source: str, columns: list, *, where: Optional[str] = None) -> tuple
Two statements: every CORR(a, b) in ONE pass over source (a one-row
table), then the k x k matrix x / y / v built from that row.
NULL correlations (a constant column) are left out.
td_plot_mesh_sql
¶
td_plot_mesh_sql(table: str, *, title=None, xlabel=None, ylabel=None, width: int = 760, height: int = 640, image: str = 'png', vmin: float = -1.0, vmax: float = 1.0, cmap: str = 'RdBu') -> str
TD_PLOT of a matrix (MATRIX_SPEC) as a mesh heatmap with a colour bar.
plot_correlation
¶
plot_correlation(dataset: str, columns=None, *, where: Optional[str] = None, title: Optional[str] = None, image: str = 'png', interactive='auto', width: int = 760, height: int = 640) -> dict
The correlation matrix of a dataset's numeric columns, drawn in the database.
Every Pearson correlation is computed in ONE pass (CORR) and the matrix is
drawn by TD_PLOT as a heatmap (mesh, colour bar from -1 to 1). The
matrix itself (k x k aggregates, not rows) is returned in matrix and drawn
interactively with the column names on both axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
str
|
|
required |
columns
|
the columns (at least 2, at most |
None
|
|
where
|
Optional[str]
|
a predicate on the rows used. |
None
|