Lattice Grid Buy a licence

blog

An editable grid for your pandas DataFrame

Building…
Loading a live grid…

Data teams live in notebooks. You load a frame, you print it, and you get a wall of text you cannot sort, cannot filter, and certainly cannot edit. To change a single value you drop back into code, rerun the cell, and print it again. The DataFrame is the thing you are working on, and the one thing you cannot do is touch it.

Lattice Grid brings the grid to Python. Point it at a pandas DataFrame and you get an interactive, editable grid right there in the notebook: scroll it, sort a column, open a filter, and double-click a cell to change a value. Every edit flows straight back into the DataFrame, and the value comes back typed, so a number stays a number and a date stays a date. There is no export step and no second copy to keep in step by hand. The grid above is that same grid, running in the page you are reading.

Hello grid, in a notebook

import pandas as pd
from lattice_grid_jupyter import LatticeGridWidget

df = pd.DataFrame({"name": ["Ada", "Grace"], "score": [91, 88]})
grid = LatticeGridWidget(df)   # evaluate the widget in a cell to render it
grid                           # the interactive grid appears in the notebook

grid.df                        # the live DataFrame, reflecting your edits
grid.apply_edit(key="0", col_id="score", value=100)   # set one cell from Python

Evaluate the widget on the last line of a cell and the notebook draws it. From then on grid.df is the live frame: it already carries anything you changed in the grid, cast to the column’s dtype, so an integer column stays an integer rather than a string you would have to parse. You can drive the grid from code as well, and it repaints to match. apply_edit sets one cell by its row key and column, append_rows adds rows and hands you their new keys, delete_rows removes rows by key, and set_data swaps in a whole new frame. Edit in the grid or edit in code: the frame and the grid stay in step either way.

A real grid component for Dash

The same grid drops into a Dash app as a component, so a dashboard gets a table your users can actually work in rather than one they can only read. Hand it a DataFrame, turn editing on, and wire one callback: a committed edit arrives at the cellChanged output, apply_cell_edit applies it to the server-side frame with the column’s dtype preserved, and the updated frame flows back to the grid. The DataFrame on the server and the grid in the browser stay in step, typed, with one round trip and no bespoke table code to maintain.

Three packages, one grid

There are three packages, and which one you install depends on how you work. lattice-grid-jupyter is the notebook widget. lattice-grid-dash is the Dash component. Both sit on lattice-grid-pandas, the shared layer that turns a DataFrame into the grid’s data and casts an edit back to the right dtype, so the type handling is identical whichever way you render. Install the one that fits:

pip install lattice-grid-jupyter
pip install lattice-grid-dash

Each command pulls in everything it needs, including the shared pandas layer, so there is nothing else to wire up. You need Python 3.9 or newer and pandas 1.5 or newer, and on your own machine the grid renders with no key.

The same grid, wherever it runs

This is the same grid engine that powers the JavaScript product, delivered to Python. The grid’s front-end code ships inside the wheel, so it works offline with no build step and no request to a content delivery network when a cell or a dashboard renders. Whether you are in a notebook on a laptop with no connection or behind a firewall that blocks outside traffic, the grid is already there.

Who reaches for which

An analyst exploring data reaches for the notebook widget, because the work happens in cells and the frame is right there to poke at. A team building a dashboard reaches for the Dash component, because the grid belongs in the app everyone opens rather than in one person’s notebook. A web developer building a product reaches for the JavaScript grid directly. All three are the same grid, so a filter, a sort, an edit and a typed column behave the same wherever you meet them.

Start with the Python data grid overview, follow the get started guide to have one running in a few minutes, and keep the Python reference open for every argument and method. The packages live on PyPI: lattice-grid-jupyter, lattice-grid-dash and lattice-grid-pandas.

Read next

  • A grid over DuckDB, in the browser

    Point Lattice Grid at a duckdb-wasm connection and it pushes filter, sort and paging down, and gets whole-dataset stats by pulling the set in or pushing the aggregation to DuckDB.

  • The table is the schema

    htmx renders the table on the server; Lattice Grid upgrades it into a live grid in place, columns and rows read straight from the markup, and it survives htmx swaps.

  • Swap the import

    A compatibility layer gives Lattice Grid the shape of dhtmlx's dhx.Grid, so the constructor, the data and selection namespaces and the events keep working. Swap the import.

All posts RSS