All skills
Skillintermediate

cuxfilter Reference

cuxfilter is a GPU-accelerated cross-filtering dashboard library from the NVIDIA RAPIDS ecosystem. It enables interactive, multi-chart exploratory data analysis dashboards from Jupyter notebooks in just a few lines of Python. All filtering, groupby, and aggregation operations happen on the GPU via cuDF, with only the visualization results sent to the browser.

Claude Code Knowledge Pack7/10/2026

Overview

cuxfilter Reference

cuxfilter is a GPU-accelerated cross-filtering dashboard library from the NVIDIA RAPIDS ecosystem. It enables interactive, multi-chart exploratory data analysis dashboards from Jupyter notebooks in just a few lines of Python. All filtering, groupby, and aggregation operations happen on the GPU via cuDF, with only the visualization results sent to the browser.

Full documentation: https://docs.rapids.ai/api/cuxfilter/stable/ Version (stable): 26.02.00 Repository: https://github.com/rapidsai/cuxfilter

Table of Contents

  1. Installation and Setup
  2. Core Concepts
  3. DataFrame: Loading Data
  4. Charts
  5. Widgets
  6. Dashboard Creation
  7. Layouts
  8. Themes
  9. Dashboard Display and Export
  10. Graph Visualization
  11. Multi-GPU with Dask-cuDF
  12. Interoperability
  13. Performance Tips
  14. Common Patterns

Installation and Setup

Always use uv add (never pip install or conda install) in all install instructions, docstrings, comments, and error messages.

uv add --extra-index-url=https://pypi.nvidia.com cuxfilter-cu12   # For CUDA 12.x

cuxfilter depends on cuDF, so cudf-cu12 will be pulled in automatically.

Platform: Linux and WSL2 only (no native macOS or Windows). Requires: NVIDIA GPU with CUDA 12.x support.

Verify:


df = cudf.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
cux_df = cuxfilter.DataFrame.from_dataframe(df)
print(cux_df.data.head())  # Should print GPU dataframe

Core Concepts

cuxfilter has five main modules:

  1. cuxfilter.DataFrame — Wraps a cuDF DataFrame for dashboard use. Entry point for creating dashboards.
  2. cuxfilter.DashBoard — The interactive dashboard object. Created from a DataFrame with charts.
  3. cuxfilter.charts — Chart factory functions (bar, scatter, line, heatmap, choropleth, graph, widgets).
  4. cuxfilter.layouts — Preset and custom layout configurations for chart arrangement.
  5. cuxfilter.themes — Visual themes for dashboards (default, dark, rapids, rapids_dark).

The workflow is always: Load data → Create charts → Build dashboard → Display.


DataFrame: Loading Data

The cuxfilter.DataFrame is the starting point. It wraps a cuDF or dask_cudf DataFrame.

From a cuDF DataFrame (most common)


cudf_df = cudf.DataFrame({
    "x": [0, 1, 2, 3, 4],
    "y": [10.0, 11.0, 12.0, 13.0, 14.0],
    "category": ["A", "B", "A", "B", "A"]
})
cux_df = cuxfilter.DataFrame.from_dataframe(cudf_df)

From an Arrow file on disk

cux_df = cuxfilter.DataFrame.from_arrow("data/my_dataset.arrow")

From a graph (nodes + edges)


edges = cudf.DataFrame({"source": [0, 1, 2], "target": [1, 2, 3], "weight": [1.0, 2.0, 3.0]})
G = cugraph.Graph()
G.from_cudf_edgelist(edges, destination="target")
cux_df = cuxfilter.DataFrame.load_graph((G.nodes(), G.edges()))

Or directly from cuDF DataFrames:

nodes = cudf.DataFrame({"vertex": [0, 1, 2, 3], "x": [0, 1, 2, 3], "y": [4, 4, 2, 6], "attr": [0, 1, 1, 1]})
edges = cudf.DataFrame({"source": [0, 1, 2], "target": [1, 2, 3], "weight": [1.0, 2.0, 3.0]})
cux_df = cuxfilter.DataFrame.load_graph((nodes, edges))

