tesorotools-python 0.0.26__tar.gz → 0.0.27__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 (64) hide show
  1. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/PKG-INFO +1 -1
  2. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/pyproject.toml +1 -1
  3. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/stacked.py +48 -16
  4. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/.gitignore +0 -0
  5. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/__init__.py +0 -0
  6. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/__init__.py +0 -0
  7. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/barh.md +0 -0
  8. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/barh_plot.py +0 -0
  9. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/line_plot.py +0 -0
  10. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/table.py +0 -0
  11. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/artists/type_curve.py +0 -0
  12. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/README.md +0 -0
  13. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
  14. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
  15. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
  16. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
  17. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
  18. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
  19. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
  20. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
  21. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/fonts/README.md +0 -0
  22. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/plots.yaml +0 -0
  23. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/assets/tesoro.mplstyle +0 -0
  24. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/convert.py +0 -0
  25. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/data_sources/README.md +0 -0
  26. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/data_sources/__init__.py +0 -0
  27. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/data_sources/debug.py +0 -0
  28. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/data_sources/lseg.py +0 -0
  29. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/database/__init__.py +0 -0
  30. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/database/local.py +0 -0
  31. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/database/push.py +0 -0
  32. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/dependencies/__init__.py +0 -0
  33. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/dependencies/node.py +0 -0
  34. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/dependencies/resolution.py +0 -0
  35. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/main.py +0 -0
  36. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/offsets/__init__.py +0 -0
  37. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/offsets/offsets.py +0 -0
  38. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/offsets/outliers.py +0 -0
  39. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/pipeline/__init__.py +0 -0
  40. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/pipeline/diagnose.py +0 -0
  41. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/pipeline/engine.py +0 -0
  42. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/pipeline/rules.py +0 -0
  43. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/providers/__init__.py +0 -0
  44. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/providers/base.py +0 -0
  45. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/providers/bde.py +0 -0
  46. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/py.typed +0 -0
  47. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/__init__.py +0 -0
  48. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/__init__.py +0 -0
  49. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/content.py +0 -0
  50. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/images.py +0 -0
  51. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/section.py +0 -0
  52. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/subtitle.py +0 -0
  53. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/table.py +0 -0
  54. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/text.py +0 -0
  55. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/content/title.py +0 -0
  56. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/render/report.py +0 -0
  57. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/__init__.py +0 -0
  58. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/config.py +0 -0
  59. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/format.py +0 -0
  60. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/globals.py +0 -0
  61. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/matplotlib.py +0 -0
  62. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/series.py +0 -0
  63. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/src/tesorotools/utils/shortcuts.py +0 -0
  64. {tesorotools_python-0.0.26 → tesorotools_python-0.0.27}/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.26
