Skip to content

Commit

Permalink
Controlled data return (#89)
Browse files Browse the repository at this point in the history
* Control which kinds of data are returned (and which trigger reruns)

* Convert example app into MPA

* Add limited return example

* Standardize layout

* Bump version

* Don't replace functionality of folium_static yet
  • Loading branch information
blackary authored Nov 9, 2022
1 parent 68526ea commit 83eec9e
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 136 deletions.
18 changes: 0 additions & 18 deletions examples/draw_support.py

This file was deleted.

37 changes: 37 additions & 0 deletions examples/pages/draw_support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import streamlit as st

st.set_page_config(
page_title="streamlit-folium documentation: Draw Support",
page_icon=":pencil:",
layout="wide",
)

"""
# streamlit-folium: Draw Support
Folium supports some of the [most popular leaflet plugins](https://python-visualization.github.io/folium/plugins.html). In this example,
we can add the [`Draw`](https://python-visualization.github.io/folium/plugins.html#folium.plugins.Draw) plugin to our map, which allows for drawing geometric shapes on the map.
When a shape is drawn on the map, the coordinates that represent that shape are passed back as a geojson feature via
the `all_drawings` and `last_active_drawing` data fields.
Draw something below to see the return value back to Streamlit!
"""

with st.echo():

import folium
import streamlit as st
from folium.plugins import Draw

from streamlit_folium import st_folium

m = folium.Map(location=[39.949610, -75.150282], zoom_start=5)
Draw(export=True).add_to(m)

c1, c2 = st.columns(2)
with c1:
output = st_folium(m, width=700, height=500)

with c2:
st.write(output)
54 changes: 54 additions & 0 deletions examples/pages/limit_data_return.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import streamlit as st

st.set_page_config(
page_title="streamlit-folium documentation: Limit Data Return",
page_icon="🤏",
layout="wide",
)

"""
# streamlit-folium: Limit Data Return
By default, st_folium returns quite a few data fields (zoom, bounds, last active drawing,
all drawings, etc). If you only need a subset of these fields, you can pass a list of
the fields you want returned to the `returned_objects` parameter.
"""

"""
### Example: Only return the last object clicked on the map
Try clicking on the tooltips below. Note that clicking elsewhere on the map, or zooming
or scrolling will not cause the app to rerun.
"""

with st.echo():
import folium
import streamlit as st

from streamlit_folium import st_folium

m = folium.Map(location=[39.949610, -75.150282], zoom_start=13)

folium.Marker(
[39.949610, -75.150282], popup="Liberty Bell", tooltip="Liberty Bell"
).add_to(m)
folium.Marker(
[39.95887, -75.150026],
popup="Independence Hall",
tooltip="Independence Hall",
).add_to(m)
folium.Marker(
[39.965570, -75.180966],
popup="Philadelphia Museum of Art",
tooltip="Philadelphia Museum of Art",
).add_to(m)

c1, c2 = st.columns(2)
with c1:
output = st_folium(
m, width=700, height=500, returned_objects=["last_object_clicked"]
)

with c2:
st.write(output)
36 changes: 36 additions & 0 deletions examples/pages/static_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import streamlit as st

st.set_page_config(
page_title="streamlit-folium documentation: Static Map",
page_icon=":ice:",
layout="wide",
)

"""
# streamlit-folium: Non-interactive Map
If you don't need any data returned from the map, you can just
pass returned_objects=[] to st_folium. The streamlit app will not rerun
when the user interacts with the map, and you will not get any data back from the map.
---
"""
"### Basic `returned_objects=[]` Example"

with st.echo():

import folium
import streamlit as st

from streamlit_folium import st_folium

# center on Liberty Bell, add marker
m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
folium.Marker(
[39.949610, -75.150282], popup="Liberty Bell", tooltip="Liberty Bell"
).add_to(m)

# call to render Folium map in Streamlit, but don't get any data back
# from the map (so that it won't rerun the app when the user interacts)
st_folium(m, width=725, returned_objects=[])
File renamed without changes.
117 changes: 32 additions & 85 deletions examples/streamlit_app.py
Original file line number Diff line number Diff line change
@@ -1,121 +1,68 @@
import streamlit as st
import streamlit_folium

st.set_page_config(page_title="streamlit-folium documentation")

page = st.sidebar.radio(
"Select page", ["Home", "Bi-directional data model", "Plugin: Draw"], index=0
st.set_page_config(
page_title="streamlit-folium documentation",
page_icon=":world_map:️",
layout="wide",
)

"# streamlit-folium"

if page == "Home":
"streamlit-folium integrates two great open-source projects in the Python ecosystem: [Streamlit](https://streamlit.io) and [Folium](https://python-visualization.github.io/folium/)!"

"""
Currently, there are two functions defined:
"streamlit-folium integrates two great open-source projects in the Python ecosystem: [Streamlit](https://streamlit.io) and [Folium](https://python-visualization.github.io/folium/)!"

- `st_folium()`: a bi-directional Component, taking a Folium/Branca object and plotting to the Streamlit app. Upon mount/interaction with the Streamlit app, st_folium() returns a Dict with selected information including the bounding box and items clicked on
- `folium_static()`: takes a folium.Map, folium.Figure, or branca.element.Figure object and displays it in a Streamlit app.
_Note: `folium_static()` is based on the `_repr_html()` representation created in Folium. This function should be a strict subset the of functionality of the newer `st_folium()` function._
It is recommended that users switch to `st_folium()` as soon as possible, as `folium_static()` will likely be deprecated. If there is a reason why `folium_static()` needs to remain, please leave a [GitHub issue](https://github.com/randyzwitch/streamlit-folium/issues) describing your use-case.
"""
"""
Currently, there are two functions defined:
- `st_folium()`: a bi-directional Component, taking a Folium/Branca object and plotting to the Streamlit app. Upon mount/interaction with the Streamlit app, st_folium() returns a Dict with selected information including the bounding box and items clicked on
"---"
"### Basic `st_folium()` Example"

with st.echo():

import streamlit as st
from streamlit_folium import st_folium
import folium

# center on Liberty Bell, add marker
m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
folium.Marker(
[39.949610, -75.150282],
popup="Liberty Bell",
tooltip="Liberty Bell"
).add_to(m)
- `folium_static()`: takes a folium.Map, folium.Figure, or branca.element.Figure object and displays it in a Streamlit app.
"""

# call to render Folium map in Streamlit
st_data = st_folium(m, width = 725)
"""
On its own, Folium is limited to _display-only_ visualizations; the Folium API generates the proper [leaflet.js](https://leafletjs.com/) specification,
as HTML and displays it. Some interactivity is provided (depending on how the Folium API is utilized), but the biggest drawback
is that the interactivity from the visualization isn't passed back to Python, and as such, you can't make full use of the functionality
provided by the leaflet.js library.
elif page == "Bi-directional data model":
"""
On its own, Folium is limited to _display-only_ visualizations; the Folium API generates the proper [leaflet.js](https://leafletjs.com/) specification,
as HTML and displays it. Some interactivity is provided (depending on how the Folium API is utilized), but the biggest drawback
is that the interactivity from the visualization isn't passed back to Python, and as such, you can't make full use of the functionality
provided by the leaflet.js library.
`streamlit-folium` builds upon the convenient [Folium API](https://python-visualization.github.io/folium/modules.html)
for building geospatial visualizations by adding a _bi-directional_ data transfer functionality. This not only allows for increased interactivity between
the web browser and Python, but also the use of larger datasets through intelligent querying.
`streamlit-folium` builds upon the convenient [Folium API](https://python-visualization.github.io/folium/modules.html)
for building geospatial visualizations by adding a _bi-directional_ data transfer functionality. This not only allows for increased interactivity between
the web browser and Python, but also the use of larger datasets through intelligent querying.
### Bi-directional data model
"""
left, right = st.columns(2)

### Bi-directional data model

If we take a look at the example from the Home page, it might seem trivial. We define a single point with a marker and pop-up and display it:
with left:
"""
If we take a look at the example from the Home page, it might seem trivial. We define a single point with a marker and pop-up and display it:
"""
with st.echo():

import folium
import streamlit as st

from streamlit_folium import st_folium
import folium


# center on Liberty Bell, add marker
m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
folium.Marker(
[39.949610, -75.150282],
popup="Liberty Bell",
tooltip="Liberty Bell"
[39.949610, -75.150282], popup="Liberty Bell", tooltip="Liberty Bell"
).add_to(m)

# call to render Folium map in Streamlit
st_data = st_folium(m, width = 725)
st_data = st_folium(m, width=725)

with right:
"""
But behind the scenes, a lot more is happening _by default_. The return value of `st_folium` is set to
But behind the scenes, a lot more is happening _by default_. The return value of `st_folium` is set to
`st_data`, and within this Python variable is information about what is being displayed on the screen:
"""

with st.expander("Expand to see data returned to Python"):
st_data
st_data

"""
As the user interacts with the data visualization, the values for `bounds` are constantly updating, along
with `zoom`. With these values available in Python, we can now limit queries based on bounding box, change
the marker size based on the `zoom` value and much more!
"""

elif page == "Plugin: Draw":

"""
Folium supports some of the [most popular leaflet plugins](https://python-visualization.github.io/folium/plugins.html). In this example,
we can add the [`Draw`](https://python-visualization.github.io/folium/plugins.html#folium.plugins.Draw) plugin to our map, which allows for drawing geometric shapes on the map.
When a shape is drawn on the map, the coordinates that represent that shape are passed back as a geojson feature via
the `all_drawings` and `last_active_drawing` data fields.
Draw something below to see the return value back to Streamlit!
"""

with st.echo():

import folium
import streamlit as st
from folium.plugins import Draw
from streamlit_folium import st_folium

m = folium.Map(location=[39.949610, -75.150282], zoom_start=5)
Draw(export=True).add_to(m)

c1, c2 = st.columns(2)
with c1:
output = st_folium(m, width = 700, height=500)

with c2:
st.write(output)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setuptools.setup(
name="streamlit_folium",
version="0.6.15",
version="0.7.0",
author="Randy Zwitch",
author_email="[email protected]",
description="Render Folium objects in Streamlit",
Expand Down
Loading

0 comments on commit 83eec9e

Please sign in to comment.