Updating Data in a pydeck_chart Object

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!