Build hierarchical visualizations
HierarchyPlotter builds a tree of subgroup counts and optional continuous-score aggregates. It returns data arrays; it does not render a chart itself.
Install a renderer
Section titled “Install a renderer”Plotly is not a Model Auditor dependency.
python -m pip install plotlyCompile a flat feature hierarchy
Section titled “Compile a flat feature hierarchy”from model_auditor.plotting import HierarchyPlotter
plotter = HierarchyPlotter()plotter.set_data(data)plotter.set_features( [ "region", "age_group", "device_type", ])plotter.set_score( name="risk_score", label="Risk score",)plotter.set_aggregator("median")
plot_data = plotter.compile( container="All observations",)The root and every hierarchy node receive:
- a display label;
- a unique ID;
- a parent ID;
- a row count in
values; and - the aggregated continuous score in
colors.
Render a sunburst
Section titled “Render a sunburst”import plotly.graph_objects as go
figure = go.Figure( go.Sunburst( labels=plot_data.labels, ids=plot_data.ids, parents=plot_data.parents, values=plot_data.values, branchvalues="total", marker={ "colors": plot_data.colors, "colorscale": "Viridis", "colorbar": {"title": "Median risk score"}, }, ))
figure.update_layout( margin={"t": 30, "l": 0, "r": 0, "b": 0},)
figure.show()The same arrays can feed a treemap or another hierarchy renderer.
Use a custom aggregate
Section titled “Use a custom aggregate”A string aggregator is applied to the score Series. A callable receives the full DataFrame for the root and each grouped branch in v0.1.16.
import pandas as pd
def upper_quartile_score(group: pd.DataFrame) -> float: return float(group["risk_score"].quantile(0.75))
plotter.set_aggregator(upper_quartile_score)plot_data = plotter.compile(container="All observations")The callable must return one scalar per node.
Define a branch-dependent hierarchy
Section titled “Define a branch-dependent hierarchy”Use Hierarchy, HLevel, and HItem when the next column depends on the current branch.
from model_auditor.plotting.schemas import Hierarchy, HItem, HLevel
hierarchy = Hierarchy( levels=[ HLevel( [ HItem(name="region_type"), ] ), HLevel( [ HItem( name="urban_density", query="region_type == 'Urban'", ), HItem( name="rural_access", query="region_type == 'Rural'", ), ] ), HLevel( [ HItem(name="age_group"), ] ), ])
plotter.set_features(hierarchy)plot_data = plotter.compile(container="All observations")An item’s query is evaluated against the current hierarchy branch. The item is selected only when the expression is true for every row in that branch. It is not a row-level filter.
At a level where multiple items are valid, Model Auditor concatenates their row values with & to form a composite temporary feature.
Compile counts without score colors
Section titled “Compile counts without score colors”A score is optional:
count_plotter = HierarchyPlotter()count_plotter.set_data(data)count_plotter.set_features(["region", "age_group"])
plot_data = count_plotter.compile( container="All observations",)The method emits a warning and appends None for node colors.
Prepare categorical data deliberately
Section titled “Prepare categorical data deliberately”Hierarchy grouping uses pandas with observed=False. Unused categories can therefore appear as zero-count or NaN-colored nodes, depending on the aggregation path. Remove unused categories first when the chart should show only observed combinations:
data["region"] = data["region"].cat.remove_unused_categories()Null grouping values are not represented as ordinary groups by default.
Stable-release limitations
Section titled “Stable-release limitations”The hierarchy API does not calculate performance metrics or bootstrap intervals. Join externally prepared values or create a custom renderer when the chart needs those quantities.
See Hierarchical plot data and Plotting API for exact schemas.