I created a non-linear slider, but the marks are not evenly distributed on the slider. They are somehow sitting on each other. If I use linear values, the slider is working fine. But my values are in a log scale.
There is an example of a non-linear slider in the docs here, but there is a small bug in the example (the marks donβt appear). Below is an updated version so you can see the scale on the slider:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# Use the following function when accessing the value of 'my-slider'
# in callbacks to transform the output value to logarithmic
def transform_value(value):
return 10 ** value
app.layout = html.Div([
dcc.Slider(
id='slider-updatemode',
marks={i: {'label': '{}'.format(10 ** i)} for i in range(4)},
min=0,
max=3,
value=2,
step=0.01,
updatemode='drag'
),
html.Div(id='updatemode-output-container', style={'margin-top': 20})
])
@app.callback(Output('updatemode-output-container', 'children'),
Input('slider-updatemode', 'value'))
def display_value(value):
return 'Linear Value: {} | \
Log Value: {:0.2f}'.format(value, transform_value(value))
if __name__ == '__main__':
app.run_server(debug=True)
As you can see in the code, to archive an evenly distributed spacing between the marks, my values are the numbers from 1 to 6. But I need the numbers 0.001 to 0.5 like the marks as input values in callbacks.
Hi @cody
If you look at the example, the log value is calculated in the callback:
# Use the following function when accessing the value of 'my-slider'
# in callbacks to transform the output value to logarithmic
def transform_value(value):
return 10 ** value
In your case, to get the range you are looking for, you can adjust the min and max values of the slider. For example, to get a scale from 0.001 to 1, you could use a min=-3 and max=0
Hi @AnnMarieW
I understand. But what do I do when I want to have exactly these values only: 0.001, 0.005, 0.01, 0.05, 0.1 and 0.5? Nothing in between?
Am I even supposed to use a slider for that? What do you think are better selection options for such a case? Those numbers are parameters for a function. Each of those parameters will have a different affect on a graph shown as an output.
If you really want a slider, you can set the steps so you only get the numbers you want, but for this use-case, a Dropdown or even RadioItems might work better for you.
So, I found a solution to my problem. Huge thanks to @AnnMarieW for her input. She suggested to use a function to transform the values. I wrote a function that uses a dictionary to map the slider input value to whatever value I need, but still maintaining an even spacing between the marks on the slider. Keep in mind, when the values of the slider (marks) are not linear scale (e.g. 1,3,5,7,9,β¦), but rather log scale or non-linear scale (e.g. 1,2,6,14,30), the slider will have the marks sitting on each other. That is because the steps are not going up by a constant factor like step=1. This problem (see OP) renders the slider pretty much useless.
dcc.Slider(
id='non_linear_scale_slider',
min=1,
max=6,
step=None,
marks={
1: '0.001',
2: '0.005',
3: '0.01',
4: '0.05',
5: '0.1',
6: '0.5'
},
value=4
)
# Use in a callback to transform input value of slider to arbitrary value
def transform_value(slider_value):
int_to_scale = dict([
(1, 0.001),
(2, 0.005),
(3, 0.01),
(4, 0.05),
(5, 0.1),
(6, 0.5)
])
return int_to_scale[slider_value]