wizata-dsapi 2.0.0.dev26__tar.gz → 2.0.0.dev27__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 (67) hide show
  1. {wizata_dsapi-2.0.0.dev26/wizata_dsapi.egg-info → wizata_dsapi-2.0.0.dev27}/PKG-INFO +1 -1
  2. wizata_dsapi-2.0.0.dev27/wizata_dsapi/plots/__init__.py +2 -0
  3. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/plots/common.py +141 -0
  4. wizata_dsapi-2.0.0.dev27/wizata_dsapi/version.py +1 -0
  5. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27/wizata_dsapi.egg-info}/PKG-INFO +1 -1
  6. wizata_dsapi-2.0.0.dev26/wizata_dsapi/plots/__init__.py +0 -2
  7. wizata_dsapi-2.0.0.dev26/wizata_dsapi/version.py +0 -1
  8. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/LICENSE.txt +0 -0
  9. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/README.rst +0 -0
  10. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/setup.cfg +0 -0
  11. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/setup.py +0 -0
  12. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/__init__.py +0 -0
  13. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/api_config.py +0 -0
  14. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/api_dto.py +0 -0
  15. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/api_interface.py +0 -0
  16. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/bucket.py +0 -0
  17. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/business_label.py +0 -0
  18. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/context.py +0 -0
  19. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/dashboard.py +0 -0
  20. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/dataframe_toolkit.py +0 -0
  21. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/datapoint.py +0 -0
  22. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/datastore.py +0 -0
  23. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/ds_dataframe.py +0 -0
  24. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  25. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/edge_config.py +0 -0
  26. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/edge_device.py +0 -0
  27. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/edge_module.py +0 -0
  28. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/evaluation.py +0 -0
  29. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/execution.py +0 -0
  30. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/execution_log.py +0 -0
  31. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/experiment.py +0 -0
  32. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/graylog_log.py +0 -0
  33. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/group_system.py +0 -0
  34. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/ilogger.py +0 -0
  35. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/insight.py +0 -0
  36. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/mlmodel.py +0 -0
  37. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/mobile_asset.py +0 -0
  38. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/model_toolkit.py +0 -0
  39. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/models/__init__.py +0 -0
  40. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/models/common.py +0 -0
  41. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/notification.py +0 -0
  42. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/paged_query_result.py +0 -0
  43. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/pipeline.py +0 -0
  44. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/pipeline_image.py +0 -0
  45. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/plot.py +0 -0
  46. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/plots/theme.py +0 -0
  47. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/request.py +0 -0
  48. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/script.py +0 -0
  49. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/scripts/__init__.py +0 -0
  50. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/scripts/common.py +0 -0
  51. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/search.py +0 -0
  52. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/solution_component.py +0 -0
  53. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/streamlit_utils.py +0 -0
  54. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/template.py +0 -0
  55. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/template_config.py +0 -0
  56. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/trigger.py +0 -0
  57. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/twin.py +0 -0
  58. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/twinregistration.py +0 -0
  59. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/user.py +0 -0
  60. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/wizard_function.py +0 -0
  61. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/wizard_request.py +0 -0
  62. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/wizata_dsapi_client.py +0 -0
  63. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi/words.py +0 -0
  64. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  65. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  66. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi.egg-info/requires.txt +0 -0
  67. {wizata_dsapi-2.0.0.dev26 → wizata_dsapi-2.0.0.dev27}/wizata_dsapi.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.0.0.dev26
3
+ Version: 2.0.0.dev27
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -0,0 +1,2 @@
1
+ from .common import ts_chart, confusion_matrix, r_squared, anomalies_chart, parallel_coordinates, data_table, setpoint_recommendation, feature_importance
2
+ from . import theme
@@ -220,6 +220,147 @@ def parallel_coordinates(context: wizata_dsapi.Context):
220
220
  )
221
221
 
222
222
 