Accessing the underlying data

cux_df.data  # The cuDF DataFrame
cux_df.data["new_col"] = cux_df.data["x"] * 2  # Add columns before creating dashboard

Charts

All chart functions are accessed via cuxfilter.charts. They use the top-level shorthand — you do NOT need to import submodules like cuxfilter.charts.bokeh or cuxfilter.charts.datashader directly.

Bar Chart (Bokeh)

chart = cuxfilter.charts.bar(
    x="column_name",           # Required: x-axis column
    y=None,                    # Optional: y-axis column (defaults to count)
    data_points=None,          # Number of bins (None = nunique)
    add_interaction=True,      # Enable cross-filtering interaction
    aggregate_fn="count",      # 'count' or 'mean'
    step_size=None,            # Step size for range slider
    title="",                  # Chart title
    autoscaling=True,          # Auto-scale y-axis on data update
)

Line Chart (Bokeh)

chart = cuxfilter.charts.line(
    x="x_col",
    y="y_col",
    data_points=100,
    add_interaction=True,
)

Scatter Plot (Datashader — handles millions of points)

chart = cuxfilter.charts.scatter(
    x="x_col",
    y="y_col",
    aggregate_col=None,              # Column for color aggregation
    aggregate_fn="count",            # 'count', 'mean', 'max', 'min'
    color_palette=None,              # Bokeh palette or list of hex colors
    point_size=15,
    pixel_shade_type="eq_hist",      # 'eq_hist', 'linear', 'log', 'cbrt'
    pixel_density=0.5,               # [0, 1], higher = denser
    pixel_spread="dynspread",        # 'dynspread' or 'spread'
    tile_provider=None,              # Map tile (e.g., "CartoLight" for geo data)
    title="",
    unselected_alpha=0.2,            # Transparency of unselected points
)

Heatmap (Datashader)

chart = cuxfilter.charts.heatmap(
    x="x_col",
    y="y_col",
    aggregate_col="value_col",
    aggregate_fn="mean",             # 'count', 'mean', 'max', 'min'
    color_palette=None,
    point_size=10,
    point_shape="rect_vertical",     # 'circle', 'square', 'rect_vertical', 'rect_horizontal'
    title="",
)

Stacked Lines (Datashader)

chart = cuxfilter.charts.stacked_lines(
    x="time_col",
    y=["series_a", "series_b", "series_c"],   # List of y columns
    colors=["red", "green", "blue"],
)

Choropleth (Deck.gl — 2D and 3D maps)

chart = cuxfilter.charts.choropleth(
    x="zip_code",
    color_column="metric_col",
    color_aggregate_fn="mean",         # 'count', 'mean', 'sum', 'min', 'max', 'std'
    elevation_column="value_col",      # Set for 3D choropleth, omit for 2D
    elevation_factor=0.00001,
    elevation_aggregate_fn="sum",
    geoJSONSource="https://url/to/geojson",
    geo_color_palette=None,            # Default: Inferno256
    nan_color="#d3d3d3",
    tooltip=True,
    tooltip_include_cols=["zip_code", "metric_col"],
    title="",
)

Graph (Datashader — node-link diagrams)

chart = cuxfilter.charts.datashader.graph(
    node_x="x",                  # Default "x"
    node_y="y",                  # Default "y"
    node_id="vertex",            # Default "vertex"
    edge_source="source",        # Default "source"
    edge_target="target",        # Default "target"
    node_aggregate_col=None,
    node_color_palette=None,
    edge_color_palette=["#000000"],
    node_point_size=15,
    node_pixel_shade_type="eq_hist",
    edge_render_type="direct",   # 'direct' or 'curved' (curved is experimental)
    edge_transparency=0,         # [0, 1]
    tile_provider=None,
    title="",
    unselected_alpha=0.2,
)

Widgets

