Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Coming soon] Ability to accept input from Charts, Tables, etc. #455

Closed
tvst opened this issue Oct 18, 2019 · 114 comments · Fixed by #8302
Closed

[Coming soon] Ability to accept input from Charts, Tables, etc. #455

tvst opened this issue Oct 18, 2019 · 114 comments · Fixed by #8302
Labels
area:events feature:charts Related to charting functionality feature:st.dataframe status:in-progress We're on it! type:enhancement Requests for feature enhancements or new features

Comments

@tvst
Copy link
Contributor

tvst commented Oct 18, 2019

What if every output element could also serve as an input widget?

Then you could do things like:

  • User clicks on chart datapoint → python script receives the value for that data point and does something with it
  • User zooms into a chart → python script receives the new zoom bounds and does something with it
  • User clicks on dataframe rows → python script receives row index and does something with it
  • User click on two points on an image → python script draws a rectangle touching those points
  • User edits a row on a dataframe → python script receives the new dataframe

Related discussions:


Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.

If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.

Visits

@tvst tvst added type:enhancement Requests for feature enhancements or new features spec needed labels Oct 18, 2019
@MarcSkovMadsen
Copy link

Eventually you will be building that kind of functionality (is my guess). Very much needed to provide awesome interactivity. :-)

@markopy
Copy link

markopy commented Oct 18, 2019

Other issues that depend on having this kind of functionality: #298 #271

@tvst tvst changed the title Ability to accept input from Charts and Tables Ability to accept input from Charts, Tables, etc. Oct 20, 2019
@tvst
Copy link
Contributor Author

tvst commented Oct 20, 2019

Another one: ability to get the time from an audio widget. See forum thread here.

@treuille
Copy link
Contributor

If you want to select rows in a table, you can use this somewhat inelegant workaround, which will scale up to about 1000 rows or so. 👍

@MarcSkovMadsen
Copy link

Here is just my few cents.

If we supported the ipywidgets then we would also get access to the awesome qgrid/ slickgrid.

That grid is really great to read, sort and filter. And it's fast. But I guess the looks of it is not very Streamlit like.

@MarcSkovMadsen
Copy link

MarcSkovMadsen commented Nov 5, 2019

You can see plotly's new FigureWidget in action here and how it plays well with the ipywidgets and supports call backs.

https://plot.ly/python/figurewidget/
https://plot.ly/python/figurewidget-app/

@rmitsch
Copy link

rmitsch commented Nov 19, 2019

That would be a great feature, since it might allow to support brushing & linking between charts in streamlit apps. For reference, dc.js is a cool JS chart framework that focuses on getting exactly this kind of interaction/dependency between multiple charts right (example). That kind of functionality would be awesome in streamlit.

@torwag
Copy link

torwag commented Dec 6, 2019

Esp. Tables as inputs or resp. changeable, like a spreadsheet, would allow using streamlit.io as a replacement for a lot of excel-file based solutions, which are floating around in the millions in cooperate settings.
Streamlit.io would enable a programmer to really get the logic right, access databases, transfer data, have sanity checks, etc. using pandas resp. python in a single file, but still allows everyone to contribute or change data of that "online-spreadsheet"-system.

@treuille
Copy link
Contributor

treuille commented Dec 9, 2019

@torwag : I think this is a super valid use case. Can you please tell me a bit more about the setup you envision. Would you want only a single "spreadsheet" (i.e. table), or would you want graphs etc? Do you want widgets / sidebar? Also, what industry are you working in? Thanks!

@torwag
Copy link

torwag commented Dec 11, 2019

@treuille My vision would be to have all possibilities, like graphs, buttons, sliders etc. but also have editable tables, thus people can contribute data to it. Possibilities are endless.
From inventory where people type in the stock amount to annotation of medical data.

I am in an university setting, and here we would have both academic and administrative use for such a solution. E.g. staff and lecture dashboards to show all kind of information on a single page. But enable the user to make inputs where necessary.

@hcoohb
Copy link

hcoohb commented Dec 17, 2019

I would love also to have the output from a selection on a graph.
Plotly allows to select certain points, and I wish I could use this as a input for some other graphs displaying more details...

@tvst
Copy link
Contributor Author

tvst commented Dec 19, 2019

Just a quick update: we're currently brainstorming a few other features that touch on this one, so it would be great to hear some more use cases from you all, to better inform our discussion.

Even better if you provide a tiny toy example with some arbitrary API! For example:

st.write("Pick a user to edit")

# In this example, st.Table (with capital T) returns an object with properties you can use.
# This is not something that exists today. Just one of the many possible APIs for this...
table = st.Table(users_table)

