user-interfacemapstaipy

How to retrieve information from a point on a Taipy chart


In our Taipy application, we've integrated a map. On this map, multiple points are available, representing various locations or data points. When a user interacts with one of these points, an hoverlay is displayed with certain information.

However, how to be able to get additional information from this point upon interaction, other than the details already presented in the hoverlay.

from taipy import Gui

import pandas as pd
import numpy as np

cities = [
    {"name": "Tokyo", "lat": 35.6839, "lon": 139.7744, "population": 39105000},
    {"name": "Jakarta", "lat": -6.2146, "lon": 106.8451, "population": 35362000},
    {"name": "Xinyang", "lat": 32.1264, "lon": 114.0672, "population": 6109106},
]

# Convert to Pandas DataFrame
data = pd.DataFrame(cities)

solve = np.linalg.solve([[data["population"].min(), 1], [data["population"].max(), 1]], [5, 60])
data["size"] = data["population"].apply(lambda p: p*solve[0]+solve[1])

# Add a column holding the bubble hover texts
# Format is "<city name> [<population>]"
data["text"] = data.apply(lambda row: f"{row['name']} [{row['population']}]", axis=1)

marker = {
    "size": "size"
}

layout = {
    "dragmode": "zoom",
    "mapbox": { "style": "open-street-map"}
}

map = "<|{data}|chart|type=scattermapbox|mode=markers|lat=lat|lon=lon|marker={marker}|text=text|layout={layout}|>"


Gui(map).run()

Solution

  • What you're looking for is a chart's 'selected' property. You can bind this property with a Python variable in your chart. This allows you to retrieve the indices of the points that have been selected and then do whatever you want with this information.

    Take a look at the following code, which creates a map with this property. The on_change callback is called when a user selects a point. Some print statements in this function show that we retrieve the index and can then find the associated data.

    from taipy import Gui
    
    import pandas as pd
    import numpy as np
    
    cities = [
        {"name": "Tokyo", "lat": 35.6839, "lon": 139.7744, "population": 39105000},
        {"name": "Jakarta", "lat": -6.2146, "lon": 106.8451, "population": 35362000},
        {"name": "Xinyang", "lat": 32.1264, "lon": 114.0672, "population": 6109106},
    ]
    
    # Convert to Pandas DataFrame
    data = pd.DataFrame(cities)
    
    solve = np.linalg.solve([[data["population"].min(), 1], [data["population"].max(), 1]], [5, 60])
    data["size"] = data["population"].apply(lambda p: p*solve[0]+solve[1])
    
    # Add a column holding the bubble hover texts
    # Format is "<city name> [<population>]"
    data["text"] = data.apply(lambda row: f"{row['name']} [{row['population']}]", axis=1)
    
    marker = {
        "size": "size"
    }
    
    layout = {
        "dragmode": "zoom",
        "mapbox": { "style": "open-street-map"}
    }
    
    selected_points = []
    
    map = "<|{data}|chart|type=scattermapbox|mode=markers|lat=lat|lon=lon|marker={marker}|text=text|layout={layout}|selected={selected_points}|>"
    
    def on_change(state, var_name, var_value):
        print("on_change", var_name, var_value)
        print(data.loc[state.selected_points,:])
    
    Gui(map).run()