wizata-dsapi 2.0.0.dev27__tar.gz → 2.0.0.dev29__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.
- {wizata_dsapi-2.0.0.dev27/wizata_dsapi.egg-info → wizata_dsapi-2.0.0.dev29}/PKG-INFO +1 -1
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/plots/__init__.py +1 -1
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/plots/common.py +207 -32
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/plots/theme.py +10 -0
- wizata_dsapi-2.0.0.dev29/wizata_dsapi/version.py +1 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29/wizata_dsapi.egg-info}/PKG-INFO +1 -1
- wizata_dsapi-2.0.0.dev27/wizata_dsapi/version.py +0 -1
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/LICENSE.txt +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/README.rst +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/setup.cfg +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/setup.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/__init__.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/api_config.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/api_dto.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/api_interface.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/bucket.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/business_label.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/context.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/dashboard.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/dataframe_toolkit.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/datapoint.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/datastore.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/ds_dataframe.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/dsapi_json_encoder.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/edge_config.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/edge_device.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/edge_module.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/evaluation.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/execution.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/execution_log.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/experiment.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/graylog_log.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/group_system.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/ilogger.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/insight.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/mlmodel.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/mobile_asset.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/model_toolkit.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/models/__init__.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/models/common.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/notification.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/paged_query_result.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/pipeline.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/pipeline_image.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/plot.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/request.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/script.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/scripts/__init__.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/scripts/common.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/search.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/solution_component.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/streamlit_utils.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/template.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/template_config.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/trigger.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/twin.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/twinregistration.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/user.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/wizard_function.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/wizard_request.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/wizata_dsapi_client.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi/words.py +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi.egg-info/requires.txt +0 -0
- {wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi.egg-info/top_level.txt +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .common import ts_chart, confusion_matrix, r_squared, anomalies_chart, parallel_coordinates, data_table, setpoint_recommendation, feature_importance
|
|
1
|
+
from .common import ts_chart, confusion_matrix, r_squared, anomalies_chart, parallel_coordinates, data_table, setpoint_recommendation, feature_importance, process_variability
|
|
2
2
|
from . import theme
|
|
@@ -6,13 +6,60 @@ import plotly.graph_objects as go
|
|
|
6
6
|
import plotly.express as px
|
|
7
7
|
import sklearn.metrics
|
|
8
8
|
|
|
9
|
+
from plotly.subplots import make_subplots
|
|
10
|
+
|
|
9
11
|
from .theme import (
|
|
10
|
-
apply_theme, SERIES_COLORS, ANOMALY_COLOR,
|
|
12
|
+
apply_theme, SERIES_COLORS, ANOMALY_COLOR, MAIN_COLOR, POSITIVE_COLOR,
|
|
13
|
+
TEXT_MUTED, WHITE,
|
|
11
14
|
TABLE_HEADER_BG, TABLE_HEADER_TEXT, TABLE_CELL_BG, TABLE_CELL_TEXT,
|
|
12
15
|
TABLE_LINE_COLOR, FONT_FAMILY, FONT_SIZE,
|
|
16
|
+
COLUMN_TYPE_TELEMETRY, COLUMN_TYPE_SETPOINT, COLUMN_TYPE_RECOMMENDATION,
|
|
17
|
+
COLUMN_TYPE_TARGET, COLUMN_TYPE_CALCULATED, COLUMN_TYPES_ORDER,
|
|
13
18
|
)
|
|
14
19
|
|
|
15
20
|
|
|
21
|
+
def _classify_columns(df, context):
|
|
22
|
+
"""Classify each dataframe column by its role in the pipeline.
|
|
23
|
+
|
|
24
|
+
Returns a dict of {col_name: {"type": str, "tag": str, "label": str, "color": str}}.
|
|
25
|
+
Type ordering: telemetry < setpoint < recommendation < calculated < target.
|
|
26
|
+
"""
|
|
27
|
+
datapoints = context.datapoints or {}
|
|
28
|
+
target = context.properties.get("target_feat") if context.properties else None
|
|
29
|
+
|
|
30
|
+
# Also check models for target_feat if not in properties
|
|
31
|
+
if target is None and hasattr(context, "models") and context.models:
|
|
32
|
+
for model in context.models.values():
|
|
33
|
+
if hasattr(model, "has_target_feat") and model.has_target_feat:
|
|
34
|
+
target_candidates = getattr(model, "target_feat", None)
|
|
35
|
+
if target_candidates:
|
|
36
|
+
target = target_candidates if isinstance(target_candidates, str) else target_candidates[0]
|
|
37
|
+
break
|
|
38
|
+
|
|
39
|
+
classification = {}
|
|
40
|
+
for col in df.select_dtypes(include="number").columns:
|
|
41
|
+
if col == target:
|
|
42
|
+
classification[col] = {**COLUMN_TYPE_TARGET, "type": "target"}
|
|
43
|
+
elif isinstance(col, str) and col.endswith("_recommended"):
|
|
44
|
+
classification[col] = {**COLUMN_TYPE_RECOMMENDATION, "type": "recommendation"}
|
|
45
|
+
elif col in datapoints:
|
|
46
|
+
dp = datapoints[col]
|
|
47
|
+
if dp.business_type == wizata_dsapi.BusinessType.SET_POINTS:
|
|
48
|
+
classification[col] = {**COLUMN_TYPE_SETPOINT, "type": "setpoint"}
|
|
49
|
+
else:
|
|
50
|
+
classification[col] = {**COLUMN_TYPE_TELEMETRY, "type": "telemetry"}
|
|
51
|
+
else:
|
|
52
|
+
classification[col] = {**COLUMN_TYPE_CALCULATED, "type": "calculated"}
|
|
53
|
+
|
|
54
|
+
return classification
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _sort_columns_by_type(columns, classification):
|
|
58
|
+
"""Sort columns following COLUMN_TYPES_ORDER: telemetry, setpoint, recommendation, calculated, target."""
|
|
59
|
+
order_map = {t: i for i, t in enumerate(COLUMN_TYPES_ORDER)}
|
|
60
|
+
return sorted(columns, key=lambda c: order_map.get(classification.get(c, {}).get("type", "calculated"), 3))
|
|
61
|
+
|
|
62
|
+
|
|
16
63
|
def check_single_column_and_target_feat(context: wizata_dsapi.Context):
|
|
17
64
|
"""
|
|
18
65
|
check_single_column_and_target_feat
|
|
@@ -221,14 +268,12 @@ def parallel_coordinates(context: wizata_dsapi.Context):
|
|
|
221
268
|
|
|
222
269
|
|
|
223
270
|
def setpoint_recommendation(context: wizata_dsapi.Context):
|
|
224
|
-
"""Compare current vs recommended setpoint values as a
|
|
225
|
-
|
|
226
|
-
Auto-pairs columns: for every column ending in '_recommended', looks for a matching column
|
|
227
|
-
with the same name minus the suffix. Validates that the base column corresponds to a datapoint
|
|
228
|
-
with BusinessType.SET_POINTS via context.datapoints (defense against accidental pairings).
|
|
229
|
-
Uses the **last row** of the dataframe for current and recommended values (most recent state).
|
|
271
|
+
"""Compare current vs recommended setpoint values as a grouped bar chart with a summary table.
|
|
230
272
|
|
|
231
|
-
|
|
273
|
+
Auto-pairs columns ending in '_recommended' with the matching setpoint column, validated via
|
|
274
|
+
context.datapoints BusinessType.SET_POINTS. Uses the last row (most recent state). The top half
|
|
275
|
+
shows a horizontal grouped bar chart (Current vs Recommended) with type-colored labels; the
|
|
276
|
+
bottom half is a summary table with Setpoint | Current | Recommended | delta | delta (%).
|
|
232
277
|
"""
|
|
233
278
|
df = context.dataframe
|
|
234
279
|
datapoints = context.datapoints or {}
|
|
@@ -244,8 +289,6 @@ def setpoint_recommendation(context: wizata_dsapi.Context):
|
|
|
244
289
|
base = col[: -len(suffix)]
|
|
245
290
|
if base not in df.columns:
|
|
246
291
|
continue
|
|
247
|
-
# Safety check: only pair if the base column is a declared setpoint datapoint.
|
|
248
|
-
# If datapoints are not populated (e.g. local test), fall back to pairing by name.
|
|
249
292
|
if datapoints:
|
|
250
293
|
dp = datapoints.get(base)
|
|
251
294
|
if dp is None or dp.business_type != wizata_dsapi.BusinessType.SET_POINTS:
|
|
@@ -258,32 +301,64 @@ def setpoint_recommendation(context: wizata_dsapi.Context):
|
|
|
258
301
|
)
|
|
259
302
|
|
|
260
303
|
last = df.iloc[-1]
|
|
261
|
-
|
|
304
|
+
names, currents, recommendeds, deltas, pcts = [], [], [], [], []
|
|
262
305
|
for base, rec in pairs:
|
|
263
|
-
current = last[base]
|
|
264
|
-
recommended = last[rec]
|
|
306
|
+
current = float(last[base])
|
|
307
|
+
recommended = float(last[rec])
|
|
265
308
|
delta = recommended - current
|
|
266
309
|
pct = (delta / current * 100.0) if current not in (0, 0.0) and not pd.isna(current) else float("nan")
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
310
|
+
names.append(base)
|
|
311
|
+
currents.append(current)
|
|
312
|
+
recommendeds.append(recommended)
|
|
313
|
+
deltas.append(delta)
|
|
314
|
+
pcts.append(pct)
|
|
315
|
+
|
|
316
|
+
# ── Build combined figure: bar chart (top) + table (bottom) ──────────
|
|
317
|
+
fig = make_subplots(
|
|
318
|
+
rows=2, cols=1,
|
|
319
|
+
specs=[[{"type": "xy"}], [{"type": "domain"}]],
|
|
320
|
+
row_heights=[0.55, 0.45],
|
|
321
|
+
vertical_spacing=0.08,
|
|
322
|
+
)
|
|
280
323
|
|
|
281
|
-
|
|
324
|
+
# Grouped horizontal bars
|
|
325
|
+
fig.add_trace(go.Bar(
|
|
326
|
+
y=names,
|
|
327
|
+
x=recommendeds,
|
|
328
|
+
orientation="h",
|
|
329
|
+
name="Recommended Value",
|
|
330
|
+
marker_color=POSITIVE_COLOR,
|
|
331
|
+
text=[f"{v:.2f}" for v in recommendeds],
|
|
332
|
+
textposition="inside",
|
|
333
|
+
insidetextanchor="start",
|
|
334
|
+
textfont=dict(color=WHITE, size=FONT_SIZE),
|
|
335
|
+
), row=1, col=1)
|
|
336
|
+
|
|
337
|
+
fig.add_trace(go.Bar(
|
|
338
|
+
y=names,
|
|
339
|
+
x=currents,
|
|
340
|
+
orientation="h",
|
|
341
|
+
name="Current Value",
|
|
342
|
+
marker_color=MAIN_COLOR,
|
|
343
|
+
text=[f"{v:.2f}" for v in currents],
|
|
344
|
+
textposition="inside",
|
|
345
|
+
insidetextanchor="start",
|
|
346
|
+
textfont=dict(color=WHITE, size=FONT_SIZE),
|
|
347
|
+
), row=1, col=1)
|
|
348
|
+
|
|
349
|
+
fig.update_layout(barmode="group")
|
|
350
|
+
fig.update_xaxes(title_text="Values", row=1, col=1)
|
|
351
|
+
fig.update_yaxes(title_text="Setpoints", row=1, col=1)
|
|
352
|
+
|
|
353
|
+
# Summary table
|
|
354
|
+
fmt = lambda v: "—" if pd.isna(v) else f"{v:.3f}"
|
|
355
|
+
n_rows = len(names)
|
|
282
356
|
cell_bg = [TABLE_CELL_BG[i % 2] for i in range(n_rows)]
|
|
283
357
|
|
|
284
|
-
fig
|
|
358
|
+
fig.add_trace(go.Table(
|
|
285
359
|
header=dict(
|
|
286
|
-
values=[
|
|
360
|
+
values=["<b>Setpoint</b>", "<b>Current</b>", "<b>Recommended</b>",
|
|
361
|
+
"<b>\u0394</b>", "<b>\u0394 (%)</b>"],
|
|
287
362
|
fill_color=TABLE_HEADER_BG,
|
|
288
363
|
font=dict(family=FONT_FAMILY, size=FONT_SIZE, color=TABLE_HEADER_TEXT),
|
|
289
364
|
align="left",
|
|
@@ -291,16 +366,25 @@ def setpoint_recommendation(context: wizata_dsapi.Context):
|
|
|
291
366
|
height=32,
|
|
292
367
|
),
|
|
293
368
|
cells=dict(
|
|
294
|
-
values=[
|
|
369
|
+
values=[
|
|
370
|
+
names,
|
|
371
|
+
[fmt(v) for v in currents],
|
|
372
|
+
[fmt(v) for v in recommendeds],
|
|
373
|
+
[fmt(v) for v in deltas],
|
|
374
|
+
[fmt(v) for v in pcts],
|
|
375
|
+
],
|
|
295
376
|
fill_color=[cell_bg],
|
|
296
377
|
font=dict(family=FONT_FAMILY, size=FONT_SIZE, color=TABLE_CELL_TEXT),
|
|
297
378
|
align="left",
|
|
298
379
|
line_color=TABLE_LINE_COLOR,
|
|
299
380
|
height=28,
|
|
300
381
|
),
|
|
301
|
-
)
|
|
382
|
+
), row=2, col=1)
|
|
302
383
|
|
|
303
|
-
fig.update_layout(
|
|
384
|
+
fig.update_layout(
|
|
385
|
+
title="Actual vs Recommended Values",
|
|
386
|
+
legend=dict(orientation="h", y=1.02, x=0.5, xanchor="center"),
|
|
387
|
+
)
|
|
304
388
|
apply_theme(fig)
|
|
305
389
|
|
|
306
390
|
context.set_plot(figure=fig, name="setpoint_recommendation")
|
|
@@ -361,6 +445,97 @@ def feature_importance(context: wizata_dsapi.Context):
|
|
|
361
445
|
context.set_plot(figure=fig, name="feature_importance")
|
|
362
446
|
|
|
363
447
|
|
|
448
|
+
def process_variability(context: wizata_dsapi.Context):
|
|
449
|
+
"""Parallel coordinates plot showing process configurations variability, colored by a quality
|
|
450
|
+
outcome. Columns are ordered by type: telemetry, setpoints, recommendations, calculated,
|
|
451
|
+
with the target/quality column last. Each axis label is prefixed with a type tag
|
|
452
|
+
([T], [SP], [REC], [C], [Q]) for quick identification.
|
|
453
|
+
|
|
454
|
+
Column selection:
|
|
455
|
+
- color_by: property name of the quality column used for coloring (defaults to
|
|
456
|
+
context.properties['target_feat'] if set, otherwise the last numeric column).
|
|
457
|
+
- color_reverse: set to true (default) when a LOWER color_by value is better
|
|
458
|
+
(e.g. residual_co2) — low values will be green. Set to false when higher is better
|
|
459
|
+
(e.g. 'good_bottles') — high values will be green.
|
|
460
|
+
"""
|
|
461
|
+
df = context.dataframe
|
|
462
|
+
if df is None or len(df) == 0:
|
|
463
|
+
raise ValueError("process_variability: dataframe is empty")
|
|
464
|
+
|
|
465
|
+
numeric_cols = df.select_dtypes(include="number").columns.tolist()
|
|
466
|
+
if len(numeric_cols) < 2:
|
|
467
|
+
raise ValueError("process_variability: need at least 2 numeric columns")
|
|
468
|
+
|
|
469
|
+
# Classify and order columns by type
|
|
470
|
+
classification = _classify_columns(df, context)
|
|
471
|
+
ordered_cols = _sort_columns_by_type(
|
|
472
|
+
[c for c in numeric_cols if c in classification],
|
|
473
|
+
classification
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
# Resolve color column
|
|
477
|
+
color_by = context.properties.get("color_by")
|
|
478
|
+
if color_by is None:
|
|
479
|
+
color_by = context.properties.get("target_feat")
|
|
480
|
+
if color_by is None:
|
|
481
|
+
color_by = ordered_cols[-1] if ordered_cols else numeric_cols[-1]
|
|
482
|
+
if color_by not in df.columns:
|
|
483
|
+
raise ValueError(f"process_variability: color_by column '{color_by}' not found in dataframe")
|
|
484
|
+
|
|
485
|
+
color_reverse = context.properties.get("color_reverse", True)
|
|
486
|
+
if isinstance(color_reverse, str):
|
|
487
|
+
color_reverse = color_reverse.lower() not in ("false", "0", "no")
|
|
488
|
+
|
|
489
|
+
# Build dimensions with type-tagged labels, in order
|
|
490
|
+
dimensions = []
|
|
491
|
+
for col in ordered_cols:
|
|
492
|
+
col_vals = df[col].dropna()
|
|
493
|
+
if col_vals.empty:
|
|
494
|
+
continue
|
|
495
|
+
info = classification[col]
|
|
496
|
+
tagged_label = f"[{info['tag']}] {col}"
|
|
497
|
+
dimensions.append(dict(
|
|
498
|
+
label=tagged_label,
|
|
499
|
+
values=df[col].values,
|
|
500
|
+
range=[float(col_vals.min()), float(col_vals.max())],
|
|
501
|
+
))
|
|
502
|
+
|
|
503
|
+
# Colorscale: red → yellow → green (reversed if lower is better)
|
|
504
|
+
if color_reverse:
|
|
505
|
+
colorscale = [[0, POSITIVE_COLOR], [0.5, "#FDDD60"], [1, "#FF6E76"]]
|
|
506
|
+
else:
|
|
507
|
+
colorscale = [[0, "#FF6E76"], [0.5, "#FDDD60"], [1, POSITIVE_COLOR]]
|
|
508
|
+
|
|
509
|
+
fig = go.Figure(data=go.Parcoords(
|
|
510
|
+
line=dict(
|
|
511
|
+
color=df[color_by].values,
|
|
512
|
+
colorscale=colorscale,
|
|
513
|
+
showscale=True,
|
|
514
|
+
colorbar=dict(title=color_by),
|
|
515
|
+
),
|
|
516
|
+
dimensions=dimensions,
|
|
517
|
+
))
|
|
518
|
+
|
|
519
|
+
# Add a legend-like annotation for the type tags
|
|
520
|
+
type_legend = " ".join(
|
|
521
|
+
f"[{t['tag']}] {t['label']}"
|
|
522
|
+
for t in [COLUMN_TYPE_TELEMETRY, COLUMN_TYPE_SETPOINT, COLUMN_TYPE_RECOMMENDATION,
|
|
523
|
+
COLUMN_TYPE_CALCULATED, COLUMN_TYPE_TARGET]
|
|
524
|
+
)
|
|
525
|
+
fig.update_layout(
|
|
526
|
+
title=dict(text="Configurations Variability"),
|
|
527
|
+
annotations=[dict(
|
|
528
|
+
text=type_legend,
|
|
529
|
+
xref="paper", yref="paper", x=0, y=-0.08,
|
|
530
|
+
showarrow=False,
|
|
531
|
+
font=dict(size=10, color=TEXT_MUTED),
|
|
532
|
+
)],
|
|
533
|
+
)
|
|
534
|
+
apply_theme(fig)
|
|
535
|
+
|
|
536
|
+
context.set_plot(figure=fig, name="process_variability")
|
|
537
|
+
|
|
538
|
+
|
|
364
539
|
def data_table(context: wizata_dsapi.Context):
|
|
365
540
|
"""Render the dataframe as a styled table with Wizata theme colors."""
|
|
366
541
|
df = context.dataframe.copy()
|
|
@@ -53,6 +53,16 @@ TABLE_CELL_BG = [TERTIARY, FOURTH]
|
|
|
53
53
|
TABLE_CELL_TEXT = TEXT_MUTED
|
|
54
54
|
TABLE_LINE_COLOR = "rgba(255,255,255,0.12)"
|
|
55
55
|
|
|
56
|
+
# -- Column type classification -----------------------------------------------
|
|
57
|
+
# Used by plots to visually distinguish column roles in the process pipeline.
|
|
58
|
+
COLUMN_TYPE_TELEMETRY = {"tag": "T", "label": "Telemetry", "color": "#4992FF"}
|
|
59
|
+
COLUMN_TYPE_SETPOINT = {"tag": "SP", "label": "Setpoint", "color": "#E64600"}
|
|
60
|
+
COLUMN_TYPE_RECOMMENDATION = {"tag": "REC", "label": "Recommendation", "color": "#7CFFB2"}
|
|
61
|
+
COLUMN_TYPE_TARGET = {"tag": "Q", "label": "Target / Quality", "color": "#FDDD60"}
|
|
62
|
+
COLUMN_TYPE_CALCULATED = {"tag": "C", "label": "Calculated", "color": "#9E7CFF"}
|
|
63
|
+
|
|
64
|
+
COLUMN_TYPES_ORDER = ["telemetry", "setpoint", "recommendation", "calculated", "target"]
|
|
65
|
+
|
|
56
66
|
# -- Font ---------------------------------------------------------------------
|
|
57
67
|
FONT_FAMILY = "Inter, -apple-system, BlinkMacSystemFont, sans-serif"
|
|
58
68
|
FONT_SIZE = 12
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.0.dev29"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.0.0.dev27"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{wizata_dsapi-2.0.0.dev27 → wizata_dsapi-2.0.0.dev29}/wizata_dsapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|