Hello community,
Here is a plot with 3 geo locations. I would like to change the color of one marker and draw line when I click on a marker.
Figure is updated but the color on the plot doesn’t change.
Any idea ?
import dash
import pandas as pd
from dash import dcc, html, Input, Output
import plotly.graph_objects as go
# Data dictionary
datadic = {'text': ['P1', 'P2', 'P3'],
'lat': [51.210861, 51.15074269, 51.25448546],
'lon': [4.430369, 4.38558337, 4.39597967],
'color': ['blue', 'blue', 'blue']}
data_df = pd.DataFrame(datadic)
# Initialize Dash app
app = dash.Dash(__name__)
# Layout
app.layout = html.Div([
dcc.Graph(id='map', style={'height': '90vh'}),
])
# Callback
@app.callback(
Output('map', 'figure'),
Input('map', 'clickData'),
prevent_initial_call=False
)
def update_map(click_data):
# Create the base figure
fig = go.Figure()
newdata_df = data_df.copy()
print('newdata_df1')
print(newdata_df)
if click_data:
point = click_data['points'][0]
for index in range(len(newdata_df)):
if newdata_df.loc[index, 'lat'] == point['lat'] and newdata_df.loc[index, 'lon'] == point['lon']:
newdata_df.loc[index, 'color'] = 'red'
print('newdata_df2')
print(newdata_df)
# Add points to the map
fig.add_trace(go.Scattermapbox(
lat=newdata_df['lat'],
lon=newdata_df['lon'],
mode='markers+text',
text=newdata_df['text'],
marker=dict(size=10, color=newdata_df['color']),
hoverinfo='text'
))
print(fig)
# Add a red line dynamically when a point is clicked
if click_data:
try:
# Extract coordinates of the clicked point
point = click_data['points'][0]
lon, lat = point['lon'], point['lat']
# Add a red line extending from the clicked point
fig.add_trace(go.Scattermapbox(
lat=[lat, lat + 0.1], # Extending vertically by 0.1
lon=[lon, lon], # Keeping longitude constant
mode='lines',
line=dict(color='red', width=2),
name=f"Line from {point['text']}" # Label the line dynamically
))
except Exception as e:
print(f"[ERROR] Failed to process clickData: {e}")
# Set mapbox properties
fig.update_layout(
mapbox=dict(
style="carto-positron",
center=dict(lat=sum(datadic['lat']) / len(datadic['lat']), # Center map around the average lat
lon=sum(datadic['lon']) / len(datadic['lon'])), # Center map around the average lon
zoom=12
),
margin=dict(l=0, r=0, t=0, b=0)
)
return fig
# Run the app
if __name__ == '__main__':
app.run_server(debug=True)