Advanced interactive data table widget for pandas DataFrames — Python port of the R ViewR viewdt() function
Project description
viewdt
Advanced interactive data table widget for pandas DataFrames — Python port of the R ViewR viewdt() function.
viewdt() transforms any pandas DataFrame into a high-performance, fully self-contained HTML explorer with zero browser-side dependencies. Column statistics are profiled in Python before the page renders, so the widget is fast even on large datasets.
Features
| Feature | Details |
|---|---|
| Type badges | # numeric A text T/F logical ⏱ datetime |
| Spark histograms | Inline SVG mini-charts in every column header |
| Completeness bars | Per-column fill-rate indicator (green / amber / red) |
| Column labels | Reads series.attrs["label"] — compatible with haven / ADaM clinical datasets |
| Virtualised grid | Renders only visible rows — handles hundreds of thousands of rows smoothly |
| Global search | Live cross-column text filter |
| Visual query builder | Multi-condition AND / OR filtering with type-aware operators |
| Data Insights drawer | Full histogram, descriptive stats, and category charts — click any column header |
| Column picker | Toggle column visibility at runtime |
| Code export | Generates pandas, Python, and SQL that reproduce the current filter state |
| Dark / light / auto theme | Follows the system preference by default; toggle at runtime |
| Standalone HTML | One self-contained file, no CDN or internet connection required |
Installation
pip install viewdt
Python 3.9+ and pandas 1.3+ are required. No JavaScript build step is needed.
Quick start
import pandas as pd
from viewdt import viewdt
df = pd.read_csv("sales.csv")
viewdt(df) # renders inline in Jupyter
viewdt(df).show() # opens in the default browser
viewdt(df).save("explorer.html") # exports a standalone file
Or explore one of the built-in sample datasets immediately:
from viewdt import viewdt, load_iris, load_mtcars, load_titanic
viewdt(load_iris()) # 150 rows — flower measurements
viewdt(load_mtcars()) # 32 rows — 1974 car specs
viewdt(load_titanic()) # 891 rows — survival data with missing values
API reference
viewdt(data, options=None, dataset_name=None)
Create an interactive data-explorer widget from a pandas DataFrame.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
data |
pd.DataFrame |
required | The DataFrame to explore |
options |
ViewdtOptions |
viewdt_options() |
Configuration object — see viewdt_options() below |
dataset_name |
str |
inferred | Variable name substituted in generated code. Auto-detected from the call site if omitted |
Returns ViewdtWidget
Widget methods
| Method | Description |
|---|---|
.show() |
Open the widget in the default web browser |
.save(path) |
Export to a standalone HTML file |
_repr_html_() |
Renders inline in Jupyter / VS Code notebooks automatically |
viewdt_options(**kwargs) → ViewdtOptions
Build a configuration object to pass to viewdt().
All parameters are keyword-only and have sensible defaults — pass only what you want to change.
from viewdt import viewdt, viewdt_options
viewdt(df, options=viewdt_options(
theme="dark",
hidden_columns=["internal_id", "created_at"],
hist_bins=30,
top_n=15,
))
Options reference
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
"auto" | "light" | "dark" |
"auto" |
UI colour scheme. "auto" follows the OS preference |
show_labels |
bool |
True |
Show variable labels from series.attrs["label"] |
histograms |
bool |
True |
Render spark-histograms / category bars in column headers |
missing_bars |
bool |
True |
Show the data-completeness bar at the bottom of each header |
type_badges |
bool |
True |
Show data-type badges in column headers |
insights |
bool |
True |
Enable the Data Insights drawer (click any column header) |
query_builder |
bool |
True |
Enable the visual query builder |
column_picker |
bool |
True |
Enable the column-visibility picker |
code_export |
bool |
True |
Enable the reproducible code generator |
global_search |
bool |
True |
Enable the global search box |
na_string |
str |
"NA" |
Text displayed for missing values |
hidden_columns |
list[str] | None |
None |
Columns hidden on initial render |
page_size |
int |
200 |
Rows kept in the virtualised DOM buffer |
hist_bins |
int |
20 |
Bin count for numeric / datetime histograms |
top_n |
int |
10 |
Number of categories profiled for text columns |
max_cells |
int |
5_000_000 |
Warn when nrow × ncol exceeds this threshold |
save_viewdt(data, path, options=None, dataset_name=None)
Convenience wrapper — profiles data and writes the widget directly to path.
from viewdt import save_viewdt
save_viewdt(df, "report.html")
save_viewdt(df, "report_dark.html", options=viewdt_options(theme="dark"))
Built-in datasets
Seven sample datasets are included — no internet connection required.
| Loader | Rows | Columns | Description |
|---|---|---|---|
load_iris() |
150 | 5 | Fisher's Iris flower measurements — setosa, versicolor, virginica |
load_mtcars() |
32 | 12 | Motor Trend Car Road Tests 1974 — mpg, hp, weight, transmission |
load_penguins() |
344 | 8 | Palmer Archipelago penguins — bill & flipper measurements (with NaNs) |
load_tips() |
244 | 7 | Restaurant tips — bill, tip, sex, smoker, day, time, party size |
load_gapminder() |
444 | 6 | Gapminder — country, continent, year, life expectancy, population, GDP |
load_titanic() |
891 | 9 | Titanic passengers — survival, class, sex, age (with NaNs), fare |
load_stocks() |
1260 | 4 | Daily closing prices — AAPL, GOOG, MSFT, AMZN, META (datetime column) |
from viewdt import (
viewdt, viewdt_options,
load_iris, load_mtcars, load_penguins,
load_tips, load_gapminder, load_titanic, load_stocks,
list_datasets,
)
# See all available datasets
viewdt(list_datasets())
# Iris — type badges, spark histograms, column labels
viewdt(load_iris())
# mtcars — all-numeric, code export
viewdt(load_mtcars(), options=viewdt_options(theme="dark"))
# Penguins — completeness bars (missing values in age, sex)
viewdt(load_penguins())
# Gapminder — try the query builder: continent = "Asia", year >= 1990
viewdt(load_gapminder())
# Titanic — filter survived = 1, pclass = 1 to explore first-class survivors
viewdt(load_titanic(), options=viewdt_options(hidden_columns=["name"]))
# Stocks — datetime column, time-series data
viewdt(load_stocks())
Examples
Dark theme with pre-hidden columns
from viewdt import viewdt, viewdt_options
viewdt(
df,
options=viewdt_options(
theme="dark",
hidden_columns=["row_id", "updated_at"],
),
)
Clinical / labelled data (haven / ADaM)
Column labels stored in series.attrs["label"] are shown below the column name in the header — the same behaviour as the R ViewR package with haven-imported datasets.
df["AVAL"].attrs["label"] = "Analysis Value"
df["PARAMCD"].attrs["label"] = "Parameter Code"
viewdt(df) # labels appear in every column header
Lightweight view — disable heavy features
viewdt(
df,
options=viewdt_options(
histograms=False,
insights=False,
query_builder=False,
),
)
Large DataFrames
# viewdt warns automatically when nrow × ncol > max_cells (default 5 M).
# Sample before exploring if needed:
viewdt(df.sample(50_000))
# Or raise the threshold:
viewdt(df, options=viewdt_options(max_cells=20_000_000))
Export to HTML for sharing
from viewdt import save_viewdt, viewdt_options
save_viewdt(
df,
"team_report.html",
options=viewdt_options(theme="light", code_export=False),
dataset_name="sales_q1",
)
Query builder operators
The visual query builder exposes type-appropriate operators for each column:
| Column type | Available operators |
|---|---|
| Numeric | = ≠ < ≤ > ≥ is null not null |
| Text | = ≠ contains !contains in !in is null not null |
| Logical | is true is false is null not null |
| Datetime | = < ≤ > ≥ is null not null |
The in / !in operators accept a comma-separated list of values in the input field.
Code export
The Code button generates reproducible code that matches the current filter state and column selection in three dialects:
pandas
mask = (
df['category'].isin(['A', 'B']) &
(df['price'] > 50)
)
df = df[mask]
df = df[['category', 'price', 'score']]
Python
import pandas as pd
result = df[
df['category'].isin(['A', 'B']) &
(df['price'] > 50)
]
result = result[['category', 'price', 'score']]
SQL
SELECT "category", "price", "score"
FROM "df"
WHERE "category" IN ('A', 'B')
AND "price" > 50;
Comparison with R ViewR
| Feature | R viewdt() |
Python viewdt() |
|---|---|---|
| Data input | data.frame / tibble |
pd.DataFrame |
| Column profiling | In R, before render | In Python, before render |
| Spark charts | SVG, vanilla JS | SVG, vanilla JS |
| Code export | dplyr / base R / SQL | pandas / Python / SQL |
| Column labels | label attribute (haven) |
series.attrs["label"] |
| Standalone output | htmlwidget |
ViewdtWidget → .save() |
| Jupyter support | via htmlwidgets |
via _repr_html_() |
| Dependencies | R packages | pandas, numpy |
| JS dependencies | None | None |
Development
git clone https://github.com/itsmdivakaran/viewdt-python
cd viewdt-python
pip install -e ".[notebook]"
Run the smoke test:
python -c "
import pandas as pd, numpy as np
from viewdt import viewdt
df = pd.DataFrame({'x': np.random.randn(100), 'y': list('ABCD') * 25})
viewdt(df).show()
"
License
MIT License — see LICENSE for details.
Author
Mahesh Divakaran
Research Scholar, Amity University Uttar Pradesh
- GitHub: github.com/itsmdivakaran
- ORCID: 0000-0002-3488-0857
- Email: imaheshdivakaran@gmail.com
Citation
If you use viewdt in academic work, please cite the original R package:
Divakaran M (2026). ViewR: Interactive Data Viewer, Filter, and Editor. R package version 0.2.0. https://itsmdivakaran.github.io/viewR/
BibTeX:
@Manual{ViewR,
title = {{ViewR}: Interactive Data Viewer, Filter, and Editor},
author = {Mahesh Divakaran},
year = {2026},
note = {R package version 0.2.0},
url = {https://itsmdivakaran.github.io/viewR/},
}
Acknowledgements
Python port of the ViewR R package
(CRAN).
The widget design, feature set, and viewdt_options() API are derived directly
from the R implementation by the same author.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file viewdt-1.1.0.tar.gz.
File metadata
- Download URL: viewdt-1.1.0.tar.gz
- Upload date:
- Size: 35.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2561b0c8756859b6e9703c8d94144ef3793c47d1170fd11d97bd467e4d60e6fe
|
|
| MD5 |
a6da1c6ed8015b953eadfe61c0c15431
|
|
| BLAKE2b-256 |
dfe07a49cec300b1ae00128dea97b9a9f85d57c500db88029e722a5f3aa9e6e1
|