223
+ def setpoint_recommendation(context: wizata_dsapi.Context):
224
+ """Compare current vs recommended setpoint values as a Wizata-themed table.
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).
230
+
231
+ Output columns: Setpoint | Current | Recommended | Δ | Δ (%)
232
+ """
233
+ df = context.dataframe
234
+ datapoints = context.datapoints or {}
235
+
236
+ if df is None or len(df) == 0:
237
+ raise ValueError("setpoint_recommendation: dataframe is empty")
238
+
239
+ suffix = "_recommended"
240
+ pairs = []
241
+ for col in df.columns:
242
+ if not isinstance(col, str) or not col.endswith(suffix):
243
+ continue
244
+ base = col[: -len(suffix)]
245
+ if base not in df.columns:
246
+ 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
+ if datapoints:
250
+ dp = datapoints.get(base)
251
+ if dp is None or dp.business_type != wizata_dsapi.BusinessType.SET_POINTS:
252
+ continue
253
+ pairs.append((base, col))
254
+
255
+ if not pairs:
256
+ raise ValueError(
257
+ "setpoint_recommendation: no <col>_recommended / setpoint pairs found in the dataframe"
258
+ )
259
+
260
+ last = df.iloc[-1]
261
+ rows = []
262
+ for base, rec in pairs:
263
+ current = last[base]
264
+ recommended = last[rec]
265
+ delta = recommended - current
266
+ pct = (delta / current * 100.0) if current not in (0, 0.0) and not pd.isna(current) else float("nan")
267
+ rows.append({
268
+ "Setpoint": base,
269
+ "Current": current,
270
+ "Recommended": recommended,
271
+ "Δ": delta,
272
+ "Δ (%)": pct,
273
+ })
274
+
275
+ out = pd.DataFrame(rows)
276
+
277
+ # Formatting — round numerics for readability
278
+ for col in ("Current", "Recommended", "Δ", "Δ (%)"):
279
+ out[col] = out[col].apply(lambda v: "—" if pd.isna(v) else f"{v:.3f}")
280
+
281
+ n_rows = len(out)
282
+ cell_bg = [TABLE_CELL_BG[i % 2] for i in range(n_rows)]
283
+
284
+ fig = go.Figure(data=[go.Table(
285
+ header=dict(
286
+ values=[f"<b>{c}</b>" for c in out.columns],
287
+ fill_color=TABLE_HEADER_BG,
288
+ font=dict(family=FONT_FAMILY, size=FONT_SIZE, color=TABLE_HEADER_TEXT),
289
+ align="left",
290
+ line_color=TABLE_LINE_COLOR,
291
+ height=32,
292
+ ),
293
+ cells=dict(
294
+ values=[out[c].tolist() for c in out.columns],
295
+ fill_color=[cell_bg],
296
+ font=dict(family=FONT_FAMILY, size=FONT_SIZE, color=TABLE_CELL_TEXT),
297
+ align="left",
298
+ line_color=TABLE_LINE_COLOR,
299
+ height=28,
300
+ ),
301
+ )])
302
+
303
+ fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
304
+ apply_theme(fig)
305
+
306
+ context.set_plot(figure=fig, name="setpoint_recommendation")
307
+
308
+
309
+ def feature_importance(context: wizata_dsapi.Context):
310
+ """Plot the top-N feature importances of a trained model as a horizontal bar chart.
311
+
312
+ Scans context.models for a model whose underlying trained_model exposes `feature_importances_`
313
+ (RandomForestRegressor, RandomForestClassifier, GradientBoostingClassifier, etc.). Uses
314
+ `ml_model.input_columns` for feature labels. Bars are sorted ascending so the most important
315
+ feature is at the top when rendered.
316
+
317
+ Property: top_n (default 15) — maximum number of features to display.
318
+ """
319
+ top_n = int(context.properties.get("top_n", 15)) if "top_n" in context.properties else 15
320
+
321
+ selected = None
322
+ for model in (context.models or {}).values():
323
+ trained = getattr(model, "trained_model", None)
324
+ if trained is not None and hasattr(trained, "feature_importances_"):
325
+ selected = model
326
+ break
327
+
328
+ if selected is None:
329
+ raise ValueError(
330
+ "feature_importance: no trained model with feature_importances_ found in context.models "
331
+ "(supported by RandomForest, GradientBoosting, and similar tree-based models)"
332
+ )
333
+
334
+ importances = np.asarray(selected.trained_model.feature_importances_)
335
+ feature_names = list(selected.input_columns) if selected.input_columns is not None else \
336
+ [f"f{i}" for i in range(len(importances))]
337
+
338
+ if len(feature_names) != len(importances):
339
+ raise ValueError(
340
+ f"feature_importance: feature_importances_ length {len(importances)} does not match "
341
+ f"input_columns length {len(feature_names)}"
342
+ )
343
+
344
+ fi = pd.DataFrame({"feature": feature_names, "importance": importances})
345
+ fi = fi.sort_values("importance", ascending=True).tail(top_n)
346
+
347
+ fig = go.Figure(go.Bar(
348
+ x=fi["importance"],
349
+ y=fi["feature"],
350
+ orientation="h",
351
+ marker_color=SERIES_COLORS[0],
352
+ ))
353
+ fig.update_layout(
354
+ title=f"Top-{min(top_n, len(fi))} Feature Importances",
355
+ xaxis=dict(title="Importance"),
356
+ yaxis=dict(title=""),
357
+ margin=dict(l=200, r=20, t=40, b=40),
358
+ )
359
+ apply_theme(fig)
360
+
361
+ context.set_plot(figure=fig, name="feature_importance")
362
+
363
+
223
364
  def data_table(context: wizata_dsapi.Context):
224
365
  """Render the dataframe as a styled table with Wizata theme colors."""
225
366
  df = context.dataframe.copy()
@@ -0,0 +1 @@
1
+ __version__ = "2.0.0.dev27"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.0.0.dev26
3
+ Version: 2.0.0.dev27
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -1,2 +0,0 @@
1
- from .common import ts_chart, confusion_matrix, r_squared, anomalies_chart, parallel_coordinates, data_table
2
- from . import theme
@@ -1 +0,0 @@
1
- __version__ = "2.0.0.dev26"