tesorotools-python 0.0.30__tar.gz → 0.0.31__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/PKG-INFO +1 -1
  2. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/pyproject.toml +1 -1
  3. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/line_plot.py +14 -9
  4. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/stacked.py +4 -2
  5. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/pipeline/rules.py +16 -0
  6. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/.gitignore +0 -0
  7. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/__init__.py +0 -0
  8. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/__init__.py +0 -0
  9. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/barh.md +0 -0
  10. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/barh_plot.py +0 -0
  11. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/table.py +0 -0
  12. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/artists/type_curve.py +0 -0
  13. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/README.md +0 -0
  14. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
  15. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
  16. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
  17. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
  18. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
  19. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
  20. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
  21. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
  22. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/fonts/README.md +0 -0
  23. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/plots.yaml +0 -0
  24. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/assets/tesoro.mplstyle +0 -0
  25. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/convert.py +0 -0
  26. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/data_sources/README.md +0 -0
  27. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/data_sources/__init__.py +0 -0
  28. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/data_sources/debug.py +0 -0
  29. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/data_sources/lseg.py +0 -0
  30. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/database/__init__.py +0 -0
  31. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/database/local.py +0 -0
  32. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/database/push.py +0 -0
  33. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/dependencies/__init__.py +0 -0
  34. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/dependencies/node.py +0 -0
  35. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/dependencies/resolution.py +0 -0
  36. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/main.py +0 -0
  37. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/offsets/__init__.py +0 -0
  38. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/offsets/offsets.py +0 -0
  39. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/offsets/outliers.py +0 -0
  40. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/pipeline/__init__.py +0 -0
  41. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/pipeline/diagnose.py +0 -0
  42. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/pipeline/engine.py +0 -0
  43. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/providers/__init__.py +0 -0
  44. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/providers/base.py +0 -0
  45. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/providers/bde.py +0 -0
  46. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/providers/ecb.py +0 -0
  47. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/py.typed +0 -0
  48. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/__init__.py +0 -0
  49. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/__init__.py +0 -0
  50. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/content.py +0 -0
  51. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/images.py +0 -0
  52. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/section.py +0 -0
  53. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/subtitle.py +0 -0
  54. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/table.py +0 -0
  55. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/text.py +0 -0
  56. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/content/title.py +0 -0
  57. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/render/report.py +0 -0
  58. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/__init__.py +0 -0
  59. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/config.py +0 -0
  60. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/format.py +0 -0
  61. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/globals.py +0 -0
  62. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/matplotlib.py +0 -0
  63. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/series.py +0 -0
  64. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/shortcuts.py +0 -0
  65. {tesorotools_python-0.0.30 → tesorotools_python-0.0.31}/src/tesorotools/utils/template.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tesorotools-python
3
- Version: 0.0.30
3
+ Version: 0.0.31
4
4
  Requires-Python: >=3.13
5
5
  Requires-Dist: babel>=2.17
6
6
  Requires-Dist: eikon>=1.1
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "tesorotools-python"
3
3
  requires-python = ">=3.13"
