yuki_s
yuki_s

Reputation: 11

Drag and move the vertical line on the time series data graph to mark and hold

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.

enter image description here

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

Answers (1)

Matthew Thomas
Matthew Thomas

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

Related Questions