簡體   English   中英

當 plotly 圖表中的 x 軸發生變化時,如何自動調整 y 軸?

[英]How do I auto-adjust the y-axis when the x-axis changes in a plotly chart?

我有一個 plotly 圖表,它使用了一個看起來像這樣的范圍選擇器 -

import datetime
import dash
from dash import dcc, html
import plotly
from dash.dependencies import Input, Output
from pyorbital.orbital import Orbital
satellite = Orbital('TERRA')

app = dash.Dash(__name__)
app.layout = html.Div(
    html.Div([
        html.H4('TERRA Satellite Live Feed'),
        html.Div(id='live-update-text'),
        dcc.Graph(id='live-update-graph'),
        dcc.Interval(
            id='interval-component',
            interval=1*1000, # in milliseconds
            n_intervals=0
        )
    ])
)


@app.callback(Output('live-update-text', 'children'),
              Input('interval-component', 'n_intervals'))
def update_metrics(n):
    lon, lat, alt = satellite.get_lonlatalt(datetime.datetime.now())
    style = {'padding': '5px', 'fontSize': '16px'}
    return [
        html.Span('Longitude: {0:.2f}'.format(lon), style=style),
        html.Span('Latitude: {0:.2f}'.format(lat), style=style),
        html.Span('Altitude: {0:0.2f}'.format(alt), style=style)
    ]


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live(n):
    satellite = Orbital('TERRA')
    data = {
        'time': [],
        'Latitude': [],
        'Longitude': [],
        'Altitude': []
    }

    # Collect some data
    for i in range(180):
        time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
        lon, lat, alt = satellite.get_lonlatalt(
            time
        )
        data['Longitude'].append(lon)
        data['Latitude'].append(lat)
        data['Altitude'].append(alt)
        data['time'].append(time)

    # Create the graph with subplots
    fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {
        'l': 30, 'r': 10, 'b': 30, 't': 10
    }
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}

    fig.append_trace({
        'x': data['time'],
        'y': data['Altitude'],
        'name': 'Altitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 1, 1)
    fig.append_trace({
        'x': data['Longitude'],
        'y': data['Latitude'],
        'text': data['time'],
        'name': 'Longitude vs Latitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 2, 1)
    fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
        buttons=list([
            dict(count=1,
                 label="1d",
                 step="day",
                 stepmode="backward")
        ])
        )
        type="date"
    )



    return fig


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

我從這里的 wiki 中提取了這個示例代碼。

每當有人單擊將數據過濾回最近一天的數據的按鈕時,我想自動調整 y 軸。 要使用 wiki 頁面中的示例“帶有范圍滑塊和選擇器的時間序列”,我希望 y 軸從默認值 90 到 130 更改為新值 120 到 130。

使用該figurerelayoutData屬性將在這里有所幫助。 單擊圖窗范圍選擇器中的任何按鈕將觸發一個relayoutData事件,我們可以將其用作回調的輸入。 在此回調中,我們將根據需要更改yaxis范圍(在此示例中,我通過對所選日期范圍執行 diff 並檢查它是否等於1來檢查按下的按鈕是否為1d - 如果是,則將范圍更改為 120- 130,否則恢復正常)。
我在這個問題的答案的幫助下回答了。

import datetime
import dash
from dash import dcc, html
import plotly
from dash.dependencies import Input, Output, State
from pyorbital.orbital import Orbital
from dateutil import parser

satellite = Orbital('TERRA')

app = dash.Dash(__name__)
app.layout = html.Div(
    html.Div([
        html.H4('TERRA Satellite Live Feed'),
        html.Div(id='live-update-text'),
        dcc.Graph(id='live-update-graph'),
        dcc.Interval(
            id='interval-component',
            interval=10*1000, # in milliseconds
            n_intervals=0
        ),
        dcc.Store(id='zoom_info')
    ])
)


@app.callback(Output('live-update-text', 'children'),
              Input('interval-component', 'n_intervals'))
def update_metrics(n):
    lon, lat, alt = satellite.get_lonlatalt(datetime.datetime.now())
    style = {'padding': '5px', 'fontSize': '16px'}
    return [
        html.Span('Longitude: {0:.2f}'.format(lon), style=style),
        html.Span('Latitude: {0:.2f}'.format(lat), style=style),
        html.Span('Altitude: {0:0.2f}'.format(alt), style=style)
    ]


@app.callback(
    Output('zoom_info', 'data'),
    Input('live-update-graph', 'relayoutData')
)
def update_interval(relayout_data):
    if relayout_data is not None and f'xaxis.range[0]' in relayout_data:
        start_date = parser.parse(relayout_data['xaxis.range[0]'])
        end_date = parser.parse(relayout_data['xaxis.range[1]'])
        days_diff = (end_date - start_date).days
        if days_diff == 1:
            zoom_info = [120, 130]
        else:
            zoom_info = None
        return zoom_info
    else:
        return None


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph', 'figure'),
              Input('interval-component', 'n_intervals'),
              State('zoom_info', 'data'))
def update_graph_live(n, zoom_info):
    satellite = Orbital('TERRA')
    data = {
        'time': [],
        'Latitude': [],
        'Longitude': [],
        'Altitude': []
    }

    # Collect some data
    for i in range(180):
        time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
        lon, lat, alt = satellite.get_lonlatalt(
            time
        )
        data['Longitude'].append(lon)
        data['Latitude'].append(lat)
        data['Altitude'].append(alt)
        data['time'].append(time)

    # Create the graph with subplots
    fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {
        'l': 30, 'r': 10, 'b': 30, 't': 10
    }
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}

    fig.append_trace({
        'x': data['time'],
        'y': data['Altitude'],
        'name': 'Altitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 1, 1)
    fig.append_trace({
        'x': data['Longitude'],
        'y': data['Latitude'],
        'text': data['time'],
        'name': 'Longitude vs Latitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 2, 1)
    fig.update_layout(
        xaxis=dict(
            rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1d",
                     step="day",
                     stepmode="backward")
            ])
            ),
            type="date")
    )
    if zoom_info:
        fig['layout'][f'yaxis']['range'] = [
            zoom_info[0],
            zoom_info[1]
        ]
    return fig


if __name__ == '__main__':
    app.run_server(debug=True)
  • 編輯 - 根據 OP 的要求更改答案(包括間隔更新和 y 軸縮放)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM