Updating the Range Slider (range/marks) with callbacks in dash


#1

Hello,

I’m creating a dash app and having difficulty with updating a dcc.RangeSlider component.

I am using a rangeslider to dynamically update five plots concurrently and it works great. However I now would like to add a dropdown box that chooses between two datasets to display on these graphs as well. The datasets are of different lengths, therefore the rangeslider needs a different minimum and maximum to display data properly. Therefore the dropdown box should update the options within the rangeslider component, as well as which dataset is displayed in each graph. From the looks of it however, the dropdown is not successfully updating the slider, because the slider does not display any marks and both min and max values default to being 0.

My first attempt involved creating a dictionary where the two values of the dropdown correspond to the two different set of options for the rangeslider.

slider_options = {"H": dict(updatemode = 'mouseup', min = 0, max = 7200, value = [0, 7200], pushable = 1, allowCross = False), "L": dict(updatemode = 'mouseup', min = 0, max = 360, value = [0, 360], pushable = 1, allowCross = False)}

Below is the callback function that updates the rangeslider options. I’ve tried changing a few variables but nothing’s worked so far.

@app.callback(Output('time-slider', 'children'), [Input('my-dropdown', 'value')]) def change_range(dropdown_value): return slider_options(dropdown_value)

And this is what my rangeslider looks like in the code;

html.Div( dcc.RangeSlider(id = 'time-slider'), style = {'marginLeft': 200, 'marginRight': 200, 'marginBottom': 50, 'marginTop': 50 }),

tldr; Essentially what I want to know is how to successfully use a callback function to update the options inside a rangeslider component. Could someone provide an example of something like this working?

Please let me know where I’m going wrong/if this functionality is even possible at this stage.

Thanks very much.


#2

You don’t want to target the slider’s children property, as that corresponds to the child layout elements. Since you can only target a single property of an element as an output, I think that means what you’re going to have to do is create two different slider components initialised with all the properties for each. Then your dropdown callback needs to select the appropriate Slider (can use the same dictionary lookup approach you’re using) and insert it into the children property of the element that you want to contain the slider.

To avoid code repetition, it might be cleaner to have your initial app.layout not include the initial slider (the automatic initial firing of the callback will insert it for you). I think that means you’ll have to set app.config.suppress_callback_exceptions = True since the initial layout won’t then include the Slider element which is the Input for the slider callback.