Skip to main content

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


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.

Metadata

Release files for viewdt 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for viewdt 1.1.0
File Size Uploaded
viewdt-1.1.0.tar.gz 35.8 kB Details

Release files / viewdt-1.1.0.tar.gz

Download URL viewdt-1.1.0.tar.gz
Size 35.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2561b0c8756859b6e9703c8d94144ef3793c47d1170fd11d97bd467e4d60e6fe
BLAKE2b-256 checksum
How to use checksums
dfe07a49cec300b1ae00128dea97b9a9f85d57c500db88029e722a5f3aa9e6e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.5

Release history Release notifications | RSS feed

This release

1.1.0 This release

1 release file

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page