Dash 中四个图形的同步缩放。如何实施?

Synchronous zoom of four graphs in Dash. How to implement?

大家下午好! :)

这是什么问题。我有 4 个图,挑战是保持它们同步缩放(即,如果您放大 1 个图,那么其余图也会放大,等等)。

现在我所做的就是可以放大一个特定的图表 ('graph1'),其余的也随之放大。这是它的样子。

@app.callback(
              Output('graph1', 'figure'), Output('graph2', 'figure'), Output('graph3', 'figure'),Output('graph4', 'figure'),
              Input('graph1', 'relayoutData'),
              State('graph1', 'figure'), State('graph2', 'figure'), State('graph3', 'figure'), State('graph4', 'figure')
              )
def zoom_event(relayout_data, *figures):
    outputs = []
    for fig in figures:
        try:

            fig['layout']["xaxis"]["range"] = [relayout_data['xaxis.range[0]'], relayout_data['xaxis.range[1]']]
            fig['layout']["xaxis"]["autorange"] = False
        except (KeyError, TypeError) as e:
            fig['layout']["xaxis"]["autorange"] = True

        outputs.append(fig)
    return outputs

如果你尝试做一些看起来像同步图表的事情,你会得到无数的错误。我试着做了2个带子图的图形,甚至一个带4个子图的图形,但都是徒劳的。

后者之一是输出接受的输入多于输出。但是具体在这个error中我还没有想通。我试过了。

@app.callback(
Output('graph1', 'figure'), Output('graph2', 'figure'), Output('graph3', 'figure'), Output('graph4', 'figure'),
Input('graph1', 'relayoutData'), Input('graph2', 'relayoutData'), Input('graph3', 'relayoutData'), Input('graph4', 'relayoutData'), 
State('graph1', 'figure'), State('graph2', 'figure'), State('graph3', 'figure'), State('graph4', 'figure')
)

谢谢你敢帮忙

对于搜索,我建议去这里

参与者在这里解决了一个非常相似的问题(但是它写在 javascript 中,我很高兴听到有关如何将其组合的建议)

还有这里How to get zoom level in time series data as callback input in Dash

问题已解决

不幸的是,我可能无法显示最终代码,因为我会运行它在产品中,它可能是商业机密。

但是对于那些遇到类似问题的人,我建议你看看这个部分。

https://dash.plotly.com/sharing-data-between-callbacks

祝你成功!

我为此奋斗了一段时间,这是我最终想出的解决方案。

在我的用例中,我通过

动态添加图表
dcc.Graph({'type': 'graph', 'index': index_counter})

链接缩放行为

@app.callback(
    Output({'type': 'graph', 'index': ALL}, 'relayoutData'),
    Output({'type': 'graph', 'index': ALL}, 'figure'),
    Input({'type': 'graph', 'index': ALL}, 'relayoutData'),
    State({'type': 'graph', 'index': ALL}, 'figure'))
def LinkedZoom(relayout_data, figure_states):
    unique_data = None
    for data in relayout_data:
      if relayout_data.count(data) == 1:
        unique_data = data
    if unique_data:
      for figure_state in figure_states:
        if unique_data.get('xaxis.autorange'):
          figure_state['layout']['xaxis']['autorange'] = True
          figure_state['layout']['yaxis']['autorange'] = True
        else:
          figure_state['layout']['xaxis']['range'] = [
              unique_data['xaxis.range[0]'], unique_data['xaxis.range[1]']]
          figure_state['layout']['xaxis']['autorange'] = False
          figure_state['layout']['yaxis']['range'] = [
              unique_data['yaxis.range[0]'], unique_data['yaxis.range[1]']]
          figure_state['layout']['yaxis']['autorange'] = False
      return [unique_data] * len(relayout_data), figure_states
    return relayout_data, figure_states

参考提交: https://github.com/djhedges/exit_speed/commit/863efbf00250c79663dd460f6ab2bd54e051b9d7