Hello!
Iām trying to use Streamlit to display the realtime position of a GPS tracker. As such, I need the ability to create a map, put a position marker on the map, then update the markerās position when new data arrives. For now, Iām just trying to add an additional point via a button. I am using the pydeck_chart object to display this map.
Hereās how Iām creating the plot:
df = pd.DataFrame(
np.array([[0,0],[37.54642576306282, -122.10201970117545]]),
columns=['lat', 'lon'])
deck_obj = pdk.Deck(
map_style='mapbox://styles/mapbox/satellite-v9',
initial_view_state=pdk.ViewState(
latitude=37.54642576306282,
longitude=-122.10201970117545,
zoom=19,
pitch=0,
),
layers=[
pdk.Layer(
'ScatterplotLayer',
data=df,
get_position='[lon, lat]',
get_color='[200, 30, 0, 160]',
get_radius=1,
),
],
)
my_map = st.pydeck_chart(deck_obj)
After creating the plot, Iām creating a button and then attempting to update the data when the button is clicked. First attempt was to use just the add_rows command, which explicitly doesnāt work:
update_button = st.button("UPDATE!")
if update_button:
new_data = [37.54642576306282,-122.10211970117545]
my_map.add_rows(new_data)
My second attempt was to add the new point to the data inside the pydeck Deck objectās layers dictionary, then call the Deck objectās update command:
deck_obj.layers[0].data.append({'lat': 37.54642576306282,'lon':-122.10211970117545})
deck_obj.update()
This attempt doesnāt explicitly not work; however, nothing changes on the map itself.
I realized while writing this, that the fact that nothing happens with the above makes sense given that pressing the āupdateā button reinitializes the dataframe df and the map with the original data. So, I made the dataframe into a session state variable:
if 'df' not in st.session_state:
st.session_state.df = df
and changed the above deck_obj to use st.session_state.df
instead of df
. Now, my update script is as follows:
if update_button:
st.session_state.df.loc[1][1] = st.session_state.df.loc[1][1] - 0.00005
I can also add other points using the same functionality.
At this point, Iām left with one additional point of confusion: the first time I push the update button, nothing happens; all additional pushes correctly update the point.
Does anyone have suggestions on how to improve this functionality? Itād be great to cache the map object and just update the data contained within the map object, so suggestions regarding accomplishing that would be appreciated!