This question is also on SO: Add a point to plot that follows the plot according to x-value given
I want to create a plot in Plotly with 2 features:
- It is a scatterplot/lineplot that plots a list of y vs list of x variables.
- It has a 2nd dot whose x-value is controlled by a slider (range is constrained to x variables list). This dot will follow the plot in 1.
I do not know how to implement the 2nd feature.
This is my code. The first trace handles the 1st plot, the second trace should handle the 2nd dot:
# library imports
import dash
from dash import html, Input, Output, dcc
import dash_bootstrap_components as dbc
import plotly.graph_objs as go
import pandas as pd
# data
df = pd.DataFrame(
data = {
"varA": [1.5, 2.3, 3.1, 4.4954],
"varB": [6.1232, 4.4343, 8.432, 5.39],
}
)
# app info
style_sheets = [
dbc.themes.BOOTSTRAP
]
app = dash.Dash(__name__, external_stylesheets=style_sheets)
app.layout = html.Div(
[
dcc.Graph("graph"),
dcc.Slider(
min = min(df["varA"].tolist()),
max = max(df["varA"].tolist()),
value = 0,
id="slider"
)
]
)
# Callback
@app.callback(
Output("graph", "figure"),
[Input("slider", "value")]
)
def create_graph(slider_input):
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=df["varA"],
y=df["varB"],
mode='lines+markers', # add markers
marker=dict(size=10) # marker size
)
)
# Given value x, find a
closest_value = df['varA'].iloc[(df['varA'] - slider_input).abs().argsort()[:1]].values[0]
print(slider_input)
print(closest_value)
index_of_x = df.index[df['varA'] == closest_value].tolist()[0]
corresponding = df.iloc[index_of_x]['varB']
# Add the dot whose position changes based on the slider input
fig.add_trace(
go.Line(
x=[slider_input],
y=[corresponding],
mode='markers',
marker=dict(color='red', size=12),
name='Slider Dot'
)
)
return fig
if __name__ == '__main__':
app.run_server(debug=False)
In the output plot, I want the red dot to always be on the blue line, but it changes location based on the slider input.
Iām hoping to extend this solution to graphs with other shapes, not just linear examples.
Thank you in advance.