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!

2 Likes

Try using the update function provided by pydeck.

Check out the demo on the Pydeck github repository