# Link zoom and pan actions for all subplots

**URL:** <https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387>\
**Category:** plotly.js\
**Created:** [December 19, 2017, 1:26am UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387 "2017-12-19T01:26:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daifaityr234](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Daifaityr234](https://community.plotly.com/u/Daifaityr234)\
**Post date:** [December 19, 2017, 1:26am UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/1 "2017-12-19T01:26:45Z")

</div>

Is there a way to zoom in on one subplot and have every other subplot zoom in on the same place?

Right now I have a streaming application and I want to find a way to synchronise the zooming in on a trace and have corresponding trace segments from other subplots to follow the zooming of one graph. Is this possible?

 ![Untitled](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/0/04fe8622c66743a15b08fcda803ed7dba1bea563.png)

---

<div class="post-metadata">

**Author:** ![etienne](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/etienne/32/17_2.png) [@etienne](https://community.plotly.com/u/etienne)\
**Post date:** [December 19, 2017, 1:27pm UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/2 "2017-12-19T13:27:43Z")

</div>

Not easily at the moment.

You can subscribe to [https://github.com/plotly/plotly.js/issues/2173](https://github.com/plotly/plotly.js/issues/2173) for the most up-to-date development info.

---

<div class="post-metadata">

**Author:** ![Sachin\_Dev\_Sharma](https://avatars.discourse-cdn.com/v4/letter/s/3bc359/32.png) [@Sachin\_Dev\_Sharma](https://community.plotly.com/u/Sachin_Dev_Sharma)\
**Post date:** [July 24, 2020, 5:25am UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/3 "2020-07-24T05:25:06Z")

</div>

@Daifaityr234 Here is the code snippet.

```auto
app=dash.Dash()

app.layout = html.Div([
                dcc.Graph(id='graph',figure=fig),
                html.Pre(id='relayout-data', style=styles['pre']),
                dcc.Graph(id='graph2', figure=fig)])

@app.callback(Output('relayout-data', 'children'),
              [Input('basic-interactions', 'relayoutData')])
def display_relayout_data(relayoutData):
    return json.dumps(relayoutData, indent=2)

@app.callback(Output('graph2', 'figure'),
             [Input('graph', 'relayoutData')], # this triggers the event
             [State('graph2', 'figure')])
def graph_event(select_data, fig):
    try:
       fig['layout'] = {'xaxis':{'range':[select_data['xaxis.range[0]'],select_data['xaxis.range[1]']]}}
    except KeyError:
       fig['layout'] = {'xaxis':{'range':[zoomed out value]}}
return fig

app.run_server()

```

---

<div class="post-metadata">

**Author:** ![cl\_frp](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@cl\_frp](https://community.plotly.com/u/cl_frp)\
**Post date:** [April 6, 2021, 9:12pm UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/4 "2021-04-06T21:12:55Z")

</div>

would you have a full working example that I could run for this? I have an app where I generate a few rows of graphs via a loop. Each row contains two graphs. For each row, I want to be able to zoom on one graph and automatically update the zoom on the graph in the same row. I think your code could help but unable to test it to try and understand how it works. Thanks.

---

<div class="post-metadata">

**Author:** ![Sachin\_Dev\_Sharma](https://avatars.discourse-cdn.com/v4/letter/s/3bc359/32.png) [@Sachin\_Dev\_Sharma](https://community.plotly.com/u/Sachin_Dev_Sharma)\
**Post date:** [April 11, 2021, 1:05pm UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/5 "2021-04-11T13:05:44Z")

</div>

@cl_frp Here is the test code

```
fig={'data':[go.Scatter(x=np.random.randint(1,100,10), y=np.random.randint(1,100,10),mode='markers')]}

app=dash.Dash()

app.layout = html.Div([
dcc.Graph(id='graph',figure=fig ),
html.Pre(id='relayout-data', style={'border': 'thin lightgrey solid','overflow':'scroll'}),
dcc.Graph(id='graph2', figure=fig )])

@app.callback(Output('relayout-data', 'children'),
                      [Input('graph', 'relayoutData')])
def display_relayout_data(relayoutData):
     return json.dumps(relayoutData, indent=2)

@app.callback(Output('graph2', 'figure'),
             [Input('graph', 'relayoutData')], 
             [State('graph2', 'figure')])
def graph_event(select_data, fig):
    try:
        fig['layout'] = {'xaxis':{'range':[select_data['xaxis.range[0]'],select_data['xaxis.range[1]']]},
                         'yaxis':{'range':[select_data['yaxis.range[0]'],select_data['yaxis.range[1]']]}}
    except KeyError:
        fig['layout'] = {'xaxis':{'range':[0,100]},
                         'yaxis':{'range':[0,100]}}
    
    return fig

app.run_server()
```

---

<div class="post-metadata">

**Author:** ![cl\_frp](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@cl\_frp](https://community.plotly.com/u/cl_frp)\
**Post date:** [April 27, 2021, 8:32pm UTC](https://community.plotly.com/t/link-zoom-and-pan-actions-for-all-subplots/7387/6 "2021-04-27T20:32:36Z")

</div>

> [@Sachin\_Dev\_Sharma](#):
>
> ```auto
> fig={'data':[go.Scatter(x=np.random.randint(1,100,10), y=np.random.randint(1,100,10),mode='markers')]}
> 
> app=dash.Dash()
> 
> app.layout = html.Div([
> dcc.Graph(id='graph',figure=fig ),
> html.Pre(id='relayout-data', style={'border': 'thin lightgrey solid','overflow':'scroll'}),
> dcc.Graph(id='graph2', figure=fig )])
> 
> @app.callback(Output('relayout-data', 'children'),
> [Input('graph', 'relayoutData')])
> def display_relayout_data(relayoutData):
> return json.dumps(relayoutData, indent=2)
> 
> @app.callback(Output('graph2', 'figure'),
> [Input('graph', 'relayoutData')], 
> [State('graph2', 'figure')])
> def graph_event(select_data, fig):
> try:
> fig['layout'] = {'xaxis':{'range':[select_data['xaxis.range[0]'],select_data['xaxis.range[1]']]},
> 'yaxis':{'range':[select_data['yaxis.range[0]'],select_data['yaxis.range[1]']]}}
> except KeyError:
> fig['layout'] = {'xaxis':{'range':[0,100]},
> 'yaxis':{'range':[0,100]}}
>     
> return fig
> 
> ```

Thanks a lot for this. It works great though when I try adding a third graph which I’d like to update similarly to graph2 I get errors. I don’t know how to check the shape/content of “select\_data” so hard to fix it. That’s what I tried:

```auto
import plotly.graph_objects as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import numpy as np

fig={'data':[go.Scatter(x=np.random.randint(1,100,10), y=np.random.randint(1,100,10),mode='markers')]}

app=dash.Dash()

app.layout = html.Div([
dcc.Graph(id='graph',figure=fig ),
html.Pre(id='relayout-data', style={'border': 'thin lightgrey solid','overflow':'scroll'}),
dcc.Graph(id='graph2', figure=fig ),
dcc.Graph(id='graph3', figure=fig ),
])

@app.callback(Output('relayout-data', 'children'),
                      [Input('graph', 'relayoutData')])

def display_relayout_data(relayoutData):
     return json.dumps(relayoutData, indent=2)

@app.callback(Output('graph2', 'figure'),
              Output('graph3', 'figure'),
             [Input('graph', 'relayoutData')],
             [State('graph2', 'figure')],
             [State('graph3', 'figure')])

def graph_event(select_data, fig):
    try:
        fig['layout'] = {'xaxis':{'range':[select_data['xaxis.range[0]'], select_data['xaxis.range[1]'], select_data['xaxis.range[2]']]},
                         'yaxis':{'range':[select_data['yaxis.range[0]'], select_data['yaxis.range[1]'], select_data['yaxis.range[2]']]}}
    except KeyError:
        fig['layout'] = {'xaxis':{'range':[0,100]},
                         'yaxis':{'range':[0,100]}}

    return fig

if __name__ == ' __main__':
    app.run_server()

```

Thank you very much.
