Bug in Dash on mobile?

Hello,
I have found what appears to be a reproducible issue that only occurs when using Dash for interactive plots on a mobile device. Tip: If you are on a computer and want to simulate a mobile device, just go to the website in Chrome, hit F12, and select a mobile device in the drop down along the top bar.

My dash application has two plots which you can see live if you go to airpollutiondata.com on your mobile device or via the Chrome method above. Alternatively, I provided screenshots below. The top is a map that indicates where pollution measurements occurred.
image

Clicking on one of the dots on the map will update the content in the bottom graph. The bottom graph has the measurement for each pollutant over time. You can click on one of the data points in this graph to see more information about it.
image
So far everything is perfect. The problem arises when the user clicks another location in the top map. The hover information lingers despite the fact that the data point generating it is no longer displayed.
image

The expected behavior is that the hover text would go away when the bottom graph is updated. As part of the debugging process, I did update my dash modules to 1.0.2 which did not resolve the issue. Plotly is at 4.0.0.

Here is the code I’m using to generate the plots in case there is a workaround available. Maybe there’s something I can add to clear the textboxes in the app callback?

app = dash.Dash()
server = app.server

************************************ APP LAYOUT ************************************

app.layout = html.Div([

----------- AIR POLLUTANT MAP -----------------

html.Div([
    dcc.Graph(
            figure=go.Figure(
                # Make the dark outline on the markers
                data = [go.Scattermapbox(
                        lon = siteDf ['Longitude'],
                        lat = siteDf ['Latitude'],
                        hoverinfo = 'none',
                        mode = 'markers',
                        marker = dict( 
                            size = 7, 
                            opacity = 1,
                            color = 'rgb(0, 0, 0)',
                    ), 
                    ), 
                    
                    # Create markers whose color are scaled to the risk level
                    go.Scattermapbox(
                        lon = siteDf ['Longitude'],
                        lat = siteDf ['Latitude'],
                        text = siteDf['Plotting Text'], #siteDf ['Local Site Name'],
                        hoverinfo = 'text',
                        mode = 'markers',
                        marker = dict( 
                            size = 5, 
                            opacity = 0.8,
                            reversescale = True,
                            autocolorscale = False,
                            symbol = 'circle',
                            colorscale = scl,
                            cmin = 0, #siteDf[plottingParameter].min(),
                            color = siteDf['Risk Level'],
                            cmax = siteDf.describe(percentiles=[0.95]).loc['95%', 'Risk Level'], # Make it so the top 10% of sites have the darkest color
                            colorbar=dict(
                                title='Cancer Risk Level'
                                ),
                    ), 
                    )],
            layout = go.Layout(
                    title = 'EPA Measured Air Pollution Converted to Cancer Risk<br> Click on a site to see measurements', 
                    autosize=True,
                    hovermode='closest',
                    showlegend=False,
                    mapbox=go.layout.Mapbox(
                            accesstoken=mapbox_access_token,
                            bearing=0,
                            center=go.layout.mapbox.Center(
                                lat=38,
                                lon=-94
                            ),
                            pitch=0,
                            zoom=3,
                            style='light'
                    )
                    )),
        id='collection-map'
    )
], style={'width': '90%', 'display': 'inline-block', 'padding': '0 1'}),      

-------------------------------------------------

----------- AIR POLLUTANT PARAMETER SCATTER PLOT -----------------

 html.Div([
    dcc.Graph(
            id = 'site-param-plot'                
    )
], style={'width': '90%', 'display': 'inline-block', 'padding': '0 1'}),

-------------------------------------------------

])

************************************ APP CALLBACKS ************************************

@app.callback(
Output(‘site-param-plot’, ‘figure’),
[Input(‘collection-map’, ‘clickData’)])
def update_site_param(clickData):

if clickData is None:
    lon = data['Longitude'].iloc[0]
    lat = data['Latitude'].iloc[0]
else:
    lon = clickData['points'][0]['lon']
    lat = clickData['points'][0]['lat']
longMask = data['Longitude'] == lon
latMask = data['Latitude'] == lat
siteName = data[longMask & latMask]['Local Site Name'].unique()[0]
cityName = data[longMask & latMask]['City Name'].unique()[0].split('(')[0]
stateName = data[longMask & latMask]['State Name'].unique()[0]
if pd.isnull(siteName):
    siteName = str(cityName) + ', ' + str(stateName)
#locationString = str(siteName) + ': ' + str(cityName) + ', ' + str(stateName)
locationString = str(siteName) + '<br>' + str(cityName) + ', ' + str(stateName)

#siteName = 'Zion NP - Dalton\'s Wash'
siteData = data[longMask & latMask]
siteData = siteData[['Parameter Name', 'Units of Measure', 'Year', 'Risk Level']].groupby(['Parameter Name', 'Year', 'Units of Measure']).max().reset_index()
siteData['Plotting Text'] = siteData['Parameter Name'] + '<br>Year: ' + siteData['Year'].astype(str) + '<br>Risk: ' + siteData['Risk Level'].astype(str) + ' extra cancer cases per 100k people<br><br>'

# Apply cancer risk thresholds from the EPA
# siteData['Risk Level'] = siteData.apply(lambda x:applyrisklevel(x, Limits, plottingParameter), axis=1)


return {
        'data':[go.Scatter(
                x = siteData[siteData['Parameter Name'] == i]['Year'],
                y = siteData[siteData['Parameter Name'] == i]['Risk Level'],
                text = siteData[siteData['Parameter Name'] == i]['Plotting Text'],
                hoverinfo = 'text',
                mode='lines+markers',
                marker={
                    'size': 10,
                    'opacity': 0.5,
                    'line': {'width': 0.5, 'color': 'white'}
                },
                name = i
                )for i in np.sort(siteData['Parameter Name'].unique())
                ],
        'layout': go.Layout(
                    title = {'text': locationString}, 
                    xaxis={
                        'title': 'Year',
                        'type': 'linear'
                    },
                    yaxis={
                        'title': 'Extra # of Cancer Cases per 100k People',
                        'type': 'linear'
                    },
                    #margin={'l': 40, 'b': 30, 't': 50, 'r': 0},
                    #height=500,
                    #width = '95%',
                    hovermode='closest',
                    showlegend=True,
           
                )
                
        }

if name == ‘main’:
app.run_server()