Search code examples
pythonplotlyplotly-python

Display only single line on hover, hide all other lines


Is there is a way to hide all other lines on a figure, when I am hovering a single one?

Example:

import numpy as np
import plotly.express as px

np.random.seed(42)
data = np.random.randint(0, 10, (5, 10))
fig = px.line(data_frame=pd.DataFrame(data))

fig.show()

will produce:

enter image description here

and I want this, when I hover particular line (but without manually switching off all other lines and keeping X, Y axes dims):

enter image description here

UPD: inside jupyter notebook


Solution

  • import plotly.graph_objects as go
    import numpy as np
    import pandas as pd
    
    # callback function for on_hover
    def hide_traces_on_hover(trace, points, selector):
        if len(points.point_inds)==1: # identify hover
            i = points.trace_index # get the index of the hovered trace
            f.data[i].visible = True # keep the hovered trace visible
            # create a list of traces you want to hide
            hide_traces = [l_trace for idx, l_trace in enumerate(f.data) if idx != i] 
            for l_trace in hide_traces: # iterate over hide_traces
                l_trace.visible = 'legendonly' # hide all remaining traces
        
    # callback function to unhide traces on click
    def unhide_traces_on_click(trace, points, selector):
        for l_trace in f.data:
            l_trace.visible = True
            
    # your sample data frame
    np.random.seed(42)
    data = np.random.randint(0, 10, (5, 10))
    df = pd.DataFrame(data)
    
    f = go.FigureWidget() # create figure widget
    
    f.update_yaxes(autorange=False) # set auto range to false
    # define the range of the y-axis using min and max functions
    f.update_layout(yaxis_range=[df.values.min()-1, df.values.max()+1])
    
    # create your traces from the data frame
    for col in df.columns:
        trace = go.Scatter(x=df.index, y=df[col], mode='lines+markers')
        f.add_trace(trace)
    
    # assign your functions to each trace
    for trace in f.data:
        trace.on_hover(hide_traces_on_hover)
        trace.on_click(unhide_traces_on_click)
    
    f
    

    If you are running into issues, here is the jupyter notebook support documentation for using FigureWidget and here is the jupyter lab support documentation. Make sure you have the ipywidgets package installed. Also, just as a FYI, here is the FigureWidget documentation.

    When you hover over a marker in the graph.

    enter image description here

    When you click on any marker of the visible trace all the hidden traces will become visible again.

    enter image description here