Widget in Jupyter NotebookAdvanced Features

Advanced Features

The widget supports advanced features for flexible data processing and reusable configurations:

Partial Functions

When you call cosmo() without providing any data (no data, points, or links), it returns a partial function that captures your configuration. You can call it later with different datasets:

import pandas as pd
from cosmograph import cosmo
 
# Sample data
data_potions = {
    "potion_name": ["Elixir of Vitality", "Draught of Invisibility", "Brew of Fireball"],
    "Brewmaster": ["Elder Willow", "Mistress Shadow", "Master Ignis"],
    "Ingredients": [
        "Dragon Scale, Phoenix Feather, Unicorn Tears",
        "Nightshade, Moonflower, Shadow Essence",
        "Fireroot, Lava Crystal, Unicorn Tears, Ember Dust",
    ],
    "Location_X": [500, 620, 450],
    "Location_Y": [300, 400, 350],
    "potion_color": ["Blue", "White", "Red"],
    "potion_difficulty": [25, 30, 20],
}
 
df_potions = pd.DataFrame(data_potions)
 
# Create a reusable configuration
my_cosmo = cosmo(
    point_x_by="Location_X",
    point_y_by="Location_Y",
    point_label_by="potion_name",
    point_size_by="potion_difficulty",
    point_color_by="potion_color",
)
 
# Use with the same dataset multiple times
widget1 = my_cosmo(df_potions)
 
# You can override configuration when calling
widget2 = my_cosmo(df_potions, point_size_scale=5.0)

Ingress System

The ingress parameter allows you to define custom transformation functions that process arguments before widget creation. Each ingress function receives the kwargs dictionary and must return the modified kwargs.

A common use case is to handle functional mappings that aren’t supported directly by the widget:

def handle_functional_color(kwargs):
    """Convert functional point_color_by to a DataFrame column"""
    if callable(kwargs.get("point_color_by")):
        point_color_by_func = kwargs["point_color_by"]
        points = kwargs["points"].copy()
        points["_point_color_by"] = points.apply(point_color_by_func, axis=1)
        kwargs["point_color_by"] = "_point_color_by"
        kwargs["points"] = points
    return kwargs
 
# Use with a function instead of a column name
widget = my_cosmo(
    df_potions,
    ingress=handle_functional_color,
    point_color_by=lambda x: int("Unicorn Tears" in x["Ingredients"])
)

You can provide multiple ingress functions that are applied in sequence. By default, data is copied before ingress transformations (copy_before_ingress=True), preserving your original data.

Custom Data Resolution

The data_resolution parameter controls how the data argument is distributed between points and links. By default, it uses prioritize_points:

  • If only data is provided and points is None → data becomes points
  • If points is provided and links is None → data becomes links

Example with default behavior:

import pandas as pd
from cosmograph import cosmo
 
# Points data
points_df = pd.DataFrame({
    "id": ["A", "B", "C", "D"],
    "name": ["Node A", "Node B", "Node C", "Node D"],
    "value": [10, 20, 15, 25]
})
 
# Links data
links_df = pd.DataFrame({
    "source": ["A", "B", "C", "A"],
    "target": ["B", "C", "D", "D"],
    "weight": [1.0, 2.0, 1.5, 0.5]
})
 
# Default behavior: data → points (when points is None)
widget1 = cosmo(
    data=points_df,  # Becomes points
    point_id_by='id'
)
 
# Default behavior: data → links (when points exists)
widget2 = cosmo(
    points=points_df,
    data=links_df,  # Becomes links
    point_id_by='id',
    link_source_by='source',
    link_target_by='target'
)

You can provide a custom function to change this behavior:

def prioritize_links(kwargs, data=None):
    """Prioritize assigning data to links instead of points"""
    if data is not None:
        if kwargs.get("links", None) is None:
            kwargs["links"] = data
        elif kwargs.get("points", None) is None:
            kwargs["points"] = data
        else:
            raise ValueError("Cannot specify both points and links if data is provided")
    return kwargs
 
# Custom behavior: data → links (even when points is None)
widget3 = cosmo(
    data=links_df,  # With prioritize_links, this becomes links
    data_resolution=prioritize_links,
    point_id_by='id',
    link_source_by='source',
    link_target_by='target'
)

Execution Order

These features execute in this order:

  1. Check for partial function: If data, points, and links are all None, return a partial function
  2. Apply data_resolution: Assigns data to points or links (default: prioritize_points)
  3. Apply ingress transformations (in sequence):
    • If copy_before_ingress=True (default), copy points and links first
    • Then apply each ingress function in order
  4. Remove None values: Clean up kwargs by removing None values
  5. Validate kwargs: Checks that all argument names are valid parameter names. Provides helpful error messages for typos and suggests aliases (e.g., nodespoints, edgeslinks). You can customize this with the validate_kwargs parameter, but the default is usually sufficient.
  6. Create widget: Instantiate the Cosmograph widget

For basic usage examples, see Get started. For all configuration options, see Configuration.