Black Lives Matter. Please consider donating to Black Girls Code today.

Crossfiltering scattermapbox

Hello,

I have a dataframe that has the following columns -

Datetime, Lat, Long, Level

This is used to plot a lineGraph -
LineGraph

as well as plot the location on a map -
Map

I have read about the topic of Crossfiltering and tried to use the ‘relayoutData’ based on user zooming in to the linegraph to see if I can filter out the dataframe and only plot those points on map that are selected in the linegraph. However this doesnt work.

I tried the following code for callback -

@app.callback(Output('map2', 'figure'), [Input('freq_dropdown','value'), Input('lineGraph','relayoutData'), Input('map2_container','children')])
	def lineChart(freq, lineSelection, jsonifiedMap2):
		# Get the json data into a dataframe
		a = json.loads(jsonifiedMap2)
		b = json.loads(a['df_1'])
		df1 = pd.DataFrame(data=b['data'])
		df1.columns=b['columns']
                
# convert Datetime to datetime, set it as index and after filtering out the 'NaT'. This is to remove the UTC reference in datetime column
		df1['Datetime'] = pd.to_datetime(df1['Datetime'], errors='coerce',utc='False')
		df1= df1[~df1['Datetime'].isnull()]
		df1.set_index('Datetime', inplace=True)
		df1 = df1.tz_localize(None)
		df1.reset_index(inplace=True)

# If relayedoutData has x and y axis ranges - get them to filter the dataframe
		if len(lineSelection)==1:
			trace = [go.Scattermapbox(lat=df1["latitude"], lon=df1["longitude"], mode='markers', marker={'symbol': "circle", 'size': 10, 'color':df1[freq].values.tolist(), 'colorscale':'Hot', 'cmin':-120, 'cmax':-60, 'autocolorscale':False}, hoverinfo='text', text= df1[["Datetime",freq]].values.tolist(), name='Signal levels (dBm) on drive route')]
			fig1 = {"data": trace, "layout": go.Layout(autosize=True, hovermode='closest', showlegend=False, mapbox={'accesstoken': mapbox_access_token, 'zoom': 8,"style": 'outdoors', 'center': {'lat': df1['latitude'].iloc[-1], 'lon': df1['longitude'].iloc[-1]}})}
			return fig1
			
		
		if len(lineSelection)>1:
			x0 = lineSelection['xaxis.range[0]'].split('.')[0]
			x1 = lineSelection['xaxis.range[1]'].split('.')[0]
		
			startTime = pd.to_datetime(x0).round('1min')
			endTime = pd.to_datetime(x1).round('1min')
			
# Filter on datetime column based on user zoom level on the line chart and return the map 'figure'
			df1 = df1[(df1['Datetime']>=startTime) & (df1['Datetime']<=endTime)]
			
			trace = [go.Scattermapbox(lat=df1["latitude"], lon=df1["longitude"], mode='markers', marker={'symbol': "circle", 'size': 10, 'color':df1[freq].values.tolist(), 'colorscale':'Hot', 'cmin':-120, 'cmax':-60, 'autocolorscale':False}, hoverinfo='text', text= df1[["Datetime",freq]].values.tolist(), name='Signal levels (dBm) on drive route')]
			fig2 = {"data": trace, "layout": go.Layout(autosize=True, hovermode='closest', showlegend=False, mapbox={'accesstoken': mapbox_access_token, 'zoom': 8,"style": 'outdoors', 'center': {'lat': df1['latitude'].iloc[-1], 'lon': df1['longitude'].iloc[-1]}})}

			return fig2

This doesnt seem to make any changes on the map, although I have observed hoverinfo only showing for the filtered dataframe, however the other points also exist.

Am i missing something trivial here? Please help.

Thanks
Ananth

Hi @aiyer1, not easy to investigate without having the whole code and data, so here are a few things which you can try:

  • print messages in each of your two if statements (which could be if and else by the way) to be sure that you go to the right one when selecting a region
  • print the result of the filtered dataframe to be sure that the filter is correct
  • use a scatter trace of lat and lon instead of scattermapbox to be sure that the problem is not specific to scattermapbox.