howso-visuals 2.5.7__tar.gz → 3.0.0__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.
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/PKG-INFO +1 -1
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/tests/test_plot.py +3 -3
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/visuals.py +71 -36
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso_visuals.egg-info/PKG-INFO +1 -1
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.flake8 +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/CODEOWNERS +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/templates/version_summary.md +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/workflows/build-pr.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/workflows/build-release.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/workflows/build.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.github/workflows/rebuild-requirements.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/.gitignore +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/CONTRIBUTING.md +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/LICENSE-3RD-PARTY.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/LICENSE.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/README.md +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/bin/build.sh +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/latest-mt-debug-howso.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/latest-mt-howso.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/latest-mt-noavx-debug-howso.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/latest-st-debug-howso.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/latest-st-howso.yml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/powershell/Download-Tzdata.ps1 +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/config/powershell/Helper-Functions.ps1 +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/__init__.py +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/colors.py +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/data/iris.csv +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/graph.py +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/tests/conftest.py +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso/visuals/tests/test_graph.py +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso_visuals.egg-info/SOURCES.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso_visuals.egg-info/dependency_links.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso_visuals.egg-info/requires.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/howso_visuals.egg-info/top_level.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/pyproject.toml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.10-dev.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.10.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.11-dev.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.11.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.12-dev.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.12.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.13-dev.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.13.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.9-dev.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/requirements-3.9.txt +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/ruff.toml +0 -0
- {howso_visuals-2.5.7 → howso_visuals-3.0.0}/setup.cfg +0 -0
|
@@ -53,9 +53,9 @@ def test_plot_interpretable_prediction_react(
|
|
|
53
53
|
desired_conviction=5_000,
|
|
54
54
|
num_cases_to_generate=20,
|
|
55
55
|
)
|
|
56
|
-
generative_reacts = result["action"]
|
|
57
|
-
generative_reacts[0] = generative_reacts[0] + 0.2
|
|
58
|
-
generative_reacts[
|
|
56
|
+
generative_reacts = result["action"]
|
|
57
|
+
generative_reacts.loc[0, action_feature] = generative_reacts.loc[0, action_feature] + 0.2
|
|
58
|
+
generative_reacts.loc[19, action_feature] = generative_reacts.loc[19, action_feature] - 0.2
|
|
59
59
|
else:
|
|
60
60
|
generative_reacts = None
|
|
61
61
|
|
|
@@ -479,10 +479,11 @@ def plot_interpretable_prediction(
|
|
|
479
479
|
react: "Reaction",
|
|
480
480
|
*,
|
|
481
481
|
actual_value: float | None = None,
|
|
482
|
-
generative_reacts:
|
|
482
|
+
generative_reacts: pd.DataFrame | None = None,
|
|
483
483
|
residual: float | None = None,
|
|
484
484
|
secondary_yaxis_title: str = "Influence Weight",
|
|
485
|
-
|
|
485
|
+
subplot_titles: list[str] | None = None,
|
|
486
|
+
title: str = "Interpretable Predictions",
|
|
486
487
|
tooltip_features: Collection[str] | None = None,
|
|
487
488
|
xaxis_title: str | None = None,
|
|
488
489
|
yaxis_title: str = "Density",
|
|
@@ -495,10 +496,10 @@ def plot_interpretable_prediction(
|
|
|
495
496
|
react : Reaction
|
|
496
497
|
The reaction predicting the action feature(s) to visualize. If this contains more than one action feature,
|
|
497
498
|
each will be given its own plot.
|
|
498
|
-
generative_reacts :
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
499
|
+
generative_reacts : DataFrame, optional
|
|
500
|
+
Ann optional `DataFrame` of generative reactions which will be used to visualize a KDE around
|
|
501
|
+
the predicted value. If this is None, the distribution of influential cases in the react will
|
|
502
|
+
be used instead, if present.
|
|
502
503
|
actual_value : float, optional
|
|
503
504
|
The actual value for the point that was predicted. If this is None, only the predicted value will be
|
|
504
505
|
visualized.
|
|
@@ -507,7 +508,9 @@ def plot_interpretable_prediction(
|
|
|
507
508
|
predicted value. If this is None, no error bar will be displayed
|
|
508
509
|
secondary_yaxis_title : str, default "Influence Weight"
|
|
509
510
|
The title for the figure's secondary y axis.
|
|
510
|
-
|
|
511
|
+
subplot_titles : list[str], optional
|
|
512
|
+
A list of titles to use for subplots. If this is None, titles will be auto-generated.
|
|
513
|
+
title : str, default "Interpretable Prediction"
|
|
511
514
|
The title for the figure.
|
|
512
515
|
tooltip_features : Collection[str], optional
|
|
513
516
|
Additional features to include in the tooltip when hovering over an influential case in the plot.
|
|
@@ -521,31 +524,52 @@ def plot_interpretable_prediction(
|
|
|
521
524
|
Figure or list of Figure
|
|
522
525
|
The resultant `Plotly` figure(s).
|
|
523
526
|
"""
|
|
524
|
-
figures = []
|
|
525
527
|
tooltip_features = list(tooltip_features) if tooltip_features is not None else []
|
|
528
|
+
action_features = react["action"].columns
|
|
529
|
+
num_rows = len(action_features)
|
|
530
|
+
subplot_titles = subplot_titles or [f"Interpretable Prediction for: {af}" for af in action_features]
|
|
531
|
+
case_hover_template = "<b>Value:</b> %{x}<br><b>Influence:</b> N/A"
|
|
532
|
+
fig = make_subplots(
|
|
533
|
+
rows=num_rows,
|
|
534
|
+
specs=[[{"secondary_y": True}]] * num_rows,
|
|
535
|
+
subplot_titles=subplot_titles,
|
|
536
|
+
)
|
|
526
537
|
|
|
527
|
-
for action_feature in
|
|
538
|
+
for row, action_feature in enumerate(action_features):
|
|
528
539
|
predicted_value = react["action"][action_feature].iloc[0]
|
|
540
|
+
legend = "legend" if row == 0 else f"legend{row + 1}"
|
|
529
541
|
|
|
530
542
|
influential_cases = react.get("details", {}).get("influential_cases")
|
|
531
543
|
influential_cases = influential_cases[0] if influential_cases else None
|
|
532
544
|
|
|
533
545
|
if generative_reacts is not None:
|
|
534
|
-
action_distribution = generative_reacts
|
|
535
|
-
|
|
546
|
+
action_distribution = generative_reacts[action_feature]
|
|
547
|
+
elif influential_cases is not None:
|
|
536
548
|
action_distribution = [c[action_feature] for c in influential_cases]
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
+
else:
|
|
550
|
+
action_distribution = None
|
|
551
|
+
|
|
552
|
+
if action_distribution is not None:
|
|
553
|
+
action_kde = gaussian_kde(action_distribution)
|
|
554
|
+
density_x = np.linspace(
|
|
555
|
+
min(action_distribution) * 0.6,
|
|
556
|
+
max(action_distribution) * 1.4,
|
|
557
|
+
len(action_distribution),
|
|
558
|
+
)
|
|
559
|
+
density_y = action_kde(density_x)
|
|
560
|
+
fig.add_trace(
|
|
561
|
+
go.Scattergl(
|
|
562
|
+
x=density_x,
|
|
563
|
+
y=density_y,
|
|
564
|
+
fill="tonexty",
|
|
565
|
+
name="Distribution",
|
|
566
|
+
hoverinfo="skip",
|
|
567
|
+
mode="lines",
|
|
568
|
+
legend=legend,
|
|
569
|
+
),
|
|
570
|
+
row=row + 1,
|
|
571
|
+
col=1,
|
|
572
|
+
)
|
|
549
573
|
predicted_case_hover_template = case_hover_template
|
|
550
574
|
|
|
551
575
|
if influential_cases is not None:
|
|
@@ -561,14 +585,17 @@ def plot_interpretable_prediction(
|
|
|
561
585
|
fig.add_trace(
|
|
562
586
|
go.Scattergl(
|
|
563
587
|
x=[predicted_value],
|
|
564
|
-
y=[max_inf_weight * 1.05],
|
|
588
|
+
y=[max_inf_weight * 1.05] if max_inf_weight else 1,
|
|
565
589
|
name="Predicted Value",
|
|
566
590
|
mode="markers",
|
|
567
591
|
marker={"size": 15, "color": "purple"},
|
|
568
592
|
hovertemplate=predicted_case_hover_template,
|
|
569
593
|
error_x=error_x,
|
|
594
|
+
legend=legend,
|
|
570
595
|
),
|
|
571
596
|
secondary_y=True,
|
|
597
|
+
row=row + 1,
|
|
598
|
+
col=1,
|
|
572
599
|
)
|
|
573
600
|
|
|
574
601
|
if actual_value is not None:
|
|
@@ -576,19 +603,22 @@ def plot_interpretable_prediction(
|
|
|
576
603
|
fig.add_trace(
|
|
577
604
|
go.Scattergl(
|
|
578
605
|
x=[actual_value],
|
|
579
|
-
y=[max_inf_weight * 1.05],
|
|
606
|
+
y=[max_inf_weight * 1.05] if max_inf_weight else 1,
|
|
580
607
|
name="Actual Value",
|
|
581
608
|
mode="markers",
|
|
582
609
|
marker=dict(size=15, color="orange"),
|
|
583
610
|
hovertemplate=case_hover_template,
|
|
611
|
+
legend=legend,
|
|
584
612
|
),
|
|
585
613
|
secondary_y=True,
|
|
614
|
+
row=row + 1,
|
|
615
|
+
col=1,
|
|
586
616
|
)
|
|
587
617
|
|
|
588
618
|
# Update axes, hover mode
|
|
589
|
-
fig.update_xaxes(title_text=xaxis_title or action_feature, autorange=True)
|
|
590
|
-
fig.update_yaxes(title_text=yaxis_title, color="blue", secondary_y=False)
|
|
591
|
-
fig.update_yaxes(title_text=secondary_yaxis_title, color="green", secondary_y=True)
|
|
619
|
+
fig.update_xaxes(title_text=xaxis_title or action_feature, autorange=True, row=row + 1, col=1)
|
|
620
|
+
fig.update_yaxes(title_text=yaxis_title, color="blue", secondary_y=False, row=row + 1, col=1)
|
|
621
|
+
fig.update_yaxes(title_text=secondary_yaxis_title, color="green", secondary_y=True, row=row + 1, col=1)
|
|
592
622
|
|
|
593
623
|
if influential_cases is not None and len(influential_cases):
|
|
594
624
|
inf_case_hover_template = (
|
|
@@ -621,19 +651,24 @@ def plot_interpretable_prediction(
|
|
|
621
651
|
customdata=inf_case_labels,
|
|
622
652
|
mode="markers",
|
|
623
653
|
marker=dict(color="green"),
|
|
654
|
+
legend=legend,
|
|
624
655
|
),
|
|
625
656
|
secondary_y=True,
|
|
657
|
+
row=row + 1,
|
|
658
|
+
col=1,
|
|
626
659
|
)
|
|
627
660
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
661
|
+
# Increase height based on the number of rows
|
|
662
|
+
fig.update_layout(height=300 * num_rows)
|
|
663
|
+
# Place a legend to the right of each subplot.
|
|
664
|
+
for i, yaxis in enumerate(fig.select_yaxes(secondary_y=False), 1):
|
|
665
|
+
legend_name = f"legend{i}"
|
|
666
|
+
fig.update_layout({legend_name: dict(y=yaxis.domain[1], yanchor="top")}, showlegend=True)
|
|
667
|
+
fig.update_traces(row=i, legend=legend_name)
|
|
633
668
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
return
|
|
669
|
+
title = title or "Interpretable Predictions"
|
|
670
|
+
fig.update_layout(title=title)
|
|
671
|
+
return fig
|
|
637
672
|
|
|
638
673
|
|
|
639
674
|
def plot_fairness_disparity(
|
|
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
|