3
+ Version: 0.0.27
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.26"
4
+ version = "0.0.27"
5
5
  dependencies = [
6
6
  # database and ORM
7
7
  "psycopg[binary]>=3.1",
@@ -139,6 +139,13 @@ class StackedBarPlot:
139
139
 
140
140
  Positive and negative values are stacked separately so
141
141
  that bars extend in both directions from the baseline.
142
+
143
+ The ``plot`` method delegates to overridable hooks so
144
+ subclasses can customise individual steps without
145
+ reimplementing the full render pipeline:
146
+
147
+ * ``_prepare_data`` — slice, scale, resample
148
+ * ``_format_xticks`` — tick positions, labels, rotation
142
149
  """
143
150
 
144
151
  def __init__(
@@ -156,6 +163,8 @@ class StackedBarPlot:
156
163
  figsize: tuple[float, float] | None = None,
157
164
  overlay_series: dict[str, str] | None = None,
158
165
  plot_size: tuple[float, float] | None = None,
166
+ bar_width: float = 0.7,
167
+ x_rotation: float = 0,
159
168
  ) -> None:
160
169
  if out_path.suffix != ".png":
161
170
  raise ValueError(f"out_path must be .png: {out_path}")
@@ -171,6 +180,8 @@ class StackedBarPlot:
171
180
  self.plot_size = plot_size
172
181
  self.figsize = figsize
173
182
  self.overlay_series = overlay_series or {}
183
+ self.bar_width = bar_width
184
+ self.x_rotation = x_rotation
174
185
 
175
186
  @classmethod
176
187
  def from_yaml(cls, loader: TemplateLoader, node: MappingNode) -> Self:
@@ -182,7 +193,13 @@ class StackedBarPlot:
182
193
  cfg["data"] = pd.read_feather(cfg.pop("data_path"))
183
194
  return cls(**cfg)
184
195
 
185
- def plot(self) -> Axes:
196
+ # -- Overridable hooks -----------------------------------
197
+
198
+ def _prepare_data(self) -> pd.DataFrame:
199
+ """Slice, scale, and return plot-ready DataFrame.
200
+
201
+ Override to resample, change the index type, etc.
202
+ """
186
203
  start = (
187
204
  pd.Timestamp(self.start_date)
188
205
  if self.start_date
@@ -193,10 +210,35 @@ class StackedBarPlot:
193
210
  if self.end_date
194
211
  else self.data.index.max()
195
212
  )
196
-
197
213
  all_cols = list(self.series.keys()) + list(self.overlay_series.keys())
198
214
  plot_data = self.data.loc[start:end, all_cols].dropna()
199
- plot_data = plot_data * self.scale
215
+ return plot_data * self.scale
216
+
217
+ def _format_xticks(
218
+ self,
219
+ ax: Axes,
220
+ plot_data: pd.DataFrame,
221
+ x: np.ndarray[tuple[int], np.dtype[np.intp]],
222
+ ) -> None:
223
+ """Set tick positions, labels, and rotation.
224
+
225
+ Override for custom labels (e.g. string index).
226
+ """
227
+ dates = plot_data.index
228
+ step = max(1, len(dates) // 12)
229
+ tick_pos = list(range(0, len(dates), step))
230
+ tick_labels = [dates[i].strftime("%Y") for i in tick_pos]
231
+ ax.set_xticks( # type: ignore[reportUnknownMemberType]
232
+ tick_pos
233
+ )
234
+ ax.set_xticklabels( # type: ignore[reportUnknownMemberType]
235
+ tick_labels, rotation=self.x_rotation
236
+ )
237
+
238
+ # -- Main render -----------------------------------------
239
+
240
+ def plot(self) -> Axes:
241
+ plot_data = self._prepare_data()
200
242
 
201
243
  fig_kw = dict(FIG_CONFIG)
202
244
  if self.figsize is not None:
@@ -210,7 +252,6 @@ class StackedBarPlot:
210
252
  labels = list(self.series.values())
211
253
 
212
254
  x = np.arange(len(plot_data))
213
- bar_width = 0.7
214
255
 
215
256
  pos_bottom: np.ndarray[tuple[int], np.dtype[np.float64]] = np.zeros(
216
257
  len(plot_data)
@@ -235,7 +276,7 @@ class StackedBarPlot:
235
276
  x,
236
277
  pos,
237
278
  bottom=pos_bottom,
238
- width=bar_width,
279
+ width=self.bar_width,
239
280
  label=label,
240
281
  )
241
282
  .patches[0]
@@ -245,7 +286,7 @@ class StackedBarPlot:
245
286
  x,
246
287
  neg,
247
288
  bottom=neg_bottom,
248
- width=bar_width,
289
+ width=self.bar_width,
249
290
  color=color,
250
291
  )
251
292
  pos_bottom = pos_bottom + pos
@@ -262,16 +303,7 @@ class StackedBarPlot:
262
303
  zorder=10,
263
304
  )
264
305
 
265
- dates = plot_data.index
266
- step = max(1, len(dates) // 12)
267
- tick_pos = list(range(0, len(dates), step))
268
- tick_labels = [dates[i].strftime("%Y") for i in tick_pos]
269
- ax.set_xticks( # type: ignore[reportUnknownMemberType]
270
- tick_pos
271
- )
272
- ax.set_xticklabels( # type: ignore[reportUnknownMemberType]
273
- tick_labels
274
- )
306
+ self._format_xticks(ax, plot_data, x)
275
307
 
276
308
  style_spines(
277
309
  ax,