Dash dcc.Slider mouseup and drag event - python

I have a dcc.Slider object which I would like to have an #app.callback for a drag event(update the state of the slider in a ) and also an #app.callback for an mouseup event, which will update a graph that I have. My question, is this doable with dash? The documentation for mouseup in updatemode mentions drag_value, but i cannot see how to use it in #app.callback.
Here is my plot:
app.title = "Plot Log"
app.layout = html.Div(
[
dcc.Graph(id="graph"),
dcc.Slider(0, slider_length, 1,
id='slider-updatemode',
value=2,
updatemode='mouseup'
),
html.Div(id='updatemode-output-container', style={'margin-top': 20})
],
style={"width": "500"},
)
Reading documentation, using drag_value

Yes, one can have a callback for handling the drag event and another one for the mouseup event. Quoting the part of the doc you are referring to for clarity :
If you want different actions during and after drag, leave updatemode
as mouseup and use drag_value for the continuously updating value.
Here an example that displays the drag value as it changes, and updates the graph on mouseup :
app.layout = html.Div([
dcc.Graph(id="graph"),
dcc.Slider(min=-5, max=5, step=0.01, value=1,
marks={i: str(i) for i in range(-5, 6)},
id='slider-updatemode',
updatemode='mouseup',
),
html.Div(id='updatemode-output-container', style={'margin-top': 20})
])
#app.callback(Output('updatemode-output-container', 'children'),
Input('slider-updatemode', 'drag_value'))
def display_value(drag_value):
return f'Slider Value: {drag_value}'
#app.callback(Output('graph', 'figure'),
Input('slider-updatemode', 'value'))
def update_graph(value):
x = np.linspace(0.1, 10, 1000)
y = [x**value for x in x]
return go.Figure(data=[go.Scatter(x=x, y=y)])

Related

hide some marks of a slider and display the others

If it possible to keep the marks for 0, 5,20 and hide the marks 10 and 15 in this code :
from dash import dcc, html, Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Slider(0, 20, 5,
value=10,
id='my-slider'
),
html.Div(id='slider-output-container')
])
#app.callback(
Output('slider-output-container', 'children'),
Input('my-slider', 'drag_value'))
def update_output(value):
return 'You have selected "{}"'.format(value)
if __name__ == '__main__':
I would like be able to slag on the value 10 or 15 without viewing the labels.
You can add custom marks:
app.layout = html.Div([
dcc.Slider(0, 20,
step=None,
marks={0:"0", 5:"5", 20:"20"},
value=10,
id='my-slider'
),
html.Div(id='slider-output-container')
])

Add vrect with text to plotly express with button

I have the following code for a vertical rectangle in plotly express:
fig.add_vrect(
x0 = '2020-04',
x1 = '2020-09',
fillcolor="red",
opacity=0.25
)
I would like to make a button where the user can toggle with rectangle on and off, and when it's on there's some text in the middle. I would like them to be off by default.
You can use dictionaries to create your rectangle shape and rectangle annotation and then use these as arguments for a button. A few details: we use the "relayout" method for buttons because toggling a shape and text annotation means we are only changing the layout, and args and args2 tells the button how to behave when toggled on/off.
Edit: in order to keep another shape (like a vline) on the figure, you can add the vline to both args and args2 of your button so the vline remains when the button is toggled
import plotly.express as px
fig = px.scatter(
x=['2020-01-30', '2020-04-01', '2020-04-01','2020-09-01'],
y=[3,2,3,2]
)
fig.add_vline(
x='2020-02',
line_dash='dash'
)
vline_shape = [dict(
type='line',
x0='2020-02',
x1='2020-02',
xref='x',
y0=0,
y1=1,
yref='y domain',
line= {'dash': 'dash'}
)]
rectangle_shape = [dict(
type='rect',
x0='2020-04',
x1='2020-09',
xref='x',
y0=0,
y1=1,
yref='y domain',
fillcolor='red',
opacity=0.25
)]
rectangle_annotation = [dict(
showarrow=False,
x='2020-06-15',
y=2.5,
text="Selected Time Period"
)]
fig.update_layout(
updatemenus=[
dict(
type="buttons",
buttons=[
dict(label="Toggle Rectangle",
method="relayout",
args=[{
"shapes": rectangle_shape + vline_shape,
"annotations": rectangle_annotation}],
args2=[{
"shapes": vline_shape,
"annotations": []}]),
# dict(label="Untoggle Rectangle",
# method="relayout",
# args=["shapes", []]),
],
)
]
)
fig.show()

Graph dimension decreases if CheckList is used to update y axis