Widgets provide interactive filtering controls, typically placed in the sidebar.

Range Slider

widget = cuxfilter.charts.range_slider("numeric_col", step_size=1)

Date Range Slider

widget = cuxfilter.charts.date_range_slider("datetime_col")

Float Slider

widget = cuxfilter.charts.float_slider("float_col", step_size=0.5)

Int Slider

widget = cuxfilter.charts.int_slider("int_col", step_size=1)

Dropdown

widget = cuxfilter.charts.drop_down("category_col")

Multi-Select

widget = cuxfilter.charts.multi_select("category_col")

Number (KPI indicator)

widget = cuxfilter.charts.number(
    expression="column_name",                # Or a computed expression like "(x + y) / 2"
    aggregate_fn="mean",                     # 'count', 'mean', 'min', 'max', 'sum', 'std'
    title="Average Value",
    format="{value:.2f}",                    # Python format string
    colors=[(33, "green"), (66, "gold"), (100, "red")],  # Threshold coloring
    font_size="18pt",
)

Card (Markdown content)


widget = cuxfilter.charts.card(pn.pane.Markdown("## My Dashboard\
Some description text"))

Dashboard Creation

Create a dashboard by calling .dashboard() on a cuxfilter DataFrame:

# Define charts and widgets
chart1 = cuxfilter.charts.scatter(x="x_col", y="y_col")
chart2 = cuxfilter.charts.bar("category_col")
sidebar_widget = cuxfilter.charts.range_slider("value_col")
number_widget = cuxfilter.charts.number(expression="value_col", aggregate_fn="mean", title="Mean Value")

# Build dashboard
d = cux_df.dashboard(
    charts=[chart1, chart2],               # Main area charts
    sidebar=[sidebar_widget, number_widget],  # Sidebar widgets
    layout=cuxfilter.layouts.feature_and_base,
    theme=cuxfilter.themes.rapids_dark,
    title="My Dashboard",
    data_size_widget=True,                 # Show current data count
)

Adding charts after creation

new_chart = cuxfilter.charts.line("x_col", "y_col")
d.add_charts(charts=[new_chart])
# or
d.add_charts(sidebar=[cuxfilter.charts.card(pn.pane.Markdown("# Note"))])

Layouts

Preset Layouts

LayoutDescriptionCharts
layouts.single_featureOne chart fills the page1
layouts.feature_and_baseLarge chart on top, smaller below (66/33 split)2
layouts.double_featureTwo charts side-by-side2
layouts.left_feature_right_doubleOne large left, two stacked right3
layouts.triple_featureThree charts in a row3
layouts.feature_and_double_baseOne large top, two below3
layouts.two_by_two2x2 grid4
layouts.feature_and_triple_baseOne large top, three below4
layouts.feature_and_quad_baseOne large top, four below5
layouts.feature_and_five_edgeOne large center, five around6
layouts.two_by_three2x3 grid6
layouts.double_feature_quad_baseTwo large top, four below6
layouts.three_by_three3x3 grid9

Custom Layouts with layout_array

Use layout_array for full control. It's a list-of-lists where each inner list is a row, and numbers refer to chart indices (1-based):

# Chart 1 takes top-left 2x2 area, charts 2 and 3 on the right
d = cux_df.dashboard(
    charts_list,
    layout_array=[[1, 1, 2, 2], [1, 1, 3, 4]],
    theme=cuxfilter.themes.rapids_dark,
)

Rules:

  • Each number maps to a chart (1 = first chart, 2 = second, etc.)
  • Repeating a number across cells makes that chart span those cells
  • The array is auto-scaled to fit the screen

Themes

Four built-in themes:

ThemeDescription
cuxfilter.themes.defaultLight theme (default)
cuxfilter.themes.darkDark theme
cuxfilter.themes.rapidsRAPIDS-branded light theme
cuxfilter.themes.rapids_darkRAPIDS-branded dark theme
d = cux_df.dashboard(charts, theme=cuxfilter.themes.rapids_dark)

