Reputation: 11
I want to use Python plotly to mark a vertical line that can be dragged around on a time series data graph.
Share my image below.
I remember browsing the plotly or dash web pages that previously described the features of this image, but I couldn't find it when I searched again. If my mistake is, please let me know how to realize this function.
Upvotes: 1
Views: 3098
Reputation: 861
One approach is to use a shapes
object in a dcc.Graph
. You have to configure the graph to editable
to be able to move the shape. You can then use the relayoutData
property of the dcc.Graph as input in the callback function in order to get the position of the shape on the graph. This is explained in the link below. I don't think there is a way to restrict the movement of the shape, unfortunately. So in your case, there is no way to restrict the vertical line to stay vertical. A user would be able to alter it's angle, for example.
https://community.plotly.com/t/moving-the-location-of-a-graph-point-interactively/7161/2
I've also included some starter code as an example of a movable vertical line on a dash plot.
import json
from textwrap import dedent as d
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/dZVMbK.css'})
styles = {'pre': {'border': 'thin lightgrey solid', 'overflowX': 'scroll'}}
app.layout = html.Div(className='row', children=[
dcc.Graph(
id='basic-interactions',
className='six columns',
figure={
'data': [{
'x': [1, 2, 3, 4],
'y': [4, 1, 3, 5],
'text': ['a', 'b', 'c', 'd'],
'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers',
'marker': {
'size': 12
}
}, {
'x': [1, 2, 3, 4],
'y': [9, 4, 1, 4],
'text': ['w', 'x', 'y', 'z'],
'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
'name': 'Trace 2',
'mode': 'markers',
'marker': {
'size': 12
}
}],
'layout': {
'shapes': [{
'type': 'line',
'x0': 0.5,
'x1': 0.5,
'xref': 'paper',
'y0': 0,
'y1': 9,
'yref': 'y',
'line': {
'width': 4,
'color': 'rgb(30, 30, 30)',
'dash': 'dashdot'
}
}]
}
},
config={
'editable': True,
'edits': {
'shapePosition': True
}
}
),
html.Div(
className='six columns',
children=[
html.Div(
[
dcc.Markdown(
d("""
**Zoom and Relayout Data**
""")),
html.Pre(id='relayout-data', style=styles['pre']),
]
)
]
)
])
@app.callback(
Output('relayout-data', 'children'),
[Input('basic-interactions', 'relayoutData')])
def display_selected_data(relayoutData):
print("relayoutData:" + str(relayoutData))
return json.dumps(relayoutData, indent=2)
if __name__ == '__main__':
app.run_server(debug=True)
Upvotes: 2