I'm working on a Dash App that represents graphs about data in a database. One column of the database is a list of journals and I represented this column in a pie and in a bar chart with the respective frequency of each journal. I decided to put also a CheckList, because the database can change and if there are too many journals, the graphs are no more readable. So at the beginning only the first 15 items of the list are shown in the graphs, like the image below.
The problem is that, if I change the selected journals in the Checklist, the graphs update correctly but the width of the bar chart decreases and I don't understand why. In the image below it is possible to see that, changing the selection, the graph dimension is reduced and re-checking the two items, the graph does not return with the initial dimension anymore. Why?
(The graphs are created in a callback after the selection of the database in a dropdown)
#app.callback(
Output('first_graph', 'children'),
Input('database', 'value')
)
def create_graph(value):
if value is not None: #if i select the database from a dropdown, the graphs appear
df = pd.read_csv(value)
#Count unique values: index takes the values, the other takes the counts
journals = df['Journal'].value_counts().index.tolist() # --> x
journals_frequency = df['Journal'].value_counts().tolist() # --> y
trace1 = go.Bar(y=journals, x=journals_frequency,orientation='h', name='Number of journals',
marker=dict(color=color_charts_journals)) #'h' stays for horizontal
layout1 = go.Layout(autosize=False,
width=450,
height=350,
xaxis=dict(tickformat=',d', showgrid=False),
yaxis=dict(type='category', tickmode='linear', showticklabels=False, showgrid=False),
margin=dict(t=25,b=25,l=5,r=5),
bargap=0,
)
fig1=go.Figure(data=[trace1],layout=layout1)
pie_journals = go.Pie(labels=journals, values=journals_frequency, hole=0.5, showlegend=False,textposition='inside',
name='Frequency of Journals',marker=dict(colors=color_charts_journals))
fig_pie_journals = go.Figure(data=[pie_journals])
fig_pie_journals.update_layout(title={
'text': "Frequency of journals",
'y':1,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
autosize=False,
width=450,
height=350,
margin=dict(t=20, b=15, l=5, r=5),)
return html.B('List of journals', style={'textAlign': 'center','width': '50%'}),
html.Div([
dcc.Checklist(
id="all-or-none",
options=[{"label": "Select All", "value": "All"}],
value=[],
)]),
html.Div([
dcc.Checklist(
id='checklist_journals',
options=[
{'label': x, 'value': x, 'disabled': False}
for x in sorted(journals) #set in alphabetical order
],
value=sorted(journals)[0:15],
labelStyle={'display': 'block','margin-left':'40px','margin-top':'10px'}
)],style={'width': '33%', 'display': 'inline-block',"overflow-y":"scroll","height": "350px"}), #'backgroundColor':'blue'
html.Div([dcc.Graph(id='journals_pie',figure=fig_pie_journals)],style={'width': '33%', 'display': 'inline-block'}),
html.Div([dcc.Graph(id='journals_graph', figure=fig1)],style={'width': '33%', 'display': 'inline-block'}),
#callback for select all values of the checklist
#app.callback(
Output("checklist_journals", "value"),
[Input("all-or-none", "value")],
[State("checklist_journals", "options"),State("checklist_journals", "value")],
)
def select_all_none(all_selected, options, values_checklist):
if all_selected: #se clicco seleziona tutto
all_or_none = []
all_or_none = [option["value"] for option in options if all_selected]
return all_or_none
else:
return values_checklist[0:15] #se non clicco seleziona i primi 15 altrimenti si tolgono tutti
#callback to choose values in pie journals and bar journals
#app.callback(
[Output(component_id='journals_pie', component_property='figure'),Output('journals_graph','figure')],
[Input('database', 'value'),Input(component_id='checklist_journals', component_property='value')]
)
def update_graph(value,options_chosen):
if value is not None:
df = pd.read_csv(value)
dff = df[df['Journal'].isin(options_chosen)] #dataframe with only selected journals
journals = dff['Journal'].value_counts().index.tolist() # --> x
journals_frequency = dff['Journal'].value_counts().tolist() # --> y
pie_journals = go.Pie(labels=journals, values=journals_frequency, showlegend=False, hole=0.5,textposition='inside',
name='Frequency of Journals',marker=dict(colors=color_charts_journals))
fig_pie_journals = go.Figure(data=[pie_journals])
fig_pie_journals.update_layout(title={
'text': "Frequency of journals",
'y':1,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
autosize=False,
width=450,
height=350,
margin=dict(t=20, b=15, l=5, r=5),)
#paper_bgcolor="LightSteelBlue") #per settare le dimensioni della torta
trace1 = go.Bar(y=journals, x=journals_frequency, orientation='h', name='Number of journals',
marker=dict(color=color_charts_journals)) # 'h' stays for horizontal
layout1 = go.Layout(autosize=False,
width=450,
height=350,
xaxis=dict(tickformat=',d', showgrid=False),
yaxis=dict(type='category', tickmode='linear', showticklabels=False, showgrid=False),
margin=dict(t=25,b=25,l=5,r=5),
bargap=0,
#paper_bgcolor="LightSteelBlue",
#per avere massimo 20 valori
#yaxis=dict(type='category', tickmode='auto', showgrid=False,
# automargin=False, nticks=20, tickwidth=10),
)
fig1 = go.Figure(data=[trace1], layout=layout1)#to set bar width
return fig_pie_journals,fig1
else:
return dash.no_update,dash.no_update

How to fix plotly graph size in dash web application

I am trying to fix a graph size in a dash application, so that it is the desired size and that it doesn't change when resizing the browser page.
The code for my graph and dash application is as such:
distplot = ff.create_distplot(hist_data, group_labels, bin_size=50000, show_hist=False)
distplot = distplot.update_layout(
title_text='Kernel Density Plot of House Price Data',
title_x=0.5,
xaxis_showgrid=False,
yaxis_showgrid=False,
hoverlabel=dict(font_size=10, bgcolor='rgb(69, 95, 154)'),
legend=dict(title='Year of data',
x=1,
y=1,
traceorder='normal',
xanchor = 'auto')
)
#Dash application
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
##Creating Dash server ##
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.config.suppress_callback_exceptions=True
url_bar_and_content_div = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content', style={'font': 'Georgia, sans-serif'})
]
)
layout_index = html.Div([
html.H1('Webpage Information', style={'textAlign': 'center'}),
html.H2('Distplot', style={'font-size': '40px'}),
html.Br(),
dcc.Graph(id='distplot', figure=distplot),
],
style={'margin-top': '20px', 'margin-bottom': '20px',
'margin-right': '80px', 'margin-left': '80px'}
)
## Creating HTML style ##
# index layout
app.layout = url_bar_and_content_div
# "complete" layout
app.validation_layout = html.Div([
url_bar_and_content_div,
layout_index
])
# Index callbacks
#app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
return layout_index
## Run ##
if __name__ == '__main__':
app.run_server(debug=True)
I have tried several methods to achieve this, firstly putting the graph in it's own html.Div() and using style{'height' : '700', 'width' : '700' } but it hasn't worked. I have tried using style directly to the dcc.Graph object but this has also not worked.
Does anyone know how I would go about this? Thanks
EDIT
I can now properly set the size of the graph height using height=700 in the .update_layout() method. However when resizing my browsing window, the graph rescales and changes size incorrecty to browser window size.
If anyone knows how to do this, it would be appreciated.
try including the width and height arguments inside the graph create method.
distplot = ff.create_distplot(hist_data, group_labels, bin_size=50000,
show_hist=False, width=700, height=700)

