Event handling ^^^^^^^^^^^^^^ .. NOTE:: Event handling requires the Jupyter widget integration, which is not currently functional in pydeck v0.9+. See :doc:`jupyter` for details. pydeck provides bidirectional interactions in Jupyter via event handlers, ``on_hover``, ``on_resize``, ``on_view_state_change``, and ``on_click``. Each corresponds to the `cursor `__ and `view state `__ events in the deck.gl documentation. When an event triggers these callbacks (like a click on the visualization), data is sent from the frontend to the Jupyter kernel. The data structure varies slightly by handler. To inspect the payload of a handler, you can print the result to an `ipywidgets HTML `__ object. For a live demo of the handlers, see `03 - Event handlers and data selection in pydeck `__. The following code is a snippet from the notebook above, where a view state change triggers a count of visible points. .. code-block:: python from ipywidgets import HTML text = HTML(value='Move the viewport') layer = pdk.Layer( 'ScatterplotLayer', df, pickable=True, get_position=['lng', 'lat'], get_fill_color=[255, 0, 0], get_radius=100 ) r = pdk.Deck(layer, initial_view_state=viewport) def filter_by_bbox(row, west_lng, east_lng, north_lat, south_lat): return west_lng < row['lng'] < east_lng and south_lat < row['lat'] < north_lat def filter_by_viewport(widget_instance, payload): try: west_lng, north_lat = payload['data']['nw'] east_lng, south_lat = payload['data']['se'] filtered_df = df[df.apply(lambda row: filter_by_bbox(row, west_lng, east_lng, north_lat, south_lat), axis=1)] text.value = 'Points in viewport: %s' % int(filtered_df.count()['lng']) except Exception as e: text.value = 'Error: %s' % e r.deck_widget.on_click(filter_by_viewport) display(text) r.show() Cursor events with ``on_click`` ------------------------------- Clicking data in a visualization passes the following data back as the ``payload`` object in the ``on_click`` handler: .. code-block:: python { 'type': 'deck-click-event', 'data': { 'color': { '0': int, '1': int, '2': int, '3': int }, 'layer': str, # The layer ID, which you can specify by passing `id=...` to a Layer; `None` if no layer is picked 'index': int, # The serial index of the clicked point in the data set; -1 if no layer is picked 'picked': bool, 'x': float, # X coordinate of pixel on click 'y': float, # Y coordinate of pixel on click 'pixel': [float, float], # Pixel coordinate pair 'coordinate': [float, float], # Lat/lon coordinate pair 'lngLat': [float, float], # Duplicated information in 'coordinate' 'devicePixel': [int, int], # Pixel coordinate pair on device screen 'pixelRatio': int, 'object': { # Metadata from selected clicked object which varies by layer } } } The ``on_hover`` events are nearly identical in content, with the``type`` value of ``deck-hover-event``. Only hovering over a layer will fire an event and hovering over the basemap alone will not. .. image:: https://i.giphy.com/media/NUAAe4uewDjncNlwYQ/source.gif :width: 600 :alt: pydeck on_click handler View state change events with ``on_view_state_change`` ------------------------------------------------------ Zooming in and out, panning, and changing pitch or bearing all constitute view state changes. A view state change event sends a dictionary with the following information as the ``payload``: .. code-block:: python { 'type': 'deck-view-state-change-event', 'data': { 'width': int, 'height': int, 'latitude': float, 'longitude': float, 'zoom': float, 'bearing': float, 'pitch': float, 'altitude': float, 'maxZoom': float, 'minZoom': float 'maxPitch': float, 'minPitch': float, 'nw': [float, float], 'se': [float, float] } } Here ``nw`` and ``se`` represent the northwest and southeast corners of the current viewport. .. image:: https://i.giphy.com/media/6rVa9CcA8suplaDEpi/giphy.gif :width: 600 :alt: pydeck on_view_state_change handler Resize events with ``on_resize`` -------------------------------- Resizing the viewport sends the height and width of the new visualization back as the ``payload`` object: .. code-block:: python { 'type': 'deck-resize-event', 'data': { 'width': int, 'height': int } } .. image:: https://i.giphy.com/media/sD2SzoPs7p1uBzcmRf/source.gif :width: 600 :alt: pydeck on_resize handler