Plotly:如何仅将垂直和水平线(十字准线)显示为 hoverinfo?

2022-01-21 00:00:00 python plotly plotly-dash

问题描述

我想在 plotly dash 中绘制一个带有两个子图的图表.我的整个图表如下所示:

将 pandas 导入为 pd将 numpy 导入为 np导入破折号将 dash_core_components 导入为 dcc将 dash_html_components 导入为 html导入 plotly.graph_objs从 plotly.subplots 导入 make_subplotsdf = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv').iloc[:60]fig = make_subplots(rows=2, cols=1, row_heights=[0.8, 0.2], vertical_spacing=0)fig.add_trace(go.Candlestick(open=df['AAPL.Open'], high=df['AAPL.High'], low=df['AAPL.Low'], close=df['AAPL.Close'],增加线颜色='#0384fc',减少线颜色='#e8482c',名称='AAPL'),行=1,列=1)fig.add_trace(go.Scatter(y=np.random.randint(20, 40, len(df)), marker_color='#fae823', name='VO', hovertemplate=[]), row=2, col=1)fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},图例=dict(y=1, x=0),font=dict(color='#dedddc'),dragmode='pan',hovermode='x Unified',边距=dict(b=20, t=0, l=0, r=40))fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,showspikes=True,spikemode='across',spikesnap='data',showline=False,spikedash='solid')fig.update_yaxes(showgrid=False, zeroline=False)fig.update_traces(xaxis='x', hoverinfo='none')app = dash.Dash(__name__)app.layout = html.Div(儿童=[html.Div(dcc.Graph(id='chart', figure=fig, config={'displayModeBar': False}))])如果 __name__ == '__main__':app.run_server(debug=True, dev_tools_ui=False, dev_tools_props_check=False)

我需要的是交易图表中常见的所谓十字准线.基本上它由连接到 x 和 y 轴并随光标移动的两条线组成.这是 tradingview.com 图表的屏幕截图:

但是在我的图表中,当光标位于烛台上时会出现一个小图标:

到目前为止,我发现当光标在散点图上时,图标消失并且工作正常.我认为这是因为我在散点图中设置了 hovertemplate=[] .我不能在烛台图中这样做,因为它没有这样的参数.此外,这个图标只有在我设置 hovermode='x Unified' 时才会出现.如果我将其设置为 x,则不会出现小图标.但我需要它与我展示的 tradingview.com 示例完全相同.有没有办法复制那个十字准线?

更新 1:

我试过 fig.update_layout(hoverdistance=0).但问题是,当光标不在烛台上时,十字准线就不对了.我截取了两张截图:第一张来自 tradingview.com 图表,第二张来自我的代码,其中 hoverdistance 设置为 0.可以看出,当光标不在烛台上时,在第一个屏幕截图中,十字准线仍然正确.但是,在第二个屏幕截图中,它无法正常工作.仅当光标仅在烛台上时才有效.我只想复制

<块引用>

悬停距离

设置查找数据的默认距离(以像素为单位)添加悬停标签(-1 表示不截止,0 表示不查找数据).这只是悬停在点状物体上的真实距离,例如散点.对于类似区域的对象(条形、散点填充等)悬停在该区域内并在该区域外关闭,但这些对象将在发生冲突时不要取代悬停在点状物体上.

完整代码:(但没有破折号元素)

将 pandas 导入为 pd将 numpy 导入为 np导入 plotly.graph_objs从 plotly.subplots 导入 make_subplotsdf = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv').iloc[:60]fig = make_subplots(rows=2, cols=1, row_heights=[0.8, 0.2], vertical_spacing=0)fig.add_trace(go.Candlestick(open=df['AAPL.Open'], high=df['AAPL.High'], low=df['AAPL.Low'], close=df['AAPL.Close'],增加线颜色='#0384fc',减少线颜色='#e8482c',名称='AAPL'),行=1,列=1)fig.add_trace(go.Scatter(y=np.random.randint(20, 40, len(df)), marker_color='#fae823', name='VO', hovertemplate=[]), row=2, col=1)fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},图例=dict(y=1, x=0),font=dict(color='#dedddc'),dragmode='pan',hovermode='x Unified',边距=dict(b=20, t=0, l=0, r=40))fig.update_yaxes(showgrid=False, zeroline=False, showticklabels=False,showspikes=True,spikemode='across',spikesnap='cursor',showline=False,spikedash='solid')fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,showspikes=True,spikemode='across',spikesnap='cursor',showline=False,spikedash='solid')fig.update_layout(hoverdistance=0)fig.update_traces(xaxis='x', hoverinfo='none')图.show()

I want to plot a chart with two subplots in plotly dash. My entire chart looks like this:

import pandas as pd
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from plotly.subplots import make_subplots
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv').iloc[:60]
fig = make_subplots(rows=2, cols=1, row_heights=[0.8, 0.2], vertical_spacing=0)

fig.add_trace(go.Candlestick(open=df['AAPL.Open'], high=df['AAPL.High'], low=df['AAPL.Low'], close=df['AAPL.Close'],
                             increasing_line_color='#0384fc', decreasing_line_color='#e8482c', name='AAPL'), row=1, col=1)

fig.add_trace(go.Scatter(y=np.random.randint(20, 40, len(df)), marker_color='#fae823', name='VO', hovertemplate=[]), row=2, col=1)

fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},
                  legend=dict(y=1, x=0),
                  font=dict(color='#dedddc'), dragmode='pan', hovermode='x unified',
                  margin=dict(b=20, t=0, l=0, r=40))

fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,
                 showspikes=True, spikemode='across', spikesnap='data', showline=False, spikedash='solid')

fig.update_yaxes(showgrid=False, zeroline=False)
fig.update_traces(xaxis='x', hoverinfo='none')

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    html.Div(dcc.Graph(id='chart', figure=fig, config={'displayModeBar': False}))])

if __name__ == '__main__':
    app.run_server(debug=True, dev_tools_ui=False, dev_tools_props_check=False)

What I need is a so called crosshair that is common in trading charts. Basically it consists of two lines that are connected to x and y axes and moves with cursor. This is a screenshot from tradingview.com charts:

However in my chart there is a little icon that appears when the cursor is on candlesticks:

What I have found out so far is that when the cursor is on the scatter plot, the icon disappears and it works fine. I think that is because I set hovertemplate=[] in the scatterplot. I cannot do that in the candlestick plot because there is no such parameter for it. Moreover, this icon only appears if I set hovermode='x unified'. If I set it to x, the little icon doesn't appear. But I need it to be exactly like the tradingview.com example that I showed. Is there any way to replicate that crosshair?

UPDATE 1:

I tried fig.update_layout(hoverdistance=0). But the problem is that when the cursor is not on the candlesticks, the crosshair is just not right. I took two screenshots: the first one is from tradingview.com charts and the second one is from my code with hoverdistance set to 0. As can be seen, when the cursor is not on the candlesticks, in the first screenshot the crosshair is still correct. However, in the second screenshot it is just not working correctly. It only works if the cursor is on the candlesticks ONLY. I just want to copy tradingview.com crosshair. Nothing less and nothing more.

UPDATE 2:

I think the answer could be on these plotly docs. I am working on it currently. Please share your comments about this update.

解决方案

This should do it:

fig.update_layout(hoverdistance=0)

And setting spikesnap='cursor' for xaxes and yaxes.

These little adjustments will keep the crosshair intact and remove the little icon that has been bothering you.

From the docs:

Plot:

hoverdistance

Sets the default distance (in pixels) to look for data to add hover labels (-1 means no cutoff, 0 means no looking for data). This is only a real distance for hovering on point-like objects, like scatter points. For area-like objects (bars, scatter fills, etc) hovering is on inside the area and off outside, but these objects will not supersede hover on point-like objects in case of conflict.

Complete code: (but with no dash elements)

import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.subplots import make_subplots

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv').iloc[:60]
fig = make_subplots(rows=2, cols=1, row_heights=[0.8, 0.2], vertical_spacing=0)

fig.add_trace(go.Candlestick(open=df['AAPL.Open'], high=df['AAPL.High'], low=df['AAPL.Low'], close=df['AAPL.Close'],
                             increasing_line_color='#0384fc', decreasing_line_color='#e8482c', name='AAPL'), row=1, col=1)

fig.add_trace(go.Scatter(y=np.random.randint(20, 40, len(df)), marker_color='#fae823', name='VO', hovertemplate=[]), row=2, col=1)

fig.update_layout({'plot_bgcolor': "#21201f", 'paper_bgcolor': "#21201f", 'legend_orientation': "h"},
                  legend=dict(y=1, x=0),
                  font=dict(color='#dedddc'), dragmode='pan', hovermode='x unified',
                  margin=dict(b=20, t=0, l=0, r=40))

fig.update_yaxes(showgrid=False, zeroline=False, showticklabels=False,
                 showspikes=True, spikemode='across', spikesnap='cursor', showline=False, spikedash='solid')

fig.update_xaxes(showgrid=False, zeroline=False, rangeslider_visible=False, showticklabels=False,
                 showspikes=True, spikemode='across', spikesnap='cursor', showline=False, spikedash='solid')

fig.update_layout(hoverdistance=0)

fig.update_traces(xaxis='x', hoverinfo='none')
fig.show()

相关文章