Plotting 3D Chart in Dash Plotly

I have some difficulties to create a 3D chart for my Dash App. The code does not throw any error. It returns an empty 2D chart (not even a 3D chart).
I checked the variables z, x, y - they contain the correct values + shape. Code snippet is from Plotly, Chart Example "Passing x and y data to 3D Surface Plot". Any idea what I am missing?
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output
import plotly.graph_objects as go
app = dash.Dash()
app.layout = html.Div(children=[
html.H1(children="My 3D Chart!"),
dcc.Graph(
id='my-graph'
),
])
#app.callback(Output('my-graph', 'figure'))
def create_chart():
z = df_size_rolled.values
sh_0, sh_1 = z.shape
x, y = np.linspace(0, 1, sh_0), np.linspace(0, 1, sh_1)
fig = go.Figure(data=[go.Surface(z=z, x=x, y=y)])
return fig
if __name__ == '__main__':
app.run_server(debug=True)
I also tried, but didn't work:
data=[go.Surface(z=z, x=x, y=y)]
return {'data': [data]}
Any help much appreciated.
Seems like the ´data´- property is not needed in Dash.
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("3D Charts", style={"textAlign": "center"}),
html.Div([html.Div([html.Span("Type Of Chart : ")], className="six columns",
style={"textAlign": "right", "padding-right": 30, "padding-top": 7}),
html.Div([dcc.Dropdown(id='select-date', options=[{'label': i, 'value': i} for i in my_dates],
value="2018-02-06")], className="six columns",
style={"width": "40%", "margin-left": "auto", "margin-right": "auto", "display": "block"}),
], className="row", style={"width": "80%"}),
html.Div([dcc.Graph(id='my-graph')], className="row")
], className="container")
#app.callback(
dash.dependencies.Output('my-graph', 'figure'),
[dash.dependencies.Input('select-date', 'value')])
def update_graph(selected):
global df_sliced
df_sliced = df_size.loc[selected:selected]
df_sliced = df_sliced.rolling(6).mean()
df_sliced = df_sliced.dropna()
trace2 = [go.Surface(
z = df_sliced.values,
colorscale='Rainbow', colorbar={"thickness": 10, "len": 0.5, "title": {"text": "Volume"}})]
layout2 = go.Layout(
title="Orderbook Structure " + str(selected), height=1000, width=1000, scene = dict(
xaxis_title='Order Level - Bid Side[0-9], Ask Side[10-19]',
yaxis_title='Time 08.00 until 22.00 (5Min Intervals)',
zaxis_title='Volume (Trailing Mean - 30Min)',
aspectmode='cube'),
scene_camera_eye=dict(x=2, y=-1.5, z=1.25),
)
return {"data": trace2, "layout": layout2}
if __name__ == '__main__':
app.run_server(debug=True)

Categories