if table.selected_row is not None:
  user = users_table[table.selected_row]
  show_editor(user)

@MarcSkovMadsen
Copy link

MarcSkovMadsen commented Dec 19, 2019

But if the functionality at its core could be based on being able to subscribe to any event. That would be very powerfull. The core functionality could then be wrapped into a simpler api for tables, charts etc.

With Dash you can add a callback to any kind of event. In Panel you can do reactive programming in Python using Streams. And here is an example of a Stream from the front end http://holoviews.org/reference/streams/bokeh/RangeXY.html. That concept is really powerfull but maybe too much for Streamlit?

@mstump
Copy link

mstump commented Dec 19, 2019

I'm interjecting as a hopeful user of streamlit, we're evaluating a transition from Bokeh which uses slick-grid as it's table implementation. If you do decide to introduce an editable datatable can we add ag-grid to the evaluation list? Slickgrid is not very attractive, has a number of bugs related to sortable grouped columns, and has odd editing behavior where cell state for drop-down columns isn't retained until you switch focus away from the cell. There are some working python bindings for ag-grid which may be a good starting point.

@MarcSkovMadsen
Copy link

Here is a an example use case from a user https://discuss.streamlit.io/t/plotly-click-events-in-streamlit/1419

@treuille
Copy link
Contributor

@mstump : Thanks for putting ag-grid on our radar. It looks pretty sweet!

@treuille
Copy link
Contributor

Thanks for providing that context, @MarcSkovMadsen! My current though (happy to be convinced otherwise) is that @tvst's suggestion above would allow us to integrate this kind of table selection (or point selection, respectively) within Streamlit's event model.

The main advantage of this approach is simpler state handling, since the user doesn't need to think about explicitly mutating program state.

The main disadvantage is performance (for now).

Are there are things I'm missing?

@treuille
Copy link
Contributor

Oh, and happy new year! 🎆

@adamkgoldfarb
Copy link

Just chiming in that the geospatial use case is pretty apparent: if one could take the st.Table's selections and then set an opacity/color on a scatter mark or polygon with those selections, that would be immediately useful for visualizing subsets of your geospatial data. Here's to hoping that the API feeds nicely into the emerging pydeck integration!

@katsou55
Copy link

katsou55 commented Jan 13, 2020

Hey guys, my 2 cents: another use case you might consider in the industry is data annotation. I have a webapp made of Jupyter + ipywidgets + qgrid + voila that currently allows not only my stakeholders to navigate and explore the data but most importantly, they can annotate data. Also, I have a section to serve "low confident" predictions and downstream improve my models, i.e. active learning.

Therefore, IMHO considering something like qgrid may add plenty of value to Streamlit (ps: that's why I am still using this stack instead of streamlit 😅)

Recap, 2 great use case for qgrid are:

  • data annotation
  • active learning (for tabular or text data)

Hope it helps, cheers!

@dansbecker
Copy link

Another use case for selection in tables:

I'd like to use rows in a table to control what I graph elsewhere in my app (roughly what you'd get if you could embed an st.checkbox in each row of an st.table.)

Forum post about it here

@erwindassen
Copy link

Another tool that could make this feature request easier to implement would be to use d-tale: https://pypi.org/project/dtale/ It uses flask as a back-end and already integrates with jupyter so perhaps with some hacking it could take care of all interface elements with the dataframe inside streamlit? Just throwing ideas here.

@SimonBiggs
Copy link
Contributor

SimonBiggs commented Apr 16, 2020

An amazing editable react table/spreadsheet widget is the following:

https://blueprintjs.com/docs/#table/features.editing

Also an example of an editable table in a streamlit like project is the following:

https://mybinder.org/v2/gh/SimonBiggs/scriptedforms-examples/master?urlpath=scriptedforms/use/detailed-example.md (scroll down to the "table variables" heading)

Mentioned these in the following issue, but I'm going to close that one, as here is likely the best place for that.

#1345

@rsheftel
Copy link

There has been discussion of aggrid here and I use that in Jupyter Notebooks they are beautiful, and allow a wide range of functionality as well as fast.

There is a package of python bindings to wrap it here:

https://dgothrek.gitlab.io/ipyaggrid/

@Laksh1997
Copy link

Keen to see this feature manifest

@SimonBiggs
Copy link
Contributor

SimonBiggs commented Apr 8, 2024

Bike shedding:

For # 1 what about rerun_on_select=True

@Chiyun-Lee
Copy link

Amazing stuff! Really looking forward to the release of the experimental version!

@lukefullard
Copy link

lukefullard commented Apr 9, 2024

