如何在放大时动态更改绘图图表中 y 轴的 scale/ticks?
How to dynamically change the scale/ticks of y axis in plotly charts upon zooming in?
我正在尝试使用 plotly 制作蜡烛图。我正在使用跨越 10 年的股票数据。由于这个原因,蜡烛看起来非常小,因为 y 轴的比例很大。但是,如果我放大到更小的时间段(比如 10 年中的任意 1 个月),我希望 y 轴刻度发生变化,以便蜡烛看起来很大。下面是我的代码:
df_stockData = pdr.DataReader('TSLA', data_source='yahoo', start='2011-11-04', end='2021-11-04')
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, row_width=[0.25, 0.75])
fig.add_trace(go.Candlestick(
x=df_stockData.index,
open=df_stockData['Open'],
high=df_stockData['High'],
low=df_stockData['Low'],
close=df_stockData['Close'],
increasing_line_color='green',
decreasing_line_color='red',
showlegend=False
), row=1, col=1)
fig.add_trace(go.Scatter(
x=df_stockData.index,
y=df_stockData['RSI_14'],
line=dict(color='#ff9900', width=2),
showlegend=False,
), row=2, col=1
)
fig.show()
我的图表如下所示:
如您所见,y 轴(股票价格)的比例非常大。即使我放大到更小的时间段,y 轴比例也保持不变。有什么办法可以让y轴的刻度动态变化,让蜡烛在放大时显得更大?
此方法使用带破折号的 回调,根据范围滑块中选择的值设置 y-axis 的 范围。
大量代码使您的图形成为 MWE (calc RSI_14)
import pandas_datareader as pdr
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np
import dash
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
# make dataframe complete ...
df_stockData = pdr.DataReader(
"TSLA", data_source="yahoo", start="2011-11-04", end="2021-11-04"
)
def rma(x, n, y0):
a = (n - 1) / n
ak = a ** np.arange(len(x) - 1, -1, -1)
return np.r_[
np.full(n, np.nan),
y0,
np.cumsum(ak * x) / ak / n + y0 * a ** np.arange(1, len(x) + 1),
]
n = 14
df = df_stockData
df["change"] = df["Close"].diff()
df["gain"] = df.change.mask(df.change < 0, 0.0)
df["loss"] = -df.change.mask(df.change > 0, -0.0)
df["avg_gain"] = rma(
df.gain[n + 1 :].to_numpy(), n, np.nansum(df.gain.to_numpy()[: n + 1]) / n
)
df["avg_loss"] = rma(
df.loss[n + 1 :].to_numpy(), n, np.nansum(df.loss.to_numpy()[: n + 1]) / n
)
df["rs"] = df.avg_gain / df.avg_loss
df["RSI_14"] = 100 - (100 / (1 + df.rs))
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, row_width=[0.25, 0.75])
fig.add_trace(
go.Candlestick(
x=df_stockData.index,
open=df_stockData["Open"],
high=df_stockData["High"],
low=df_stockData["Low"],
close=df_stockData["Close"],
increasing_line_color="green",
decreasing_line_color="red",
showlegend=False,
),
row=1,
col=1,
)
fig.add_trace(
go.Scatter(
x=df_stockData.index,
y=df_stockData["RSI_14"],
line=dict(color="#ff9900", width=2),
showlegend=False,
),
row=2,
col=1,
)
# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dash.dcc.Graph(
id="fig",
figure=fig,
),
]
)
@app.callback(
Output("fig", "figure"),
Input("fig", "relayoutData"),
)
def scaleYaxis(rng):
if rng and "xaxis.range" in rng.keys():
try:
d = df_stockData.loc[
rng["xaxis.range"][0] : rng["xaxis.range"][1],
["High", "Low", "Open", "Close"],
]
if len(d) > 0:
fig["layout"]["yaxis"]["range"] = [d.min().min(), d.max().max()]
except KeyError:
pass
finally:
fig["layout"]["xaxis"]["range"] = rng["xaxis.range"]
return fig
app.run_server(mode="inline")
我正在尝试使用 plotly 制作蜡烛图。我正在使用跨越 10 年的股票数据。由于这个原因,蜡烛看起来非常小,因为 y 轴的比例很大。但是,如果我放大到更小的时间段(比如 10 年中的任意 1 个月),我希望 y 轴刻度发生变化,以便蜡烛看起来很大。下面是我的代码:
df_stockData = pdr.DataReader('TSLA', data_source='yahoo', start='2011-11-04', end='2021-11-04')
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, row_width=[0.25, 0.75])
fig.add_trace(go.Candlestick(
x=df_stockData.index,
open=df_stockData['Open'],
high=df_stockData['High'],
low=df_stockData['Low'],
close=df_stockData['Close'],
increasing_line_color='green',
decreasing_line_color='red',
showlegend=False
), row=1, col=1)
fig.add_trace(go.Scatter(
x=df_stockData.index,
y=df_stockData['RSI_14'],
line=dict(color='#ff9900', width=2),
showlegend=False,
), row=2, col=1
)
fig.show()
我的图表如下所示:
如您所见,y 轴(股票价格)的比例非常大。即使我放大到更小的时间段,y 轴比例也保持不变。有什么办法可以让y轴的刻度动态变化,让蜡烛在放大时显得更大?
此方法使用带破折号的 回调,根据范围滑块中选择的值设置 y-axis 的 范围。
大量代码使您的图形成为 MWE (calc RSI_14)
import pandas_datareader as pdr
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np
import dash
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
# make dataframe complete ...
df_stockData = pdr.DataReader(
"TSLA", data_source="yahoo", start="2011-11-04", end="2021-11-04"
)
def rma(x, n, y0):
a = (n - 1) / n
ak = a ** np.arange(len(x) - 1, -1, -1)
return np.r_[
np.full(n, np.nan),
y0,
np.cumsum(ak * x) / ak / n + y0 * a ** np.arange(1, len(x) + 1),
]
n = 14
df = df_stockData
df["change"] = df["Close"].diff()
df["gain"] = df.change.mask(df.change < 0, 0.0)
df["loss"] = -df.change.mask(df.change > 0, -0.0)
df["avg_gain"] = rma(
df.gain[n + 1 :].to_numpy(), n, np.nansum(df.gain.to_numpy()[: n + 1]) / n
)
df["avg_loss"] = rma(
df.loss[n + 1 :].to_numpy(), n, np.nansum(df.loss.to_numpy()[: n + 1]) / n
)
df["rs"] = df.avg_gain / df.avg_loss
df["RSI_14"] = 100 - (100 / (1 + df.rs))
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, row_width=[0.25, 0.75])
fig.add_trace(
go.Candlestick(
x=df_stockData.index,
open=df_stockData["Open"],
high=df_stockData["High"],
low=df_stockData["Low"],
close=df_stockData["Close"],
increasing_line_color="green",
decreasing_line_color="red",
showlegend=False,
),
row=1,
col=1,
)
fig.add_trace(
go.Scatter(
x=df_stockData.index,
y=df_stockData["RSI_14"],
line=dict(color="#ff9900", width=2),
showlegend=False,
),
row=2,
col=1,
)
# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dash.dcc.Graph(
id="fig",
figure=fig,
),
]
)
@app.callback(
Output("fig", "figure"),
Input("fig", "relayoutData"),
)
def scaleYaxis(rng):
if rng and "xaxis.range" in rng.keys():
try:
d = df_stockData.loc[
rng["xaxis.range"][0] : rng["xaxis.range"][1],
["High", "Low", "Open", "Close"],
]
if len(d) > 0:
fig["layout"]["yaxis"]["range"] = [d.min().min(), d.max().max()]
except KeyError:
pass
finally:
fig["layout"]["xaxis"]["range"] = rng["xaxis.range"]
return fig
app.run_server(mode="inline")