Does dcc.Graph have an equivalent to a Dash Leafleft hideout-

I’ve been spending the last few weeks getting into the weeds with Dash Leaflet, which is an outstanding library (thanks @Emil !). There is a hideout concept which allows for super quick filtering (which I use with geojsons) and can be done clientside. I’ve played around with hiding/showing traces in a callback via the “figure”, but I’m not sure if there is a better way of doing it. Right now, if I want a graph that filters via some input, I can search the figure data via a loop and find which trace to expose and set the others to hidden. But with leaflet, I can filter via the hideout and there is no need to loop anything (or really write much code at all).

For example:

I would then create a figure with let’s say ~100 traces (Trace1-Trace100) but want to quickly filter the traces without having to loop through the entire figure. Applying the leaflet concept, the dcc.Figure could have a hideout prop that sets which traces are visible. I could then populate the entire graph (100 traces) but use the hideout client side to quickly filter the chart.

A simple code example would be:

fig = go.Figure()
for i in range(0,100):
  fig.add_trace(go.Scatter(
  x=SOMEDATA,
  y=SOMEDATA,
  name=f'Trace{i}'
  ))

myHideout = ["Trace1","Trace2","Trace3"]
dcc.Graph(figure=fig,hideout=myHideout)

And the graph would only show those traces and I could set the hideout via a callback (clientside) and it would automatically filter the graph. Does anything like this exist now? Or is it best to just loop through the fig[‘data’] (loop or list comprehension)?

Hi @bgivens33,

I think you will actually have to change the figure.

Without looping it’ll get difficult, but at least you don’t need to loop “manually” as you can use for_each_trace()

An example:

  • create 100 traces
  • assign random name out of 10 names
import plotly.graph_objects as go
import random

fig = go.Figure()
for _ in range(100):
    fig.add_scatter(
        x=np.arange(10), 
        y=np.random.randint(0,10,10), 
        name=random.choice([f'Trace{i}' for i in range(10)]), 
        visible=True
    )
fig.update_layout(height=600, width=600)

Pretty crowded, right? Define your HideOut

myHideout = ["Trace1","Trace2","Trace3"]

fig.for_each_trace(lambda x: x.update({'visible': ['legendonly', True][x.name in myHideout]}))

If you want to hide the trace completely (including legend):

fig.for_each_trace(lambda x: x.update({'visible': x.name in myHideout}))

You could also use the Patch() in a similar way, this time you will have to loop “manually” thru all traces:

1 Like