tesorotools-python 0.0.28__tar.gz → 0.0.29__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.
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/PKG-INFO +1 -1
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/pyproject.toml +1 -1
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/line_plot.py +107 -4
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/.gitignore +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/barh.md +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/barh_plot.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/stacked.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/table.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/type_curve.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/README.md +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/README.md +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/plots.yaml +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/tesoro.mplstyle +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/convert.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/README.md +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/debug.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/lseg.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/database/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/database/local.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/database/push.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/node.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/resolution.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/main.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/offsets/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/offsets/offsets.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/offsets/outliers.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/diagnose.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/engine.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/rules.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/providers/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/providers/base.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/providers/bde.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/py.typed +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/content.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/images.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/section.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/subtitle.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/table.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/text.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/title.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/report.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/__init__.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/config.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/format.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/globals.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/matplotlib.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/series.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/shortcuts.py +0 -0
- {tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/utils/template.py +0 -0
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/line_plot.py
RENAMED
|
@@ -96,6 +96,100 @@ def auto_ncol(ax: Axes, labels: list[str]) -> int:
|
|
|
96
96
|
return min(ncol, len(labels))
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
def annotate_last_values(
|
|
100
|
+
ax: Axes,
|
|
101
|
+
plot_data: pd.DataFrame,
|
|
102
|
+
*,
|
|
103
|
+
decimals: int,
|
|
104
|
+
units: str,
|
|
105
|
+
series_styles: dict[str, dict[str, Any]] | None = None,
|
|
106
|
+
annotate_color: str | None = None,
|
|
107
|
+
) -> None:
|
|
108
|
+
"""Label the last non-NaN value of each column on the right.
|
|
109
|
+
|
|
110
|
+
Colour priority (highest first): ``annotate_color``
|
|
111
|
+
(global override), ``series_styles[col]['color']``,
|
|
112
|
+
the Matplotlib line colour.
|
|
113
|
+
|
|
114
|
+
Labels are packed vertically in display space so that
|
|
115
|
+
series ending at nearly the same value do not overlap.
|
|
116
|
+
The x-axis limit is extended by the widest label so
|
|
117
|
+
the text is not clipped by the axes frame.
|
|
118
|
+
"""
|
|
119
|
+
fig = ax.get_figure()
|
|
120
|
+
if fig is None:
|
|
121
|
+
return
|
|
122
|
+
styles = series_styles or {}
|
|
123
|
+
|
|
124
|
+
lines_by_label = {str(line.get_label()): line for line in ax.lines}
|
|
125
|
+
entries: list[tuple[Any, float, str, Any]] = []
|
|
126
|
+
for col in plot_data.columns:
|
|
127
|
+
col_series: pd.Series[float] = plot_data[col].dropna()
|
|
128
|
+
if col_series.empty:
|
|
129
|
+
continue
|
|
130
|
+
last_date = col_series.index[-1]
|
|
131
|
+
last_val = float(col_series.iloc[-1])
|
|
132
|
+
if annotate_color is not None:
|
|
133
|
+
color: Any = annotate_color
|
|
134
|
+
else:
|
|
135
|
+
override = styles.get(col, {}).get("color")
|
|
136
|
+
if override is not None:
|
|
137
|
+
color = override
|
|
138
|
+
else:
|
|
139
|
+
line = lines_by_label.get(col)
|
|
140
|
+
color = line.get_color() if line is not None else "black"
|
|
141
|
+
entries.append((last_date, last_val, col, color))
|
|
142
|
+
|
|
143
|
+
if not entries:
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
fig.canvas.draw() # type: ignore[reportUnknownMemberType]
|
|
147
|
+
renderer = fig.canvas.get_renderer() # type: ignore[reportUnknownMemberType]
|
|
148
|
+
trans = ax.transData
|
|
149
|
+
|
|
150
|
+
sample = ax.text( # type: ignore[reportUnknownMemberType]
|
|
151
|
+
0, 0, "0"
|
|
152
|
+
)
|
|
153
|
+
text_height = (
|
|
154
|
+
sample.get_window_extent(renderer).height # type: ignore[reportUnknownArgumentType]
|
|
155
|
+
* 1.15
|
|
156
|
+
)
|
|
157
|
+
sample.remove()
|
|
158
|
+
|
|
159
|
+
entries.sort(key=lambda e: e[1])
|
|
160
|
+
placements: list[float] = []
|
|
161
|
+
prev_y = -float("inf")
|
|
162
|
+
for _, val, _, _ in entries:
|
|
163
|
+
y_display: float = trans.transform((0, val))[1] # type: ignore[reportUnknownArgumentType]
|
|
164
|
+
if y_display - prev_y < text_height:
|
|
165
|
+
y_display = prev_y + text_height
|
|
166
|
+
placements.append(y_display)
|
|
167
|
+
prev_y = y_display
|
|
168
|
+
|
|
169
|
+
max_label_width = 0.0
|
|
170
|
+
for (date, val, _, color), packed_y in zip(entries, placements):
|
|
171
|
+
orig_y: float = trans.transform((0, val))[1] # type: ignore[reportUnknownArgumentType]
|
|
172
|
+
dy_pts = (packed_y - orig_y) * 72.0 / fig.dpi
|
|
173
|
+
text = format_annotation(val, decimals, units)
|
|
174
|
+
t = ax.annotate( # type: ignore[reportUnknownMemberType]
|
|
175
|
+
text,
|
|
176
|
+
xy=(date, val),
|
|
177
|
+
xytext=(5, dy_pts),
|
|
178
|
+
textcoords="offset points",
|
|
179
|
+
color=color,
|
|
180
|
+
va="center",
|
|
181
|
+
ha="left",
|
|
182
|
+
)
|
|
183
|
+
width = t.get_window_extent(renderer).width # type: ignore[reportUnknownArgumentType]
|
|
184
|
+
max_label_width = max(max_label_width, width)
|
|
185
|
+
|
|
186
|
+
inv = trans.inverted()
|
|
187
|
+
x0: float = inv.transform((0, 0))[0] # type: ignore[reportUnknownArgumentType]
|
|
188
|
+
x1: float = inv.transform((max_label_width + 10, 0))[0] # type: ignore[reportUnknownArgumentType]
|
|
189
|
+
xmin, xmax = ax.get_xlim()
|
|
190
|
+
ax.set_xlim(xmin, xmax + (x1 - x0))
|
|
191
|
+
|
|
192
|
+
|
|
99
193
|
def style_spines(
|
|
100
194
|
ax: Axes,
|
|
101
195
|
decimals: int,
|
|
@@ -290,6 +384,7 @@ class LinePlot:
|
|
|
290
384
|
end_date: datetime.datetime | None = None,
|
|
291
385
|
base_100: bool = False,
|
|
292
386
|
annotate: bool = False,
|
|
387
|
+
annotate_color: str | None = None,
|
|
293
388
|
baseline: bool = False,
|
|
294
389
|
format: Format | None = None,
|
|
295
390
|
legend: Legend | None = None,
|
|
@@ -320,7 +415,8 @@ class LinePlot:
|
|
|
320
415
|
raise ValueError("series is required")
|
|
321
416
|
|
|
322
417
|
self.base_100 = base_100
|
|
323
|
-
self.annotate = annotate
|
|
418
|
+
self.annotate = annotate
|
|
419
|
+
self.annotate_color = annotate_color
|
|
324
420
|
self.format = format
|
|
325
421
|
self.start_date = start_date
|
|
326
422
|
self.end_date = end_date
|
|
@@ -379,10 +475,17 @@ class LinePlot:
|
|
|
379
475
|
else:
|
|
380
476
|
plot_data.plot(ax=ax)
|
|
381
477
|
|
|
382
|
-
if self.annotate: # not implemented yet
|
|
383
|
-
pass
|
|
384
|
-
|
|
385
478
|
assert self.format is not None
|
|
479
|
+
if self.annotate:
|
|
480
|
+
annotate_last_values(
|
|
481
|
+
ax,
|
|
482
|
+
plot_data,
|
|
483
|
+
decimals=self.format.decimals,
|
|
484
|
+
units=self.format.units,
|
|
485
|
+
series_styles=self.series_styles,
|
|
486
|
+
annotate_color=self.annotate_color,
|
|
487
|
+
)
|
|
488
|
+
|
|
386
489
|
style_spines( # maybe make this function accept a Format object
|
|
387
490
|
ax,
|
|
388
491
|
decimals=self.format.decimals,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/barh_plot.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/artists/type_curve.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/fonts/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/assets/tesoro.mplstyle
RENAMED
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/README.md
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/debug.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/data_sources/lseg.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/database/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/node.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/dependencies/resolution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/pipeline/diagnose.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/providers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/content.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/images.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/section.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/subtitle.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/table.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/text.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.28 → tesorotools_python-0.0.29}/src/tesorotools/render/content/title.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|