Hello!
Thank you to the dev team for making Streamlit, this is quite a brilliant, exiting and useful tool for data engineers who want to quickly and easily make front end app for data visualization.
I am wondering if there is a way to insert editable data table, such as the one in Dash.
It seems that editable datatable is a feature who does not exist in Plotly, so the plotly_chart() method won’t work.
This would indeed be an incredible feature. It would be very useful to be able to read pandas dataframes into a Streamlit table and allow that table to be point and click editable and then read the values out of that table back into a dataframe.
@sheridonx the way I am currently handling this problem is by displaying a Pandas dataframe and using the sliders and button presses to edit the table with whatever criteria is interesting. The only issue is you’ll need to do all of your sliding and editing in one swoop as Streamlit doesn’t appear to be able to persist when another widget is used (yet). See LINK
Hello,
to address your issue, I would consider using i/o systems to save the status after each click on button (by using pickle file for example) and reload your variables from the file at the beginning of your script.
This should work well if there will be at most one user on your app at the same time (which means there is no need to worry about multi-agent problems).
@sheridonx There is very frequently up to 5 people using the app at any given time. When I was testing for my own use that’s similar to what I was doing.
I’ve now remedied the issue by using a database… reading and writing as necessary.
Would still be best to be able to continually make changes to the dataframe and only read from the db at the beginning and write at the end.
@posey22 Absolutely.
I am also struggling to lay a streamlit project into Flask framework, like redirecting to a streamlit page by a flask view decorator…but I got totally no idea about it. Have you tried something similar?
@sheridonx So my application is mainly .NET and serves a handful of different analytics tools, my Streamlit pages being part of that. I just put a button on the pages where I list the various projects or tools you can visit. From there, I just redirect to wherever the streamlit project lives.
As for a Flask specific implementation, not sure I can help there, no experience with mixing streamlit and Flask. Maybe this will help?: LINK
Hey @sheridonx, thanks for checking out Streamlit, and for the kind words!
Editable data tables don’t currently exist in Streamlit. You can approximate them somewhat by using st.text_input and st.number_input to allow the user to enter values that you write back into your dataframe, like in this contrived example:
import streamlit as st
import numpy as np
import pandas as pd
# Randomly fill a dataframe and cache it
@st.cache(allow_output_mutation=True)
def get_dataframe():
return pd.DataFrame(
np.random.randn(50, 20),
columns=('col %d' % i for i in range(20)))
df = get_dataframe()
# Create row, column, and value inputs
row = st.number_input('row', max_value=df.shape[0])
col = st.number_input('column', max_value=df.shape[1])
value = st.number_input('value')
# Change the entry at (row, col) to the given value
df.values[row][col] = value
# And display the result!
st.dataframe(df)
But I imagine you’re after a more spreadsheet-like interface, where the user just directly edits the “cell” they’re interested in.
We don’t currently have this feature on the roadmap, but have been giving it some thought in a GitHub issue. If you’re interested, please feel free to upvote the issue and/or participate in the discussion!
Any idea if this will be implemented to have a more spreadsheet-like interface, where the user just directly edits the “cell” they’re interested in? (as you mentioned)
Guess you’re looking for solutions like Ag-grid or grid studio. People love the straightforwardness and interactive features. While these powerful features may need complex configurations. Anyway, if you like to play with javascript stuff, you will figure it out.
Hi! Thanks for the solution, what if we want to change more than one value? We’d have to save the file and read it again, right? but if we use file_uploader() we don’t have the name of the file… Is there an easy way to change more than one value?
Thaaanks!
For future references: Don’t use the solution provided by tim. It is still a workaround for a non-existent solution, but it is awful user experience since user will want to change both row and column, which will edit some unrelated parameters during the edit.
Great tool, but I try to keep the code within default anaconda imports since I’ll distribute it locally. I hope that developers can take your solution as a beta asap.
I think the key is to use st.session_state variable, it can be a dictionary. We can save a whole data frame into it. Then we can set default values of those text_input widgets (array) by this data frame.
We can also use Ag-Grid. It looks better if you like editable table. Remember to restore the values before you change the editable status of table.
import streamlit as st
import pandas as pd
from st_aggrid import AgGrid
if 'init' not in st.session_state: st.session_state['init']=False
if 'store' not in st.session_state: st.session_state['store']={}
if 'store_d' not in st.session_state: st.session_state['store_d']={}
if 'edit' not in st.session_state: st.session_state['edit']=True
if st.session_state.init == False:
st.session_state.store_d = {'A':[1,2,3,4], 'B':[7,6,5,4]}
st.session_state.init = True
@st.cache(allow_output_mutation=True)
def fetch_data():
return pd.DataFrame(st.session_state.store_d)
def saveDefault():
st.session_state.store_d = st.session_state.store
return
def app():
c1,c2=st.columns(2)
lock=c1.button('Lock', key='lock', on_click=saveDefault)
unlock=c2.button('Unlock', key='unlock', on_click=saveDefault)
if lock: st.session_state.edit = False
if unlock: st.session_state.edit = True
df = fetch_data()
ag = AgGrid(df, editable=st.session_state.edit, height=200)
df2=ag['data']
st.session_state.store=df2.to_dict()
st.dataframe(df2)
if __name__ == '__main__':
app()
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.