How to overlay two plots in same figure with slider

Hi Simone, welcome to the community!

I’ve found this thread that has a solution:

So in your example above, you have a for loop adding a sin(x) trace and a cos(x) trace to fig.data every iteration. If you print out fig.data, you have something like this:

(
Scatter({
    'line': {'color': 'blue', 'width': 6},
    'name': 'sin(x) = 0.0',
    'visible': False,
    'x': array([0.  , 0.01, 0.02, ..., 9.97, 9.98, 9.99]),
    'y': array([0., 0., 0., ..., 0., 0., 0.])
}), 
Scatter({
    'line': {'color': 'red', 'width': 6},
    'name': 'cos(x) = 0.0',
    'visible': False,
    'x': array([0.  , 0.01, 0.02, ..., 9.97, 9.98, 9.99]),
    'y': array([1., 1., 1., ..., 1., 1., 1.])
}), 
Scatter({
    'line': {'color': 'blue', 'width': 6},
    'name': 'sin(x) = 0.5',
    'visible': False,
    'x': array([0.  , 0.01, 0.02, ..., 9.97, 9.98, 9.99]),
    'y': array([ 0.        ,  0.00499998,  0.00999983, ..., -0.96307117, -0.9617129 ,
                -0.96033059])
}), 
Scatter({
    'line': {'color': 'red', 'width': 6},
    'name': 'cos(x) = 0.5',
    'visible': False,
    'x': array([0.  , 0.01, 0.02, ..., 9.97, 9.98, 9.99]),
    'y': array([1.        , 0.9999875 , 0.99995   , ..., 0.26924695, 0.27405892,
                0.27886404])
}),
...
)

Then the 2nd for loop iterates over fig.data to create a list telling the slider which of the above traces should be visible depending on the step. Now let’s have a look at steps:

{'method': 'update', 'args': [{'visible': [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 0'}]}
{'method': 'update', 'args': [{'visible': [False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 1'}]}
{'method': 'update', 'args': [{'visible': [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 2'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 3'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 4'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 5'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 6'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 7'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 8'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 9'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 10'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 11'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 12'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False]}, {'title': 'Slider switched to step: 13'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False]}, {'title': 'Slider switched to step: 14'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False]}, {'title': 'Slider switched to step: 15'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False]}, {'title': 'Slider switched to step: 16'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False]}, {'title': 'Slider switched to step: 17'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False]}, {'title': 'Slider switched to step: 18'}]}
{'method': 'update', 'args': [{'visible': [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True]}, {'title': 'Slider switched to step: 19'}]}

Since you added 20 traces to fig.data (10 for sin(x), 10 for cos(x)), we end up with the list above. But every entry in said list only sets the visibility to True for one trace. But what you want is to set it to True for 2 traces at the same time (so traces 1 and 2, 3 and 4, 5 and 6, 7 and 8, and so on…).

Here’s my proposed solution (probably not the best, but it does it’s job):

# Create and add slider
steps = []
for i in range(len(fig.data)):
    if i % 2 == 0:
        step = dict(
            method="update",
            args=[{"visible": [False] * len(fig.data)},
                  {"title": "Slider switched to step: " + str(i/2)}],  # layout attribute
        )
        step["args"][0]["visible"][i] = True  # Toggle i'th trace to "visible"
        step["args"][0]["visible"][i+1] = True
        steps.append(step)

I added

if i % 2 == 0

to only add every 2nd trace to the steps list and

step["args"][0]["visible"][i+1] = True

to set the next trace to True as well.

One small change was also required for the text that is being displayed: str(i/2)

Let me know if that helps!