So cool, thank you!
Would the proposed API also work with plotly scatterplots on maps?

https://plotly.com/python/scatter-plots-on-maps/

@jrieke
Copy link
Collaborator

jrieke commented Apr 9, 2024

Would the proposed API also work with plotly scatterplots on maps?

Yup!

CleanShot.2024-04-09.at.21.56.31.mp4

@jrieke
Copy link
Collaborator

jrieke commented Apr 9, 2024

For # 1 what about rerun_on_select=True

We want to keep it aligned with the on_change parameters we have on input widgets today, that's why we went for on_select. In the future, we want port the on_change parameters to use the same pattern as on_select, so you can both enable/disable change events on input widgets as well as pass a callback.

@benlindsay
Copy link

I also would have liked something a little clearer like rerun_on_select=True. If we're constrained to using on_select, then I highly prefer on_select="rerun" over on_select=True. Makes it clearer what to expect.

Thanks for all the work on this! very exciting

@mattbgdata
Copy link

dataframe selections

This is amazing and exactly what we need. What are some rough timeframes for this bad boy to be released?

@allocater2
Copy link

allocater2 commented Apr 23, 2024

The proposed solution is very laggy. It takes up to 1 second for the click to be processed.

How many solutions are there by now? Do all streamlit-based solutions have this issue because of the rerun-architecture? If yes, then this is probably the sign that if you want a responsive app you should switch from streamlit+plotly to javascript+plotly.

edit: I deployed the wheel file to the github codespace and running it from the github code space is actually not that laggy. But I have not figured out how to deploy it to the streamlit.app space that is connected to the github codespace. streamlit.app still uses the old/current streamlit and not the new wheel version.

edit2: To clarify, after doing:

pip install streamlit-1.32.2-py2.py3-none-any.whl

There are actually 3 ways to test it in a github codespace:

  1. In the simple browser inside the codespace page, next to the code (does not work)
  2. In the terminal, starting streamlit run Hello.py (works)
  3. In the real webpage on xxx.streamlit.app (does not work)

edit3: Now it also works in the side-browser for some reason. I have streamlit==1.32.2 in the requirements.txt

@jrieke
Copy link
Collaborator

jrieke commented Apr 24, 2024

This is amazing and exactly what we need. What are some rough timeframes for this bad boy to be released?

Probably mid May, you can follow for updates on #688!

@jrieke
Copy link
Collaborator

jrieke commented Apr 24, 2024

@allocater2 We have some documentation on how to commit changes from Codespaces and make them show up in your deployed app. In your case, you'd probably want to upload the wheel file to your repo directly and then install that as a local file via requirements.txt.

About reruns: Yes, that's the basic concept of Streamlit, it always reruns your app from top to bottom upon user interactions. In most cases, that shouldn't be too laggy, unless you're e.g. doing expensive computations. If your app feels slow, I'd recommend you to look at fragments (a way to rerun only part of your app) and caching (a way to cache expensive computations).

@Chiyun-Lee
Copy link

Mid-May! Perfect timing for our publication - keep it up team! Can't wait 🙏

@allocater2
Copy link

allocater2 commented Apr 29, 2024

Thanks, that worked. I have this in the requirements.txt now:

#streamlit==1.32.2
./streamlit-1.32.2-py2.py3-none-any.whl

We'll see how slow it is with the data I want to use. Thankfully it only has to run locally and not on the web. The web is just for collaboration.

willhuang1997 added a commit that referenced this issue Apr 29, 2024
## Describe your changes

Adds selection support to `st.plotly_chart` that can be used via:

```python
selections = st.plotly_chart(fig, on_select="rerun", selection_mode=("box", "points"))
```

## GitHub Issue Link (if applicable)

- Related: #455
- Closes #5902
- Closes #8244
- Closes #8169
- Closes #7597
- Closes #6324
- Closes #8575
- Closes #8576

## Testing Plan

- Implemented e2e and unit tests.

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

---------

Co-authored-by: Lukas Masuch <[email protected]>
Co-authored-by: William Wei Huang <[email protected]>
@SimonBiggs
Copy link
Contributor

SimonBiggs commented May 1, 2024

We'll see how slow it is with the data I want to use.

Hi @allocater2, I can confirm with @jrieke, just because Streamlit "always reruns from the top" that doesn't have to equate to "slow".

The "always rerun from the top" means that the execution model is simple to reason about (which is a huge plus), and with appropriate caching of the key load bearing items many steps do not need to rerun.

In practice I have found that I have never hit an issue where Streamlit rerun speed has became a limiting factor in the applications I have built when using the appropriate caching approaches.

