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:
<code># 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)
</code>
<code># 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)
</code>
# 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)
This is the output plot. I want the red dot to traverse the blue line according to the slider x value.
Thank you in advance.