Skill Tracer
Skills › Scientific Agent Skills › optimize-for-gpu › cuxfilter.md

cuxfilter.md

605 lines · skills/optimize-for-gpu/references/cuxfilter.md at 5f2bc03

Open on GitHub
1# cuxfilter Reference
2
3> Review: 2026-10-01. Code below is illustrative unless explicitly described as CPU-tested.
4> GPU execution, performance, GDS, and multi-GPU behavior require validation on target hardware.
5
6cuxfilter 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.
7
8> **Full documentation:** https://docs.rapids.ai/api/cuxfilter/stable/
9> **Version (stable):** 26.06.00 (final release)
10> **Repository:** https://github.com/rapidsai/cuxfilter
12> **⚠️ Project status: sunset.** cuxfilter has been sunset — **v26.06 is the final release** and no packages will be published for later RAPIDS releases (see [RSN 60](https://docs.rapids.ai/notices/rsn0060/)). The examples below target the isolated 26.06 API and are not a guarantee of compatibility with current dependencies; for new projects RAPIDS recommends composing dashboards directly from maintained libraries instead: **cuDF** for GPU data loading/aggregation plus **HoloViews / hvPlot / Datashader** for linked cross-filtering visualizations, served with **Panel**, Plotly Dash, Streamlit, or Bokeh.

cuxfilter Reference

Review: 2026-10-01. Code below is illustrative unless explicitly described as CPU-tested. GPU execution, performance, GDS, and multi-GPU behavior require validation on target hardware.

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.06.00 (final release) Repository: https://github.com/rapidsai/cuxfilter
⚠️ Project status: sunset. cuxfilter has been sunset — v26.06 is the final release and no packages will be published for later RAPIDS releases (see RSN 60). The examples below target the isolated 26.06 API and are not a guarantee of compatibility with current dependencies; for new projects RAPIDS recommends composing dashboards directly from maintained libraries instead: cuDF for GPU data loading/aggregation plus HoloViews / hvPlot / Datashader for linked cross-filtering visualizations, served with Panel, Plotly Dash, Streamlit, or Bokeh.
Raw lines 1 to 13
14## Table of Contents
161. [Installation and Setup](#installation-and-setup)
172. [Core Concepts](#core-concepts)
183. [DataFrame: Loading Data](#dataframe-loading-data)
194. [Charts](#charts)
205. [Widgets](#widgets)
216. [Dashboard Creation](#dashboard-creation)
227. [Layouts](#layouts)
238. [Themes](#themes)
249. [Dashboard Display and Export](#dashboard-display-and-export)
2510. [Graph Visualization](#graph-visualization)
2611. [Multi-GPU with Dask-cuDF](#multi-gpu-with-dask-cudf)
2712. [Interoperability](#interoperability)
2813. [Performance Tips](#performance-tips)
2914. [Common Patterns](#common-patterns)
31---

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

Raw lines 14 to 32
33## Installation and Setup
35Use `uv add` in standalone examples; follow the user's existing project package manager when one
36is already configured.
38```bash
39uv add --extra-index-url=https://pypi.nvidia.com "cuxfilter-cu12==26.6.*" # For CUDA 12.x
40uv add --extra-index-url=https://pypi.nvidia.com "cuxfilter-cu13==26.6.*" # For CUDA 13.x
41```
43Both install the final 26.06 release — no further updates will be published. cuxfilter wheels are also on PyPI directly, so the extra index is optional. cuxfilter depends on matching cuDF 26.06. Keep the entire legacy stack isolated from RAPIDS 26.08 and pandas 3.
45**Platform:** Linux and WSL2 only (no native macOS or Windows).
46**Requires:** NVIDIA GPU with CUDA 12.x or 13.x support, Python 3.11+.
48Verify:
49```python
50import cuxfilter
51import cudf
53df = cudf.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
54cux_df = cuxfilter.DataFrame.from_dataframe(df)
55print(cux_df.data.head()) # Should print GPU dataframe
56```
58---

Installation and Setup

Use uv add in standalone examples; follow the user's existing project package manager when one is already configured.

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

Both install the final 26.06 release — no further updates will be published. cuxfilter wheels are also on PyPI directly, so the extra index is optional. cuxfilter depends on matching cuDF 26.06. Keep the entire legacy stack isolated from RAPIDS 26.08 and pandas 3.

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

Verify:

import cuxfilter
import cudf

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

Raw lines 33 to 59
60## Core Concepts
62cuxfilter has five main modules:
641. **`cuxfilter.DataFrame`** — Wraps a cuDF DataFrame for dashboard use. Entry point for creating dashboards.
652. **`cuxfilter.DashBoard`** — The interactive dashboard object. Created from a DataFrame with charts.
663. **`cuxfilter.charts`** — Chart factory functions (bar, scatter, line, heatmap, choropleth, graph, widgets).
674. **`cuxfilter.layouts`** — Preset and custom layout configurations for chart arrangement.
685. **`cuxfilter.themes`** — Visual themes for dashboards (default, dark, rapids, rapids_dark).
70The workflow is always: **Load data → Create charts → Build dashboard → Display**.
72---

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.


Raw lines 60 to 73
74## DataFrame: Loading Data
76The `cuxfilter.DataFrame` is the starting point. It wraps a cuDF or dask_cudf DataFrame.

DataFrame: Loading Data

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

Raw lines 74 to 77
78### From a cuDF DataFrame (most common)
79```python
80import cudf
81import cuxfilter
83cudf_df = cudf.DataFrame({
84 "x": [0, 1, 2, 3, 4],
85 "y": [10.0, 11.0, 12.0, 13.0, 14.0],
86 "category": ["A", "B", "A", "B", "A"]
87})
88cux_df = cuxfilter.DataFrame.from_dataframe(cudf_df)
89```

From a cuDF DataFrame (most common)

import cudf
import cuxfilter

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)
Raw lines 78 to 90
91### From an Arrow file on disk
92```python
93cux_df = cuxfilter.DataFrame.from_arrow("data/my_dataset.arrow")
94```

From an Arrow file on disk

cux_df = cuxfilter.DataFrame.from_arrow("data/my_dataset.arrow")
Raw lines 91 to 95
96### From a graph (nodes + edges)
97```python
98import cugraph
100edges = cudf.DataFrame({"source": [0, 1, 2], "target": [1, 2, 3], "weight": [1.0, 2.0, 3.0]})
101G = cugraph.Graph()
102G.from_cudf_edgelist(edges, source="source", destination="target", edge_attr="weight")
103positions = cugraph.force_atlas2(G)
104cux_df = cuxfilter.DataFrame.load_graph((positions, edges))
105```
107Or directly from cuDF DataFrames:
108```python
109nodes = cudf.DataFrame({"vertex": [0, 1, 2, 3], "x": [0, 1, 2, 3], "y": [4, 4, 2, 6], "attr": [0, 1, 1, 1]})
110edges = cudf.DataFrame({"source": [0, 1, 2], "target": [1, 2, 3], "weight": [1.0, 2.0, 3.0]})
111cux_df = cuxfilter.DataFrame.load_graph((nodes, edges))
112```

From a graph (nodes + edges)

import cugraph

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, source="source", destination="target", edge_attr="weight")
positions = cugraph.force_atlas2(G)
cux_df = cuxfilter.DataFrame.load_graph((positions, 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))
Raw lines 96 to 113
114### Accessing the underlying data
115```python
116cux_df.data # The cuDF DataFrame
117cux_df.data["new_col"] = cux_df.data["x"] * 2 # Add columns before creating dashboard
118```
120---

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

Raw lines 114 to 121
122## Charts
124All 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.

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.

Raw lines 122 to 125
126### Bar Chart (Bokeh)
127```python
128chart = cuxfilter.charts.bar(
129 x="column_name", # Required: x-axis column
130 y=None, # Optional: y-axis column (defaults to count)
131 data_points=None, # Number of bins (None = nunique)
132 add_interaction=True, # Enable cross-filtering interaction
133 aggregate_fn="count", # 'count' or 'mean'
134 step_size=None, # Step size for range slider
135 title="", # Chart title
136 autoscaling=True, # Auto-scale y-axis on data update
138```

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
)
Raw lines 126 to 139
140### Line Chart (Bokeh)
141```python
142chart = cuxfilter.charts.line(
143 x="x_col",
144 y="y_col",
145 data_points=100,
146 add_interaction=True,
148```

Line Chart (Bokeh)

chart = cuxfilter.charts.line(
    x="x_col",
    y="y_col",
    data_points=100,
    add_interaction=True,
)
Raw lines 140 to 149
150### Scatter Plot (Datashader — handles millions of points)
151```python
152chart = cuxfilter.charts.scatter(
153 x="x_col",
154 y="y_col",
155 aggregate_col=None, # Column for color aggregation
156 aggregate_fn="count", # 'count', 'mean', 'max', 'min'
157 color_palette=None, # Bokeh palette or list of hex colors
158 point_size=15,
159 pixel_shade_type="eq_hist", # 'eq_hist', 'linear', 'log', 'cbrt'
160 pixel_density=0.5, # [0, 1], higher = denser
161 pixel_spread="dynspread", # 'dynspread' or 'spread'
162 tile_provider=None, # Map tile (e.g., "CartoLight" for geo data)
163 title="",
164 unselected_alpha=0.2, # Transparency of unselected points
166```

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
)
Raw lines 150 to 167
168### Heatmap (Datashader)
169```python
170chart = cuxfilter.charts.heatmap(
171 x="x_col",
172 y="y_col",
173 aggregate_col="value_col",
174 aggregate_fn="mean", # 'count', 'mean', 'max', 'min'
175 color_palette=None,
176 point_size=10,
177 point_shape="rect_vertical", # 'circle', 'square', 'rect_vertical', 'rect_horizontal'
178 title="",
180```

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="",
)
Raw lines 168 to 181
182### Stacked Lines (Datashader)
183```python
184chart = cuxfilter.charts.stacked_lines(
185 x="time_col",
186 y=["series_a", "series_b", "series_c"], # List of y columns
187 colors=["red", "green", "blue"],
189```

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"],
)
Raw lines 182 to 190
191### Choropleth (Deck.gl — 2D and 3D maps)
192```python
193chart = cuxfilter.charts.choropleth(
194 x="zip_code",
195 color_column="metric_col",
196 color_aggregate_fn="mean", # 'count', 'mean', 'sum', 'min', 'max', 'std'
197 elevation_column="value_col", # Set for 3D choropleth, omit for 2D
198 elevation_factor=0.00001,
199 elevation_aggregate_fn="sum",
200 geoJSONSource="https://url/to/geojson",
201 geo_color_palette=None, # Default: Inferno256
202 nan_color="#d3d3d3",
203 tooltip=True,
204 tooltip_include_cols=["zip_code", "metric_col"],
205 title="",
207```

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="",
)
Raw lines 191 to 208
209### Graph (Datashader — node-link diagrams)
210```python
211chart = cuxfilter.charts.datashader.graph(
212 node_x="x", # Default "x"
213 node_y="y", # Default "y"
214 node_id="vertex", # Default "vertex"
215 edge_source="source", # Default "source"
216 edge_target="target", # Default "target"
217 node_aggregate_col=None,
218 node_color_palette=None,
219 edge_color_palette=["#000000"],
220 node_point_size=15,
221 node_pixel_shade_type="eq_hist",
222 edge_render_type="direct", # 'direct' or 'curved' (curved is experimental)
223 edge_transparency=0, # [0, 1]
224 tile_provider=None,
225 title="",
226 unselected_alpha=0.2,
228```
230---

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,
)

Raw lines 209 to 231
232## Widgets
234Widgets provide interactive filtering controls, typically placed in the sidebar.

Widgets

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

Raw lines 232 to 235
236### Range Slider
237```python
238widget = cuxfilter.charts.range_slider("numeric_col", step_size=1)
239```

Range Slider

widget = cuxfilter.charts.range_slider("numeric_col", step_size=1)
Raw lines 236 to 240
241### Date Range Slider
242```python
243widget = cuxfilter.charts.date_range_slider("datetime_col")
244```

Date Range Slider

widget = cuxfilter.charts.date_range_slider("datetime_col")
Raw lines 241 to 245
246### Float Slider
247```python
248widget = cuxfilter.charts.float_slider("float_col", step_size=0.5)
249```

Float Slider

widget = cuxfilter.charts.float_slider("float_col", step_size=0.5)
Raw lines 246 to 250
251### Int Slider
252```python
253widget = cuxfilter.charts.int_slider("int_col", step_size=1)
254```

Int Slider

widget = cuxfilter.charts.int_slider("int_col", step_size=1)
Raw lines 251 to 255
256### Dropdown
257```python
258widget = cuxfilter.charts.drop_down("category_col")
259```

Dropdown

widget = cuxfilter.charts.drop_down("category_col")
Raw lines 256 to 260
261### Multi-Select
262```python
263widget = cuxfilter.charts.multi_select("category_col")
264```

Multi-Select

widget = cuxfilter.charts.multi_select("category_col")
Raw lines 261 to 265
266### Number (KPI indicator)
267```python
268widget = cuxfilter.charts.number(
269 expression="column_name", # Or a computed expression like "(x + y) / 2"
270 aggregate_fn="mean", # 'count', 'mean', 'min', 'max', 'sum', 'std'
271 title="Average Value",
272 format="{value:.2f}", # Python format string
273 colors=[(33, "green"), (66, "gold"), (100, "red")], # Threshold coloring
274 font_size="18pt",
276```

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",
)
Raw lines 266 to 277
278### Card (Markdown content)
279```python
280import panel as pn
281widget = cuxfilter.charts.card(pn.pane.Markdown("## My Dashboard\nSome description text"))
282```
284---

Card (Markdown content)

import panel as pn
widget = cuxfilter.charts.card(pn.pane.Markdown("## My Dashboard\nSome description text"))

Raw lines 278 to 285
286## Dashboard Creation
288Create a dashboard by calling `.dashboard()` on a cuxfilter DataFrame:
290```python
291# Define charts and widgets
292chart1 = cuxfilter.charts.scatter(x="x_col", y="y_col")
293chart2 = cuxfilter.charts.bar("category_col")
294sidebar_widget = cuxfilter.charts.range_slider("value_col")
295number_widget = cuxfilter.charts.number(expression="value_col", aggregate_fn="mean", title="Mean Value")
297# Build dashboard
298d = cux_df.dashboard(
299 charts=[chart1, chart2], # Main area charts
300 sidebar=[sidebar_widget, number_widget], # Sidebar widgets
301 layout=cuxfilter.layouts.feature_and_base,
302 theme=cuxfilter.themes.rapids_dark,
303 title="My Dashboard",
304 data_size_widget=True, # Show current data count
306```

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
)
Raw lines 286 to 307
308### Adding charts after creation
309```python
310new_chart = cuxfilter.charts.line("x_col", "y_col")
311d.add_charts(charts=[new_chart])
312# or
313d.add_charts(sidebar=[cuxfilter.charts.card(pn.pane.Markdown("# Note"))])
314```
316---

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"))])

Raw lines 308 to 317
318## Layouts
320### Preset Layouts
322| Layout | Description | Charts |
323|--------|-------------|--------|
324| `layouts.single_feature` | One chart fills the page | 1 |
325| `layouts.feature_and_base` | Large chart on top, smaller below (66/33 split) | 2 |
326| `layouts.double_feature` | Two charts side-by-side | 2 |
327| `layouts.left_feature_right_double` | One large left, two stacked right | 3 |
328| `layouts.triple_feature` | Three charts in a row | 3 |
329| `layouts.feature_and_double_base` | One large top, two below | 3 |
330| `layouts.two_by_two` | 2x2 grid | 4 |
331| `layouts.feature_and_triple_base` | One large top, three below | 4 |
332| `layouts.feature_and_quad_base` | One large top, four below | 5 |
333| `layouts.feature_and_five_edge` | One large center, five around | 6 |
334| `layouts.two_by_three` | 2x3 grid | 6 |
335| `layouts.double_feature_quad_base` | Two large top, four below | 6 |
336| `layouts.three_by_three` | 3x3 grid | 9 |

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
Raw lines 320 to 337
338### Custom Layouts with `layout_array`
340Use `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):
342```python
343# Chart 1 spans the left two columns; chart2 spans upper-right; charts3/4 are below
344d = cux_df.dashboard(
345 charts_list,
346 layout_array=[[1, 1, 2, 2], [1, 1, 3, 4]],
347 theme=cuxfilter.themes.rapids_dark,
349```
351Rules:
352- Each number maps to a chart (1 = first chart, 2 = second, etc.)
353- Repeating a number across cells makes that chart span those cells
354- The array is auto-scaled to fit the screen
356---

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 spans the left two columns; chart2 spans upper-right; charts3/4 are below
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

Raw lines 338 to 357
358## Themes
360Four built-in themes:
362| Theme | Description |
363|-------|-------------|
364| `cuxfilter.themes.default` | Light theme (default) |
365| `cuxfilter.themes.dark` | Dark theme |
366| `cuxfilter.themes.rapids` | RAPIDS-branded light theme |
367| `cuxfilter.themes.rapids_dark` | RAPIDS-branded dark theme |
369```python
370d = cux_df.dashboard(charts, theme=cuxfilter.themes.rapids_dark)
371```
373---

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)

Raw lines 358 to 374
375## Dashboard Display and Export

Dashboard Display and Export

Raw lines 375 to 376
377### Display inline in a notebook
378```python
379d.app(sidebar_width=280, width=1200, height=800)
380```

Display inline in a notebook

d.app(sidebar_width=280, width=1200, height=800)
Raw lines 377 to 381
382### Display as a separate web app (opens new browser tab)
383```python
384d.show()
385# or with custom URL/port
386d.show(notebook_url="http://localhost:8888", port=8050)
387```

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)
Raw lines 382 to 388
389### JupyterHub deployment
390```python
391d.show(service_proxy="jupyterhub")
392```

JupyterHub deployment

d.show(service_proxy="jupyterhub")
Raw lines 389 to 393
394### Stop the server
395```python
396d.stop()
397```

Stop the server

d.stop()
Raw lines 394 to 398
399### Export filtered data
400After interacting with the dashboard (selecting ranges, filtering), export the current filtered DataFrame:
402```python
403filtered_df = d.export() # Returns cuDF DataFrame matching current filter state
404# Also prints the query string, e.g.: "2 <= key <= 4"
405```

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"
Raw lines 399 to 406
407### Access dashboard charts
408```python
409d.charts # Dictionary of chart objects
410```
412---

Access dashboard charts

d.charts  # Dictionary of chart objects

Raw lines 407 to 413
414## Graph Visualization
416cuxfilter integrates with cuGraph for interactive graph visualization:
418```python
419import cuxfilter
420import cudf
421import cugraph
423# Create graph
424edges = cudf.DataFrame({
425 "source": [0, 0, 1, 1, 2],
426 "target": [1, 2, 2, 3, 3]
427})
428G = cugraph.Graph()
429G.from_cudf_edgelist(edges, source="source", destination="target")
431# Load into cuxfilter (needs node positions — use force_atlas2 or similar layout)
432positions = cugraph.force_atlas2(G)
433nodes = positions.rename(columns={"vertex": "vertex", "x": "x", "y": "y"})
435cux_df = cuxfilter.DataFrame.load_graph((nodes, edges))
437# Create graph chart
438chart = cuxfilter.charts.datashader.graph(
439 node_pixel_shade_type="linear",
440 unselected_alpha=0.2,
443d = cux_df.dashboard([chart], layout=cuxfilter.layouts.single_feature)
444d.app()
445```
447---

Graph Visualization

cuxfilter integrates with cuGraph for interactive graph visualization:

import cuxfilter
import cudf
import cugraph

# 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, source="source", 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, 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()

Raw lines 414 to 448
449## Multi-GPU with Dask-cuDF
451cuxfilter works seamlessly with `dask_cudf.DataFrame` — just pass it in place of a cuDF DataFrame:
453```python
454import dask_cudf
456ddf = dask_cudf.read_parquet("large_dataset/*.parquet")
457cux_df = cuxfilter.DataFrame.from_dataframe(ddf)
459# Everything else is the same
460chart = cuxfilter.charts.scatter(x="x", y="y")
461d = cux_df.dashboard([chart])
462d.app()
463```
465Use dask_cudf when:
466- Data doesn't fit in a single GPU's memory
467- You want to distribute across multiple GPUs
468- Processing many files at once
470**Supported chart types with dask_cudf:**
471- bokeh: bar, line
472- datashader: scatter, line, stacked_lines, heatmap, graph (limited edge rendering)
473- panel_widgets: all widgets
474- deckgl: choropleth (2D and 3D)
476---

Multi-GPU with Dask-cuDF

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

import dask_cudf

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)

Raw lines 449 to 477
478## Interoperability
480cuxfilter sits at the visualization layer of the RAPIDS ecosystem:
482- **cuDF** — The data layer. cuxfilter.DataFrame wraps cuDF DataFrames.
483- **cuGraph** — Graph analytics. Use `cuxfilter.DataFrame.load_graph()` to visualize cuGraph results.
484- **cuML** — Run cuML, then visualize results (e.g., UMAP embeddings, cluster assignments) with cuxfilter.
485- **HoloViz ecosystem** — Built on Panel, Bokeh, Datashader, and HoloViews.
486- **Deck.gl** — WebGL-powered choropleth maps.

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.
Raw lines 478 to 487
488### Typical RAPIDS + cuxfilter pipeline
489```python
490import cudf
491import cuml
492import cuxfilter
494# Load and preprocess with cuDF
495df = cudf.read_parquet("data.parquet")
496df = df.dropna().reset_index(drop=True)
498# Run ML with cuML (e.g., UMAP for dimensionality reduction)
499from cuml.manifold import UMAP
500umap = UMAP(n_components=2, output_type="cupy")
501embedding = umap.fit_transform(df[["feature1", "feature2", "feature3"]])
502df["umap_x"] = embedding[:, 0]
503df["umap_y"] = embedding[:, 1]
504# This illustrative input must also contain a cluster_label column for the charts below.
506# Visualize with cuxfilter
507cux_df = cuxfilter.DataFrame.from_dataframe(df)
508scatter = cuxfilter.charts.scatter(
509 x="umap_x", y="umap_y",
510 aggregate_col="cluster_label",
511 aggregate_fn="mean",
512 pixel_shade_type="linear",
514bar = cuxfilter.charts.bar("cluster_label")
515d = cux_df.dashboard([scatter, bar], layout=cuxfilter.layouts.feature_and_base)
516d.app()
517```
519---

Typical RAPIDS + cuxfilter pipeline

import cudf
import cuml
import cuxfilter

# 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, output_type="cupy")
embedding = umap.fit_transform(df[["feature1", "feature2", "feature3"]])
df["umap_x"] = embedding[:, 0]
df["umap_y"] = embedding[:, 1]
# This illustrative input must also contain a cluster_label column for the charts below.

# 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.app()

Raw lines 488 to 520
521## Performance Tips
5231. **Keep data on GPU.** Load with `cudf.read_parquet()` or `cudf.read_csv()`, then wrap with `cuxfilter.DataFrame.from_dataframe()`. Avoid converting to/from pandas.
5252. **Use appropriate chart types for data size:**
526 - < 10K points: Bokeh charts (bar, line) work well
527 - 10K–100M+ points: Datashader charts (scatter, heatmap) handle large datasets efficiently via server-side rasterization
5293. **Limit data_points for bar charts.** For columns with many unique values, set `data_points` to bin them (e.g., `bar("col", data_points=50)`).
5314. **Use `float32` when possible.** GPU operations are faster with 32-bit floats. Cast before loading: `df["col"] = df["col"].astype("float32")`.
5335. **Pre-compute derived columns** before creating the dashboard, not inside chart callbacks.
5356. **Use `layout_array`** for complex dashboards to control exactly where each chart appears.
5377. **Increase `timeout`** for datashader charts if zooming feels laggy on very large datasets.
539---

Performance Tips

  1. Keep data on GPU. Load with cudf.read_parquet() or cudf.read_csv(), then wrap with cuxfilter.DataFrame.from_dataframe(). Avoid converting to/from pandas.
  1. Use appropriate chart types for data size:
  2. < 10K points: Bokeh charts (bar, line) work well
  3. 10K–100M+ points: Datashader charts (scatter, heatmap) handle large datasets efficiently via server-side rasterization
  1. Limit data_points for bar charts. For columns with many unique values, set data_points to bin them (e.g., bar("col", data_points=50)).
  1. **Use float32 when possible.** GPU operations are faster with 32-bit floats. Cast before loading: df["col"] = df["col"].astype("float32").
  1. Pre-compute derived columns before creating the dashboard, not inside chart callbacks.
  1. **Use layout_array** for complex dashboards to control exactly where each chart appears.
  1. **Increase timeout** for datashader charts if zooming feels laggy on very large datasets.

Raw lines 521 to 540
541## Common Patterns

Common Patterns

Raw lines 541 to 542
543### Exploratory data analysis dashboard
544```python
545import cudf
546import cuxfilter
548df = cudf.read_parquet("dataset.parquet")
549cux_df = cuxfilter.DataFrame.from_dataframe(df)
551# Overview charts
552scatter = cuxfilter.charts.scatter(x="feature1", y="feature2", pixel_shade_type="linear")
553hist1 = cuxfilter.charts.bar("feature1", data_points=50)
554hist2 = cuxfilter.charts.bar("category")
556# Sidebar filters
557slider = cuxfilter.charts.range_slider("value_col")
558dropdown = cuxfilter.charts.drop_down("category")
559kpi = cuxfilter.charts.number(expression="value_col", aggregate_fn="mean", title="Mean Value")
561d = cux_df.dashboard(
562 [scatter, hist1, hist2],
563 sidebar=[slider, dropdown, kpi],
564 layout=cuxfilter.layouts.feature_and_double_base,
565 theme=cuxfilter.themes.rapids_dark,
566 title="Data Explorer",
568d.app()
569```

Exploratory data analysis dashboard

import cudf
import cuxfilter

df = cudf.read_parquet("dataset.parquet")
cux_df = cuxfilter.DataFrame.from_dataframe(df)

# Overview charts
scatter = cuxfilter.charts.scatter(x="feature1", y="feature2", pixel_shade_type="linear")
hist1 = cuxfilter.charts.bar("feature1", data_points=50)
hist2 = cuxfilter.charts.bar("category")

# Sidebar filters
slider = cuxfilter.charts.range_slider("value_col")
dropdown = cuxfilter.charts.drop_down("category")
kpi = cuxfilter.charts.number(expression="value_col", aggregate_fn="mean", title="Mean Value")

d = cux_df.dashboard(
    [scatter, hist1, hist2],
    sidebar=[slider, dropdown, kpi],
    layout=cuxfilter.layouts.feature_and_double_base,
    theme=cuxfilter.themes.rapids_dark,
    title="Data Explorer",
)
d.app()
Raw lines 543 to 570
571### Geospatial dashboard with scatter on map tiles
572```python
573chart = cuxfilter.charts.scatter(
574 x="x_mercator", # Preproject longitude/latitude to EPSG:3857 meters
575 y="y_mercator",
576 aggregate_col="value",
577 aggregate_fn="mean",
578 color_palette=["#3182bd", "#6baed6", "#ff0068"],
579 tile_provider="CartoLight",
580 pixel_shade_type="linear",
581 title="Geo Scatter",
583```

Geospatial dashboard with scatter on map tiles

chart = cuxfilter.charts.scatter(
    x="x_mercator",  # Preproject longitude/latitude to EPSG:3857 meters
    y="y_mercator",
    aggregate_col="value",
    aggregate_fn="mean",
    color_palette=["#3182bd", "#6baed6", "#ff0068"],
    tile_provider="CartoLight",
    pixel_shade_type="linear",
    title="Geo Scatter",
)
Raw lines 571 to 584
585### Time series dashboard
586```python
587line_chart = cuxfilter.charts.line("timestamp", "metric")
588bar_chart = cuxfilter.charts.bar("hour_of_day")
589date_slider = cuxfilter.charts.date_range_slider("timestamp")
591d = cux_df.dashboard(
592 [line_chart, bar_chart],
593 sidebar=[date_slider],
594 layout=cuxfilter.layouts.feature_and_base,
596```

Time series dashboard

line_chart = cuxfilter.charts.line("timestamp", "metric")
bar_chart = cuxfilter.charts.bar("hour_of_day")
date_slider = cuxfilter.charts.date_range_slider("timestamp")

d = cux_df.dashboard(
    [line_chart, bar_chart],
    sidebar=[date_slider],
    layout=cuxfilter.layouts.feature_and_base,
)
Raw lines 585 to 597
598### Export filtered subset for further analysis
599```python
600# After user interacts with dashboard, export current selection
601d.app()
602# ... user filters data in the dashboard ...
603filtered = d.export() # cuDF DataFrame of currently visible/selected data
604# Continue analysis with cuDF, cuML, etc.
605```

Export filtered subset for further analysis

# After user interacts with dashboard, export current selection
d.app()
# ... user filters data in the dashboard ...
filtered = d.export()  # cuDF DataFrame of currently visible/selected data
# Continue analysis with cuDF, cuML, etc.
Raw lines 598 to 605