Dashboard Display and Export

Display inline in a notebook

d.app(sidebar_width=280, width=1200, height=800)

Display as a separate web app (opens new browser tab)

d.show()
# or with custom URL/port
d.show(notebook_url="http://localhost:8888", port=8050)

JupyterHub deployment

d.show(service_proxy="jupyterhub")

Stop the server

d.stop()

Export filtered data

After interacting with the dashboard (selecting ranges, filtering), export the current filtered DataFrame:

filtered_df = d.export()  # Returns cuDF DataFrame matching current filter state
# Also prints the query string, e.g.: "2 <= key <= 4"

Access dashboard charts

d.charts  # Dictionary of chart objects

Graph Visualization

cuxfilter integrates with cuGraph for interactive graph visualization:


# Create graph
edges = cudf.DataFrame({
    "source": [0, 0, 1, 1, 2],
    "target": [1, 2, 2, 3, 3]
})
G = cugraph.Graph()
G.from_cudf_edgelist(edges, destination="target")

# Load into cuxfilter (needs node positions — use force_atlas2 or similar layout)
positions = cugraph.force_atlas2(G)
nodes = positions.rename(columns={"vertex": "vertex", "x": "x", "y": "y"})

cux_df = cuxfilter.DataFrame.load_graph((nodes, G.edges()))

# Create graph chart
chart = cuxfilter.charts.datashader.graph(
    node_pixel_shade_type="linear",
    unselected_alpha=0.2,
)

d = cux_df.dashboard([chart], layout=cuxfilter.layouts.single_feature)
d.app()

Multi-GPU with Dask-cuDF

cuxfilter works seamlessly with dask_cudf.DataFrame — just pass it in place of a cuDF DataFrame:


ddf = dask_cudf.read_parquet("large_dataset/*.parquet")
cux_df = cuxfilter.DataFrame.from_dataframe(ddf)

# Everything else is the same
chart = cuxfilter.charts.scatter(x="x", y="y")
d = cux_df.dashboard([chart])
d.app()

Use dask_cudf when:

  • Data doesn't fit in a single GPU's memory
  • You want to distribute across multiple GPUs
  • Processing many files at once

Supported chart types with dask_cudf:

  • bokeh: bar, line
  • datashader: scatter, line, stacked_lines, heatmap, graph (limited edge rendering)
  • panel_widgets: all widgets
  • deckgl: choropleth (2D and 3D)

Interoperability

cuxfilter sits at the visualization layer of the RAPIDS ecosystem:

  • cuDF — The data layer. cuxfilter.DataFrame wraps cuDF DataFrames.
  • cuGraph — Graph analytics. Use cuxfilter.DataFrame.load_graph() to visualize cuGraph results.
  • cuML — Run cuML, then visualize results (e.g., UMAP embeddings, cluster assignments) with cuxfilter.
  • HoloViz ecosystem — Built on Panel, Bokeh, Datashader, and HoloViews.
  • Deck.gl — WebGL-powered choropleth maps.

Typical RAPIDS + cuxfilter pipeline


# Load and preprocess with cuDF
df = cudf.read_parquet("data.parquet")
df = df.dropna().reset_index(drop=True)

# Run ML with cuML (e.g., UMAP for dimensionality reduction)
from cuml.manifold import UMAP
umap = UMAP(n_components=2)
embedding = umap.fit_transform(df[["feature1", "feature2", "feature3"]])
df["umap_x"] = embedding[:, 0]
df["umap_y"] = embedding[:, 1]

# Visualize with cuxfilter
cux_df = cuxfilter.DataFrame.from_dataframe(df)
scatter = cuxfilter.charts.scatter(
    x="umap_x", y="umap_y",
    aggregate_col="cluster_label",
    aggregate_fn="mean",
    pixel_shade_type="linear",
)
bar = cuxfilter.charts.bar("cluster_label")
d = cux_df.dashboard([scatter, bar], layout=cuxfilter.layouts.feature_and_base)
d.