4
- version = "0.0.30"
4
+ version = "0.0.31"
5
5
  dependencies = [
6
6
  # database and ORM
7
7
  "psycopg[binary]>=3.1",
@@ -102,11 +102,17 @@ def annotate_last_values(
102
102
  *,
103
103
  decimals: int,
104
104
  units: str,
105
+ labels: dict[str, str] | None = None,
105
106
  series_styles: dict[str, dict[str, Any]] | None = None,
106
107
  annotate_color: str | None = None,
107
108
  ) -> None:
108
109
  """Label the last non-NaN value of each column on the right.
109
110
 
111
+ ``plot_data.columns`` and ``series_styles`` keys must be
112
+ canonical series IDs. ``labels`` maps each ID to the
113
+ Matplotlib line label used when the axes were drawn; if
114
+ omitted, the ID itself is used as the line label.
115
+
110
116
  Colour priority (highest first): ``annotate_color``
111
117
  (global override), ``series_styles[col]['color']``,
112
118
  the Matplotlib line colour.
@@ -120,6 +126,7 @@ def annotate_last_values(
120
126
  if fig is None:
121
127
  return
122
128
  styles = series_styles or {}
129
+ label_map = labels or {}
123
130
 
124
131
  lines_by_label = {str(line.get_label()): line for line in ax.lines}
125
132
  entries: list[tuple[Any, float, str, Any]] = []
@@ -136,7 +143,7 @@ def annotate_last_values(
136
143
  if override is not None:
137
144
  color = override
138
145
  else:
139
- line = lines_by_label.get(col)
146
+ line = lines_by_label.get(label_map.get(col, col))
140
147
  color = line.get_color() if line is not None else "black"
141
148
  entries.append((last_date, last_val, col, color))
142
149
 
@@ -454,7 +461,6 @@ class LinePlot:
454
461
  plot_data: pd.DataFrame = self.data.loc[
455
462
  slice(start_date, end_date), self.series.keys()
456
463
  ]
457
- plot_data = plot_data.rename(columns=self.series)
458
464
 
459
465
  plot_data = plot_data * self.scale
460
466
 
@@ -468,12 +474,10 @@ class LinePlot:
468
474
  **fig_kw
469
475
  )
470
476
  ax = fig.add_subplot()
471
- if self.series_styles:
472
- for col in plot_data.columns:
473
- style = self.series_styles.get(col, {})
474
- plot_data[col].plot(ax=ax, label=col, **style)
475
- else:
476
- plot_data.plot(ax=ax)
477
+ styles = self.series_styles
478
+ for col in plot_data.columns:
479
+ style = styles.get(col, {}) if styles else {}
480
+ plot_data[col].plot(ax=ax, label=self.series[col], **style)
477
481
 
478
482
  assert self.format is not None
479
483
  if self.annotate:
@@ -482,6 +486,7 @@ class LinePlot:
482
486
  plot_data,
483
487
  decimals=self.format.decimals,
484
488
  units=self.format.units,
489
+ labels=self.series,
485
490
  series_styles=self.series_styles,
486
491
  annotate_color=self.annotate_color,
487
492
  )
@@ -497,7 +502,7 @@ class LinePlot:
497
502
  style_baseline(ax, reference, **AX_CONFIG["baseline"])
498
503
 
499
504
  if self.legend is not None:
500
- labels = list(plot_data.columns)
505
+ labels = [self.series[c] for c in plot_data.columns]
501
506
  ncol = (
502
507
  self.legend.ncol
503
508
  if self.legend.ncol is not None
@@ -84,7 +84,8 @@ class StackedAreaPlot:
84
84
  else self.data.index.max()
85
85
  )
86
86
 
87
- plot_data = self.data.loc[start:end, list(self.series.keys())].dropna()
87
+ plot_data = self.data.loc[start:end, list(self.series.keys())]
88
+ plot_data = plot_data.dropna(how="all").fillna(0)
88
89
  plot_data = plot_data * self.scale
89
90
 
90
91
  fig_kw = dict(FIG_CONFIG)
@@ -211,7 +212,8 @@ class StackedBarPlot:
211
212
  else self.data.index.max()
212
213
  )
213
214
  all_cols = list(self.series.keys()) + list(self.overlay_series.keys())
214
- plot_data = self.data.loc[start:end, all_cols].dropna()
215
+ plot_data = self.data.loc[start:end, all_cols]
216
+ plot_data = plot_data.dropna(how="all").fillna(0)
215
217
  return plot_data * self.scale
216
218
 
217
219
  def _format_xticks(
@@ -45,6 +45,21 @@ def sum_rule(output: str, sources: list[str]) -> TransformationRule:
45
45
  )
46
46
 
47
47
 
48
+ def mean_rule(output: str, sources: list[str]) -> TransformationRule:
49
+ """Row-wise arithmetic mean of multiple columns.
50
+
51
+ Equivalent to ``=AVERAGE(...)`` in Excel: NaN components
52
+ are skipped (not treated as zero), so a row with any
53
+ non-NaN value yields the mean of whatever is present.
54
+ A row of all NaN yields NaN.
55
+ """
56
+ return TransformationRule(
57
+ output_name=output,
58
+ dependencies=list(sources),
59
+ compute=lambda df, cols=list(sources): df[cols].mean(axis=1),
60
+ )
61
+
62
+
48
63
  def ratio_rule(
49
64
  output: str, numerator: str, denominator: str
50
65
  ) -> TransformationRule:
@@ -333,6 +348,7 @@ FACTORIES: dict[
333
348
  ] = {
334
349
  "scale": scale_rule,
335
350
  "sum": sum_rule,
351
+ "mean": mean_rule,
336
352
  "ratio": ratio_rule,
337
353
  "difference": difference_rule,
338
354
  "inverse": inverse_rule,