@Glypican
Copy link

Glypican commented May 9, 2024

I tried streamlit-1.32.2-py2.py3-none-any.whl and it doesn't appear to capture click events for plotly heatmaps. I tried both px.imshow and go.Heatmap - I'm guessing this is because click event =/= select event.

@LukasMasuch
Copy link
Collaborator

@Glypican yep, the current implementation will only capture select events and no click events :(

@allocater2
Copy link

Does the new method work for "select" or "pick" events for a pydeck_chart? Or is there another method for pydeck_chart?

@LukasMasuch
Copy link
Collaborator

@allocater2 with the 1.35, we will add selections to plotly, altair, vega_lite_chart, and dataframe. Selections for pydeck_chart will be added in a later release.

LukasMasuch added a commit that referenced this issue May 13, 2024
## Describe your changes

This PR adds row and column selection support to `st.dataframe`. It can
be used like this:

```python
selection = st.dataframe(
    df,
    on_select="rerun",
    selection_mode="single-row"
)
```

- [Demo App](https://dataframe-row-selections.streamlit.app/)


https://github.com/streamlit/streamlit/assets/2852129/f3ff476a-0bd0-4b82-bc97-6bda3a3be98c

## GitHub Issue Link (if applicable)

- Closes #688
- Closes #7134
- #455
- #8319

## Testing Plan

- Added unit tests
- Added e2e tests (see #8634)

```[tasklist]
### e2e tests
- [x] Single row/column selection
- [x] Multi row/column selection
- [x] Mixed selections
- [x] Screenshot of a dataframe with multiple selections
- [x] Clear selections via toolbar
- [x] Clear selections via escape
- [x] Select all rows in multi-row selection via top checkbox
- [x] Optional: Test drag and drop selection
- [x] Optional: Test shift selections
- [x] Optional: Test selections in form
- [x] Have some test cases work with session state and others with return value
- [x] Add a test case validating that the callback gets called
``` 


---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

---------

Co-authored-by: Benjamin Räthlein <[email protected]>
@allocater2
Copy link

Great. In the meantime I was trying dash+dash-deck and it seems they also never implemented click/selection events. The only map I have gotten to work so far is dash+leaflet with the "n_clicks" event.

@Glypican
Copy link

FWIW, I successfully used the streamlit-echarts library to perform onclick callbacks to streamlit from individual heatmap cells. I use the callback to filter a data table, showing the rows corresponding to the heatmap cell. Just mentioning for the next person who comes looking :-)

@LukasMasuch
Copy link
Collaborator

We just merged row & column selections for st.dataframe and it will be released in 1.35. You can activate selections via on_select and configure it via selection_mode, e.g.:

selection = st.dataframe(df, on_select="rerun", selection_mode="single-row")

Or for multi-row & column selections:

selection = st.dataframe(df, on_select="rerun", selection_mode=("multi-row", "multi-column"))

You can try it out in this demo.

@jrieke
Copy link
Collaborator

jrieke commented May 13, 2024

@allocater2 I created a feature request for adding selections to pydeck; please feel free to upvote and describe your use case there; that helps us a lot with prioritization! ❤️

LukasMasuch added a commit that referenced this issue May 14, 2024
#8302)

## Describe your changes

Adds selection support to `st.altair_chart` and `st.vega_lite_chart`
that can be used via:

```python
selections = st.altair_chart(fig, on_select="rerun")
```

## GitHub Issue Link (if applicable)

- Closes: #455
- Closes: #2263

## Testing Plan

- Added unit tests
- Added e2e tests

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

---------

Co-authored-by: Lukas Masuch <[email protected]>
Co-authored-by: William Wei Huang <[email protected]>
Co-authored-by: braethlein <[email protected]>
@jrieke
Copy link
Collaborator

jrieke commented May 14, 2024

Hey all! We just merged selections for st.plotly_chart, st.altair_chart, and st.vega_lite_chart and they will be released together with dataframe selections in 1.35 next week!!

You can then activate selections via the new on_select parameter, e.g.:

event_dict = st.plotly_chart(chart, on_select="rerun")

Since we now support almost all interactivity features mentioned in the original issue, we decided to (finally!) close it. I created separate issues for a few additional events we want to expose in the future. Please upvote and comment on those, and feel free to open new feature requests for additional events we should support!

Thanks everyone for your feedback over the years! ❤️

@jrieke jrieke unpinned this issue May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:events feature:charts Related to charting functionality feature:st.dataframe status:in-progress We're on it! type:enhancement Requests for feature enhancements or new features
Projects
None yet
Development

Successfully merging a pull request may close this issue.