This page only contains information on the st.data_editor API. For a deeper dive into working with dataframes and the data editor's capabilities and limitations, read Dataframes.

Display a data editor widget.

The data editor widget allows you to edit dataframes and many other data structures in a table-like UI.


When going from st.experimental_data_editor to st.data_editor in 1.23.0, the data editor's representation in st.session_state was changed. The edited_cells dictionary is now called edited_rows and uses a different format ({0: {"column name": "edited value"}} instead of {"0:1": "edited value"}). You may need to adjust the code if your app uses st.experimental_data_editor in combination with st.session_state."

Function signature[source]

st.data_editor(data, *, width=None, height=None, use_container_width=False, hide_index=None, column_order=None, column_config=None, num_rows="fixed", disabled=False, key=None, on_change=None, args=None, kwargs=None)


data (pandas.DataFrame, pandas.Series, pandas.Styler, pandas.Index, pyarrow.Table, numpy.ndarray, pyspark.sql.DataFrame, snowflake.snowpark.DataFrame, list, set, tuple, dict, or None)

The data to edit in the data editor.


Mixing data types within a column can make the column uneditable. Additionally, the following data types are not yet supported for editing: complex, list, tuple, bytes, bytearray, memoryview, dict, set, frozenset, datetime.timedelta, decimal.Decimal, fractions.Fraction, pandas.Interval, pandas.Period, pandas.Timedelta.

width (int or None)

Desired width of the data editor expressed in pixels. If None, the width will be automatically determined.

height (int or None)

Desired height of the data editor expressed in pixels. If None, the height will be automatically determined.

use_container_width (bool)

If True, set the data editor width to the width of the parent container. This takes precedence over the width argument. Defaults to False.

hide_index (bool or None)

Whether to hide the index column(s). If None (default), the visibility of index columns is automatically determined based on the data.

column_order (iterable of str or None)

Specifies the display order of columns. This also affects which columns are visible. For example, column_order=("col2", "col1") will display 'col2' first, followed by 'col1', and will hide all other non-index columns. If None (default), the order is inherited from the original data structure.

column_config (dict or None)

Configures how columns are displayed, e.g. their title, visibility, type, or format, as well as editing properties such as min/max value or step. This needs to be a dictionary where each key is a column name and the value is one of:

  • None to hide the column.
  • A string to set the display label of the column.
  • One of the column types defined under st.column_config, e.g. st.column_config.NumberColumn("Dollar values”, format=”$ %d") to show a column as dollar amounts. See more info on the available column types and config options here.

To configure the index column(s), use _index as the column name.

num_rows ("fixed" or "dynamic")

Specifies if the user can add and delete rows in the data editor. If "fixed", the user cannot add or delete rows. If "dynamic", the user can add and delete rows in the data editor, but column sorting is disabled. Defaults to "fixed".

disabled (bool or iterable of str)

Controls the editing of columns. If True, editing is disabled for all columns. If an iterable of column names is provided (e.g., disabled=("col1", "col2")), only the specified columns will be disabled for editing. If False (default), all columns that support editing are editable.

key (str)

An optional string to use as the unique key for this widget. If this is omitted, a key will be generated for the widget based on its content. Multiple widgets of the same type may not share the same key.

on_change (callable)

An optional callback invoked when this data_editor's value changes.

args (tuple)

An optional tuple of args to pass to the callback.

kwargs (dict)

An optional dict of kwargs to pass to the callback.


(pandas.DataFrame, pandas.Series, pyarrow.Table, numpy.ndarray, list, set, tuple, or dict.)

The edited data. The edited data is returned in its original data type if it corresponds to any of the supported return types. All other data types are returned as a pd.DataFrame.


import streamlit as st
import pandas as pd

df = pd.DataFrame(
       {"command": "st.selectbox", "rating": 4, "is_widget": True},
       {"command": "st.balloons", "rating": 5, "is_widget": False},
       {"command": "st.time_input", "rating": 3, "is_widget": True},
edited_df = st.data_editor(df)

favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
st.markdown(f"Your favorite command is **{favorite_command}** 🎈")

You can also allow the user to add and delete rows by setting num_rows to "dynamic":

import streamlit as st
import pandas as pd

df = pd.DataFrame(
       {"command": "st.selectbox", "rating": 4, "is_widget": True},
       {"command": "st.balloons", "rating": 5, "is_widget": False},
       {"command": "st.time_input", "rating": 3, "is_widget": True},
edited_df = st.data_editor(df, num_rows="dynamic")

favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
st.markdown(f"Your favorite command is **{favorite_command}** 🎈")

Or you can customize the data editor via column_config, hide_index, column_order, or disabled:

import pandas as pd
import streamlit as st

df = pd.DataFrame(
        {"command": "st.selectbox", "rating": 4, "is_widget": True},
        {"command": "st.balloons", "rating": 5, "is_widget": False},
        {"command": "st.time_input", "rating": 3, "is_widget": True},
edited_df = st.data_editor(
        "command": "Streamlit Command",
        "rating": st.column_config.NumberColumn(
            "Your rating",
            help="How much do you like this command (1-5)?",
            format="%d ⭐",
        "is_widget": "Widget ?",
    disabled=["command", "is_widget"],

favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
st.markdown(f"Your favorite command is **{favorite_command}** 🎈")

When working with data in Streamlit, the st.column_config class is a powerful tool for configuring data display and interaction. Specifically designed for the column_config parameter in st.dataframe and st.data_editor, it provides a suite of methods to tailor your columns to various data types - from simple text and numbers to lists, URLs, images, and more.

Whether it's translating temporal data into user-friendly formats or utilizing charts and progress bars for clearer data visualization, column configuration not only provides the user with an enriched data viewing experience but also ensures that you're equipped with the tools to present and interact with your data, just the way you want it.



Configure a generic column.

Column("Streamlit Widgets", width="medium", help="Streamlit **widget** commands 🎈")

Text column

Configure a text column.

TextColumn("Widgets", max_chars=50, validate="^st\.[a-z_]+$")

Number column

Configure a number column.

NumberColumn("Price (in USD)", min_value=0, format="$%d")

Checkbox column

Configure a checkbox column.

CheckboxColumn("Your favorite?", help="Select your **favorite** widgets")

Selectbox column

Configure a selectbox column.

SelectboxColumn("App Category", options=["🤖 LLM", "📈 Data Viz"])

Datetime column

Configure a datetime column.

DatetimeColumn("Appointment", min_value=datetime(2023, 6, 1), format="D MMM YYYY, h:mm a")

Date column

Configure a date column.

DateColumn("Birthday", max_value=date(2005, 1, 1), format="DD.MM.YYYY")

Time column

Configure a time column.

TimeColumn("Appointment", min_value=time(8, 0, 0), format="hh:mm a")

List column

Configure a list column.

ListColumn("Sales (last 6 months)", width="medium")

Configure a link column.

LinkColumn("Trending apps", max_chars=100, validate="^https://.*$")

Image column

Configure an image column.

ImageColumn("Preview Image", help="The preview screenshots")

Line chart column

Configure a line chart column.

LineChartColumn("Sales (last 6 months)" y_min=0, y_max=100)

Bar chart column

Configure a bar chart column.

BarChartColumn("Marketing spend" y_min=0, y_max=100)

Progress column

Configure a progress column.

ProgressColumn("Sales volume", min_value=0, max_value=1000, format="$%f")

Was this page helpful?

editSuggest edits

Still have questions?

Our forums are full of helpful information and Streamlit experts.