在 Plotly 中悬停/单击时更改整个轨迹的颜色
问题描述
我在 plotly 中有当前图形(下面的 jupyter notebook 代码),并希望创建这样的效果,当您将鼠标悬停或单击每条迹线时,整个迹线会以不同的颜色突出显示(在本例中为红色).我尝试从 SOF 实现这些示例:
解决方案原来这是一个分两部分的问题:
- 对我来说,问题是小部件扩展没有正确启用(我可以从执行 jupyter nbextension list 中检查,输出为空),这就是为什么没有 .show() 就无法呈现无花果以及为什么on_click 功能不起作用.您可以通过首先检查 jupyter nbextension 列表来解决此问题,如果它是空的,您可以在 conda env 中尝试:
jupyter nbextension enable --py widgetsnbextension
- 我将上面的脚本固定在下面,效果很好,遗憾的是我还没有它的 gif 动图.
import plotly.graph_objects as goteam_list = 排序(teams_list,key=str.lower)default_linewidth = 2突出显示的线宽 = 3fig = go.FigureWidget() # 悬停文本放在这里fig.layout.hovermode = '最近的'fig.layout.hoverdistance = -1 #确保没有间隙"用于选择稀疏数据对于 team_list 中的 t:fig.add_trace(go.Scatter(x=elo_all.index,y=elo_all[t],名称=t,模式='线',文本=elo_all['圆形'],不透明度=0.3,line={'width': default_linewidth, 'color':'grey'}))fig.update_layout(xaxis = 字典(滴答模式 = '数组',滴答声 = [0,29,58,87,117,146],ticktext = [2015,2016,2017,2018,2019,2020]))fig.update_yaxes(范围=[1350, 1650])# 我们的自定义事件处理程序def update_trace(跟踪,点,选择器):如果 len(points.point_inds)==1:i = points.trace_index对于范围内的 x(0,len(fig.data)):fig.data[x]['line']['color'] = 'grey'fig.data[x]['不透明度'] = 0.3fig.data[x]['line']['width'] = default_linewidth#print('正确索引:{}',format(i))fig.data[i]['line']['color'] = 'red'fig.data[i]['不透明度'] = 1fig.data[i]['line']['width'] = highlight_linewidth# 我们需要将 on_click 事件分别添加到每个跟踪对于范围内的 x(0,len(fig.data)):fig.data[x].on_click(update_trace)# 显示情节如图
I have the current figure in plotly (jupyter notebook code below), and was hoping to create the effect whereby when you hover or click over each trace, the whole trace is highlighted a different colour (in this example red). I tried implementing these examples from SOF: Plotly in Python: how to highlight a trace on hover? & How do I highlight an entire trace upon hover in Plotly for Python? with no luck. If anyone could help that would be amazing. Currently each trace remains lightgrey.
import plotly.graph_objects as go
teams_list = sorted(teams_list,key=str.lower)
default_linewidth = 2
highlighted_linewidth_delta = 2
fig = go.FigureWidget()
f.layout.hovermode = 'closest'
f.layout.hoverdistance = -1 #ensures no "gaps" for selecting sparse data
for t in teams_list:
fig.add_trace(go.Scatter(x=elo_all.index,
y=elo_all[t],
name=t,
mode='lines',
text=elo_all['Round'], # hover text goes here
line={'width': default_linewidth, 'color':'lightgrey'}))
fig.update_layout(
xaxis = dict(
tickmode = 'array',
tickvals = [0,29,58,87,117,146],
ticktext = [2015,2016,2017,2018,2019,2020]
)
)
# our custom event handler
def update_trace(trace, points, selector):
# this list stores the points which were clicked on
# in all but one event they it be empty
if len(points.point_inds) > 0:
for i in range( len(fig.data) ):
fig.data[i]['line']['color'] = 'red'
# we need to add the on_click event to each trace separately
for i in range(len(fig.data)):
fig.data[i].on_hover(update_trace)
# show the plot
fig.show()
解决方案 So this was a problem in 2 parts as it turns out:
- The problem for me was that the widgets extension had not been enabled correctly (as I could check from executing jupyter nbextension list, the output was empty), which is why the fig would not render without .show() and why the on_click function did not work. You can fix this by first checking jupyter nbextension list, if it’s empty can you try in your conda env:
jupyter nbextension enable --py widgetsnbextension
- I fixed my script above to the below which works perfectly, sadly I don't have a gif of it in action yet.
import plotly.graph_objects as go
teams_list = sorted(teams_list,key=str.lower)
default_linewidth = 2
highlighted_linewidth = 3
fig = go.FigureWidget() # hover text goes here
fig.layout.hovermode = 'closest'
fig.layout.hoverdistance = -1 #ensures no "gaps" for selecting sparse data
for t in teams_list:
fig.add_trace(go.Scatter(x=elo_all.index,
y=elo_all[t],
name=t,
mode='lines',
text=elo_all['Round'],
opacity=0.3,
line={'width': default_linewidth, 'color':'grey'}))
fig.update_layout(
xaxis = dict(
tickmode = 'array',
tickvals = [0,29,58,87,117,146],
ticktext = [2015,2016,2017,2018,2019,2020]
)
)
fig.update_yaxes(range=[1350, 1650])
# our custom event handler
def update_trace(trace, points, selector):
if len(points.point_inds)==1:
i = points.trace_index
for x in range(0,len(fig.data)):
fig.data[x]['line']['color'] = 'grey'
fig.data[x]['opacity'] = 0.3
fig.data[x]['line']['width'] = default_linewidth
#print('Correct Index: {}',format(i))
fig.data[i]['line']['color'] = 'red'
fig.data[i]['opacity'] = 1
fig.data[i]['line']['width'] = highlighted_linewidth
# we need to add the on_click event to each trace separately
for x in range(0,len(fig.data)):
fig.data[x].on_click(update_trace)
# show the plot
fig
相关文章