Hi all,
First of all, many thanks for Plotly and Dash, and for making them open source. They are awesome tools!
I have a chart with a line/scatter trace and overlaid on a bar chart. I used a callback with hoverData so that, when I hover over a bar, a dot appears on the corresponding point of the line. The code below works fine except that when I hover over the bars on the left or right side of the plot, the chart scrolls/compresses leaving an empty gap of several days, like so:
I would like to disable this scrolling/compressing behaviour. Interestingly, when I modify the code such that the bars are highlighted rather than a dot on the line, the scrolling/compressing behaviour does not occur, as shown here:
I looked at the reference docs for the scatter plot to see if there was a setting that might replicate the bar chart behaviour but I couldn’t see it. There may be a difference in the coding under the hood but unfortunately my Javascript skills are limited.
Here’s the minimal reproducible code with some random data. Change example('dot')
to example('bar')
to see how that works without scrolling/compressing. I am using plotly version 4.8.1 and dash version 1.13.4.
Thanks again
import numpy as np
import pandas as pd
import plotly.graph_objs as go
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
def example(highlight_type):
dates = pd.DataFrame(pd.date_range(start="2020-04-01",end="2020-05-31"), columns=['date'], dtype='str')
dates['date'] = dates['date'].str[:10]
sample = {
'date':dates['date'].values,
'bar_val':np.random.randint(low=20, high=100, size=len(dates)),
'line_val':np.random.randint(low=40, high=60, size=len(dates))
}
df = pd.DataFrame(sample)
bars_data = dict(
type='bar',
x=df['date'],
y=df['bar_val'],
)
line_data = dict(
type='scatter',
x=df['date'],
y=df['line_val'],
)
fig = go.Figure(
data = [bars_data, line_data],
layout = dict(
barmode='overlay',
xaxis=dict(
fixedrange=True,
)
)
)
app = dash.Dash()
app.layout = html.Div([
dcc.Graph(id='thegraph', figure=fig)
])
@app.callback(
Output('thegraph', 'figure'),
[
Input('thegraph', 'hoverData'),
]
)
def highlight_hover(hoverdata):
if hoverdata:
hover = hoverdata['points'][0]
ptix = hover['pointIndex']
if highlight_type == 'dot':
dot_x = fig['data'][1]['x'][ptix]
dot_y = fig['data'][1]['y'][ptix]
if len(fig['data']) == 2:
fig.add_scatter(
x=[dot_x],
y=[dot_y],
name='highlight',
marker_color='orange',
hoverinfo='skip',
marker_size=10,
)
else:
fig.update_traces(
x=[dot_x],
y=[dot_y],
selector=dict(name='highlight')
)
elif highlight_type == 'bar':
bar_x = fig['data'][0]['x'][ptix]
bar_y = fig['data'][0]['y'][ptix]
if len(fig['data']) == 2:
fig.add_bar(
x=[bar_x],
y=[bar_y],
name='highlight',
marker_color='orange',
hoverinfo='skip',
width = 24*60*60*1000,
)
else:
fig.update_traces(
x=[bar_x],
y=[bar_y],
selector=dict(name='highlight')
)
return fig
if __name__ == '__main__':
app.run_server()
## This scrolls/compresses on hover at the far left/right ends:
example('dot')
## This does not, and is the behaviour I would like for example('dot'):
# example('bar')