在 plotly python 中单击而不是悬停在数据点上时显示悬停?
Display hover when clicked instead of hovering over a datapoint in plotly python?
假设我在 plotly (python) 中有一个散点图。当我将鼠标悬停在一个点上时,我会立即看到点 x 和 y 的悬停。但我想做的是点击该点,然后悬停文本将出现(并停留)。当我点击另一个点时,该点的悬停文本将出现在那里。我该怎么做?
如评论中所述,我认为您无法在 plotly 中创建此功能 python,因为仅此库无法处理标记上的点击事件。
然而,在plotly-dash
中你可以使用回调来处理clickData
(例子见the documentation),这将允许你在用户点击时修改图形一个标记。
由于您想在每个标记旁边显示文本,我认为最简单的解决方案是让文本与每个轨迹关联(每个轨迹一个标记)并将文本的 opacity
设置为0 所以它最初不显示。然后当用户点击标记时,如果文本的不透明度为 0,则文本的不透明度变为 1,或者当不透明度为 1 时变为 0。您还可以传递参数 hoverinfo='none'
来隐藏 Plotly 默认的 hoverinfo显示每个标记。
import plotly.graph_objects as go
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
app = dash.Dash()
x_array = [1,2,3,4]
y_array = [5,6,7,8]
text_array = [f"x:{x}<br>y:{y}" for (x,y) in zip(x_array,y_array)]
fig = go.Figure()
for (x,y,text) in zip(x_array,y_array,text_array):
fig.add_trace(go.Scatter(
x=[x],
y=[y],
text=[text],
marker=dict(color="blue", size=20),
textfont=dict(color='rgba(0,0,0,0)'),
textposition="middle right",
mode="markers+text",
hoverinfo='none',
showlegend=False
))
fig.update_layout(title="Display Hovertext when Clicked", title_x=0.5)
fig.update_yaxes(range=[4,10])
app.layout = html.Div(children=[
dcc.Graph(
id='example-graph',
figure=fig
)
])
@app.callback(
Output('example-graph', 'figure'),
[Input('example-graph', 'clickData')])
def toggle_text(clickData, fig=fig, x_array=x_array, y_array=y_array, text_array=text_array):
if clickData is None:
return fig
else:
trace_number = clickData['points'][0]['curveNumber']
trace_color = fig.data[trace_number].textfont.color
# print(f"you clicked on trace_number {trace_number} with color {trace_color}")
if fig.data[trace_number].textfont.color == 'rgba(0,0,0,0)':
# print(f"setting trace_number {trace_number} invisible to visible")
fig.data[trace_number].textfont.color = 'rgba(0,0,0,1)'
elif fig.data[trace_number].textfont.color == 'rgba(0,0,0,1)':
# print(f"setting trace_number {trace_number} visible to invisible")
fig.data[trace_number].textfont.color = 'rgba(0,0,0,0)'
return fig
if __name__ == '__main__':
app.run_server(debug=True)
假设我在 plotly (python) 中有一个散点图。当我将鼠标悬停在一个点上时,我会立即看到点 x 和 y 的悬停。但我想做的是点击该点,然后悬停文本将出现(并停留)。当我点击另一个点时,该点的悬停文本将出现在那里。我该怎么做?
如评论中所述,我认为您无法在 plotly 中创建此功能 python,因为仅此库无法处理标记上的点击事件。
然而,在plotly-dash
中你可以使用回调来处理clickData
(例子见the documentation),这将允许你在用户点击时修改图形一个标记。
由于您想在每个标记旁边显示文本,我认为最简单的解决方案是让文本与每个轨迹关联(每个轨迹一个标记)并将文本的 opacity
设置为0 所以它最初不显示。然后当用户点击标记时,如果文本的不透明度为 0,则文本的不透明度变为 1,或者当不透明度为 1 时变为 0。您还可以传递参数 hoverinfo='none'
来隐藏 Plotly 默认的 hoverinfo显示每个标记。
import plotly.graph_objects as go
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
app = dash.Dash()
x_array = [1,2,3,4]
y_array = [5,6,7,8]
text_array = [f"x:{x}<br>y:{y}" for (x,y) in zip(x_array,y_array)]
fig = go.Figure()
for (x,y,text) in zip(x_array,y_array,text_array):
fig.add_trace(go.Scatter(
x=[x],
y=[y],
text=[text],
marker=dict(color="blue", size=20),
textfont=dict(color='rgba(0,0,0,0)'),
textposition="middle right",
mode="markers+text",
hoverinfo='none',
showlegend=False
))
fig.update_layout(title="Display Hovertext when Clicked", title_x=0.5)
fig.update_yaxes(range=[4,10])
app.layout = html.Div(children=[
dcc.Graph(
id='example-graph',
figure=fig
)
])
@app.callback(
Output('example-graph', 'figure'),
[Input('example-graph', 'clickData')])
def toggle_text(clickData, fig=fig, x_array=x_array, y_array=y_array, text_array=text_array):
if clickData is None:
return fig
else:
trace_number = clickData['points'][0]['curveNumber']
trace_color = fig.data[trace_number].textfont.color
# print(f"you clicked on trace_number {trace_number} with color {trace_color}")
if fig.data[trace_number].textfont.color == 'rgba(0,0,0,0)':
# print(f"setting trace_number {trace_number} invisible to visible")
fig.data[trace_number].textfont.color = 'rgba(0,0,0,1)'
elif fig.data[trace_number].textfont.color == 'rgba(0,0,0,1)':
# print(f"setting trace_number {trace_number} visible to invisible")
fig.data[trace_number].textfont.color = 'rgba(0,0,0,0)'
return fig
if __name__ == '__main__':
app.run_server(debug=True)