[英]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。
使用該figure
的relayoutData
屬性將在這里有所幫助。 單擊圖窗范圍選擇器中的任何按鈕將觸發一個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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.