How to combine slider and button?

Hi all,

I would like to combine slider and button. Lets say we have 3 surfaces at 3 different depths.

When i sliding through different depths i would like to toggle on/off additional traces at that particular depth with buttons.

So far i got a working slider but no luck with buttons. I created a minimal example below. Hope you can help me.

import plotly.graph_objs as go


z1 = [
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4]
]

z2 = [[zij-1 for zij in zi] for zi in z1]
z3 = [[zij-2 for zij in zi] for zi in z1]


fig = go.Figure()


for step in range(3):
    
    fig.add_trace(go.Surface(z=z1, colorscale='hsv', visible=False, showscale=False)),
    fig.add_trace(go.Surface(z=z2, colorscale='hsv', visible=False, showscale=False)),
    fig.add_trace(go.Surface(z=z3, colorscale='hsv', visible=False, showscale=False)),



# Show First Layer
fig.data[0].visible = True


# Create slider

depth=[4,3,2]

steps = []
for i in range(3):   

    step = dict(method="update",
                label = str(depth[i]),
                args = [{"visible": [False] * len(fig.data)},
                        {"title": "Depth: " + str(depth[i])}
                        ],  
                )
    
    step["args"][0]["visible"][i] = True  
    steps.append(step)


sliders = [dict(active=0, 
                currentvalue={"prefix": "Depth: ", "suffix": " km"},
                pad={"t": 50},
                steps=steps)
           ]





# 3d Scatter (Visible False)
test_data = fig.add_trace(go.Scatter3d(x=[4],y=[6],z=[3.05],visible=False,
                           marker=dict(symbol='circle',size=10,color='red')))



# Add dropdown
fig.update_layout(updatemenus=[dict(type = "buttons", direction = "left",

                                    buttons=list([dict(args=[{"visible":True},test_data],
                                                  method="update",
                                                  label="Show Scatter"
                                                       )
                                                  ]
                                                 ),
                                    
                                    pad={"r": 0, "t": 30},
                                    showactive=True,
                                    x=0.11,
                                    xanchor="left",
                                    y=1.1,
                                    yanchor="top"
                                    
                                    )
                               ]
                  )




fig.update_layout(scene=dict(zaxis=dict(range=[1, 5],autorange=False)), sliders=sliders)
                  

fig.show()

I made some progress. Here’s the current code:

import plotly.graph_objs as go

z1 = [
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4],
    [4,4,4,4,4,4]
]

z2 = [[zij-1 for zij in zi] for zi in z1]
z3 = [[zij-2 for zij in zi] for zi in z1]



fig = go.Figure()

for step in range(3):

    # Surface Traces
    fig.add_trace(go.Surface(z=z1, colorscale='hsv', visible=False, showscale=False)),
    fig.add_trace(go.Surface(z=z2, colorscale='hsv', visible=False, showscale=False)),
    fig.add_trace(go.Surface(z=z3, colorscale='hsv', visible=False, showscale=False)),

    # Scatter Traces
    fig.add_trace(go.Scatter3d(x=[4],y=[6],z=[4.0],visible=False, showlegend=False, marker=dict(symbol='circle',size=10,color='red')))
    fig.add_trace(go.Scatter3d(x=[4],y=[6],z=[3.0],visible=False, showlegend=False, marker=dict(symbol='circle',size=10,color='red')))
    fig.add_trace(go.Scatter3d(x=[4],y=[6],z=[2.0],visible=False, showlegend=False, marker=dict(symbol='circle',size=10,color='red')))


# Visibility Options
#   Surface4km  Surface3km  Surface2km   Scatter4km  Scatter3km  Scatter2km
a = [True,      False,      False,       True,       False,      False]
b = [False,     True,       False,       False,      True,       False]
c = [False,     False,      True,        False,      False,      True]


# Show First Layer
fig.data[0].visible = True


# Create slider
depth=[4,3,2]

steps = []
for i in range(3):   

    step = dict(method="update",
                label = str(depth[i]),
                args = [{"visible": [False] * len(fig.data)},
                        {"title": "Depth: " + str(depth[i])}
                        ],  
                )
    
    step["args"][0]["visible"][i] = True  
    steps.append(step)


    # Add dropdown
    updatemenus=[dict(type = "buttons", direction = "left",

                                    buttons=list([dict(args=[{'visible': c }],  #This part is the problem
                                                  method="restyle",
                                                  label="Show Scatter"
                                                       )
                                                  ]
                                                 ),
                                    
                                    pad={"r": 0, "t": 30},
                                    showactive=True,
                                    x=0.11,
                                    xanchor="left",
                                    y=1.1,
                                    yanchor="top"
                                    
                                    )
                               ]
                 

sliders = [dict(active=0, 
                currentvalue={"prefix": "Depth: ", "suffix": " km"},
                pad={"t": 50},
              
                steps=steps)
           ]


fig.update_layout(scene=dict(zaxis=dict(range=[1, 5],autorange=False),
                             xaxis=dict(range=[0, 5],autorange=False),
                             yaxis=dict(range=[1, 14],autorange=False)
                             ),
                  
                  sliders=sliders,
                  updatemenus=updatemenus
                  )
                  
fig.show()

Initial figure below (while args=[{‘visible’: c } # Surface 2km, Scatter 2km

When i clicked the button it immediately jumps args=[{‘visible’: c }. But i would like to show/hide traces depending on the current value of the slider. Lets say if slider is at 3km, when click the button args=[{‘visible’: } must be args=[{‘visible’: b }

I hope I could explain :sweat_smile:

It’s possible to combine slider and button by adding the sliders in the args

buttons += [
                dict(
                    label="X", method="update",
                    args=[
                        {"visible": [True, False, ...]}, {"sliders": sliders},
                    ]
                )
            ]