Related
I am new to plotly dash. I am trying to create an interactive dashboard where I can filter the colorbar to see the upper values for example if the value is 3000 it was red, so if I type 3000 as input, it is still red but the graph will not show values less than 3000. I am able to add the filtering option but when I filter(I used zmin in go heatmap) the colorscale also changes. Can I keep the previous colorscale so that if I choose zmin, it refreshes the graph with the original colorscale but filters values greater than zmin? Here is the code I have written so far -
app.layout = html.Div(children=[
html.H1(children='Title'),
dcc.Graph(
id='graph',
figure=fig
),
dcc.Input(
id="input", type="number", value=0
)
])
#app.callback(
Output('graph', 'figure'),
Input('input', 'value')
)
def update_figure(input):
frames = []
for d, i in enumerate(sorted(timestamp_list)):
frames.append(
go.Frame(
name=time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(int(i) / 1000)),
data=[
go.Heatmap(z=df_dict[i],
x=df_dict[i].columns,
y=df_dict[i].index,
zmin=input,
zmax=max(value_list))
]
)
)
yaxis_name = kind.split("_")[0]
xaxis_name = kind.split("_")[1]
fig = go.Figure(
data=frames[0].data,
frames=frames,
layout=go.Layout(
autosize=True,
height=800,
yaxis={"title": yaxis_name, "dtick": 1},
xaxis={"title": xaxis_name, "tickangle": 45, "side": 'top'},
),
)
# finally, create the slider
fig.update_layout(
updatemenus=[{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': True},
'transition': {'duration': 500, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 100},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}],
sliders=[{"steps": [{"args": [[f.name], {"frame": {"duration": 0, "redraw": True},
"mode": "immediate", }, ],
"label": f.name, "method": "animate", }
for f in frames],
}]
)
return fig
Here is the sample output I get-[![enter image description here][1]][1]
After filtering- [![enter image description here][2]][2]
I am not completely sure I understood what you mean, but isn't it enough to just filter your data? I also don't have an example of how you data look like, but why don't you try filtering your data frame before you plot?
data_to_plot = frames[frames['your_column'] > zmin]
I'm trying to build a Dashboard using Plotly in Python. I've initialized a dashboard, and divided it into portions/containers using 'dash_html_components.Div()'. Later, I've used 'dash_core_components.Graph()' to plot graph inside a div. The problem arises when I try to plot a graph inside a div, the plot actually goes outside the div size/container. Though the graph maintains width, but not the height. I have added comments, where is necessary.
This is the image of my dashboard, and the portion that is ticked, there I want to place a graph.
Dashboard without graph:
Dashboard with graph:
Code:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
# import pandas_datareader.data as web # requires v0.6.0 or later
from datetime import datetime
import pandas as pd
from datetime import datetime
#building Dashboard
app = dash.Dash()
app.layout = html.Div([ #(row=main, col=main) block
html.Div([ ##(row=1, col=1) block
], style = { ##(row=1, col=1) block style
'display': 'block',
'float': 'left',
# 'margin': 'auto',
'width': '25%',
'height': '50%',
# 'border': '1px solid #006600',
'background-color': 'cyan'
}),
html.Div([ ##(row=1, col=2) block
#graph containing div
dcc.Graph(
id = 'my_graph',
figure={
'data': [go.Scatter(
x = [0,1],
y = [0,1],
mode = 'lines'
)],
'layout': go.Layout(
title = 'graph',
autosize = True
)
}
)
], style = { ##(row=1, col=2) block style
'display': 'block',
'float': 'left',
# 'margin': 'auto',
'width': '25%',
'height': '50%',
# 'border': '1px solid #006600',
'background-color': 'DarkCyan'
}),
html.Div([ ##(row=1, col=3) block
], style = { ##(row=1, col=3) block sty;e
'display': 'block',
'float': 'left',
# 'margin': 'auto',
'width': '50%',
'height': '50%',
# 'border': '1px solid #006600',
'background-color': 'MediumSeaGreen'
})
], style = { #(row=main, col=main) block style
'display': 'block',
'float': 'center',
'margin': '-1vw auto',
# 'margin': '-1vw 11vw 0 11vw',
'width': '70vw',
'height': '30vw',
# 'border': '1px solid #006600',
'background-color': 'gray',
'box-shadow': '10px 10px 5px gray'
})
if __name__ == '__main__':
app.run_server(port=1000)
You need to specify a style value for your dcc.Graph if you want it to fit according to the html layout. In this case, you can do:
dcc.Graph(
id="my_graph",
figure={
"data": [go.Scatter(x=[0, 1], y=[0, 1], mode="lines")],
"layout": go.Layout(title="graph", autosize=True),
},
style={'height': '100%'}
)
I am wondering if there is a way that you can have a dash table scroll vertically up and down automatically when the scroll bar is available.
This is a simple example (I used the same dataframe 7 times to make it long enough).
import dash
import dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')
long_data = pd.concat([df,df,df,df,df,df,df])
app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in long_data.columns],
data=long_data.to_dict('records'),
)
if __name__ == '__main__':
app.run_server(debug=False)
Is there a way to make what's on this page go vertically up and down?
I'm not sure if this is what you're looking for, but you can make the table scrollable via style_table (reference):
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in long_data.columns],
data=long_data.to_dict('records'),
style_table={
'overflowY': 'scroll'
}
)
If you're looking to have the table scroll automatically at a given speed, I doubt dash/plotly has in-built functionality to do that.
Have you attempted to use "overflow":"Scroll" or overflowY
Example:
dbc.Col(
html.Div(id='timeline-div',),
width=4,
style={'width': '100%',
'height': '750px',
'overflow': 'scroll',
'padding': '10px 10px 10px 20px'
}
),
Resource: https://community.plotly.com/t/how-to-make-a-data-table-scrollable-with-using-overflowy-but-without-the-double-scroll-bars/27920
Issue Fixed :-
style_header=
{
'fontWeight': 'bold',
'border': 'thin lightgrey solid',
'backgroundColor': 'rgb(100, 100, 100)',
'color': 'white'
},
style_cell={
'fontFamily': 'Open Sans',
'textAlign': 'left',
'width': '150px',
'minWidth': '180px',
'maxWidth': '180px',
'whiteSpace': 'no-wrap',
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'backgroundColor': 'Rgb(230,230,250)'
},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
},
{
'if': {'column_id': 'country'},
'backgroundColor': 'rgb(255, 255, 255)',
'color': 'black',
'fontWeight': 'bold',
'textAlign': 'center'
}
],
fixed_rows={'headers': True, 'data': 0}
You can accomplish this using callbacks and dcc.interval, but it is clunky!
Hello I am working on a dash app, and somehow I am not able to update graphs between different divs callback. This is how the app works:
The user gives a url input on the frontend in a textinput box and button is clicked to run analysis.
The user can select the view mode as well before running the analysis, The view mode depends on the dropdown selector
The url is used to display a video frame and run a python function.
The processed results should be stored in the dcc.store component.
The stored data is then called in to update the graphs.
Below is the callback codes:
#Video Selection
#app.callback(Output("video-display", "url"),
[Input("submit_button", "n_clicks")],
[State('video_url', 'value')])
def select_footage(n_clicks, video_url):
if n_clicks is not None and n_clicks > 0:
url = video_url
return url
# Processing and Storing the results in dcc.store
#app.callback(Output("intermediate-value", "data"),
[Input("submit_button", "n_clicks")],
[State('video_url', 'value')])
def video_processing(n_clicks, value ):
global frame
if n_clicks is not None and n_clicks > 0:
frame = python_func(url)
return frame.to_json(orient='split')
# Callback to change the graph view mode div
#app.callback(Output("div-graph-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_graph_mode(value):
if value == "graphical":
return [
html.Div(
children=[
html.P(children="Retention Score of Detected Labels",
className='plot-title'),
dcc.Graph(
id="bar-score-graph",
style={'height': '55vh', 'width': '100%'}
),
html.P(children="Audience Retention Behavior",
className='plot-title'),
dcc.Graph(
id="line_chart_retention",
style={'height': '45vh', 'width': '100%'}
)
]
)
]
else:
return []
#app.callback(Output("div-table-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_mode(dropdown_value):
if dropdown_value == "table":
return [
html.Div(
children=[
html.P(children="Retention By Label",
className='plot-title'),
html.Div([
table.DataTable(
id="label_retention",
)],
style={'height': '45vh'}),
html.P(children="Retention by Time Stamp",
className='plot-title'),
html.Div([
table.DataTable(
id="timestamp_retention",
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'})],
style={'height': '40vh'}
)
]
)
]
else:
return []
# Updating Graphs
#app.callback(Output("label_retention", "figure"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_bar(value):
global frame
if frame is not None:
print(frame)
print("table")
print(value)
#app.callback(Output("bar-score-graph", "figure"),
[Input("dropdown-graph-view-mode", "value")])
def update_score_bar(value):
global frame
if frame is not None:
print(frame)
print("graph")
print(value)
Now what happens is that if I try to toggle between the two graph view modes, the app does not reflect the graphs and requires to click on the button again to get the results. So, basically I believe the data does not gets lost in the dcc.store component when I toggle with the dropdowns.
How can I make the app behave in a way that my python function runs only once on the submit button, but then I am able to toggle between the view modes to see the graphs.
Thanks a lot in advance!!
P.S. This is just a snippet of codes, as the code is too long, but please let me know if you would want to see the entire code.
UPDATE: I have just realised that when I select the Graph Mode, the app prints the results for Table Mode and when I select the table model, the app prints the results for graph mode. I am not able to figure out as to why this is happening.
I was finally able to resolve my issue as below:
#app.callback(Output("div-table-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_table_mode(dropdown_value):
if dropdown_value == "tabular":
return [
html.Div(
children=[
html.P(children="Retention By Label",
className='plot-title', style={'margin': '0 0 1em 0'}),
html.Div([
table.DataTable(
id="label_retention",
columns=[{"name": i, "id": i} for i in label_retention.columns],
data=label_retention.to_dict("rows"),
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'},
style_cell_conditional=[
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['Labels']
],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
}
],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold'
}
)],
style={'height': '40vh'}),
html.P(children="Retention by Time Stamp",
className='plot-title', style={'margin': '1em 0 1em 0'}),
html.Div([
table.DataTable(
id="timestamp_retention",
columns=[{"name": i, "id": i} for i in timeline_retention.columns],
data=timeline_retention.to_dict("rows"),
style_table={'maxHeight': '40vh', 'width': '100%', 'overflowY': 'scroll'},
style_cell={'textAlign': 'left', 'minWidth': '20px', 'width': '20px', 'maxWidth': '50px',
'whiteSpace': 'normal'},
css=[{
'selector': '.dash-cell div.dash-cell-value',
'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;'
}],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
}
],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold'
}
)],
style={'height': '40vh'}
)
],
style={'backgroundColor': '#F2F2F2'}
)
]
else:
return []
#app.callback(Output("div-graph-mode", "children"),
[Input("dropdown-graph-view-mode", "value")])
def update_graph_mode(value):
if value == "graphical":
return [
html.Div(
children=[
html.P(children="Retention Score of Detected Labels",
className='plot-title', style={'margin': '0 0 1em 0', 'width': '100%'}),
dcc.Graph(
id="bar-score-graph",
figure=go.Figure({
'data': [{'hoverinfo': 'x+text',
'name': 'Detection Scores',
#'text': y_text,
'type': 'bar',
'x': label_retention["Description"],
'marker': {'color': colors},
'y': label_retention["sum"].tolist()}],
'layout': {'showlegend': False,
'autosize': False,
'paper_bgcolor': 'rgb(249,249,249)',
'plot_bgcolor': 'rgb(249,249,249)',
'xaxis': {'automargin': True, 'tickangle': -45},
'yaxis': {'automargin': True, 'range': [minval, maxval], 'title': {'text': 'Score'}}}
}
),
style={'height': '55vh', 'width': '100%'}
),
html.P(children="Audience Retention Behavior",
className='plot-title', style={'margin': '0 0 1em 0', 'width': '100%'}),
dcc.Graph(
id="line_chart_retention",
figure=go.Figure({
'data': [go.Scatter(x=label_retention['Start'], y=label_retention['sum'], mode='lines', name='Audience Retention',
line=dict(color='firebrick', width=4))],
'layout': {
'yaxis': {'title': {'text': 'Audience Retention'}, 'automargin': True},
'xaxis': {'title': {'text': 'Time Segment'}, 'automargin': True},
'paper_bgcolor': 'rgb(249,249,249)',
'plot_bgcolor': 'rgb(249,249,249)',
}
}),
style={'height': '45vh', 'width': '100%'}
)
],
style={'backgroundColor': '#F2F2F2', 'width': '100%'}
)
]
else:
return []
As part of a project, I want to visualize data, which is why I chose Dash. For example, the user should drag and drop the column Age and this will then be displayed graphically. How can I achieve this?
I would prefer to display the individual columns as buttons, which he can then 'just' pull.
With dropdown menu it had worked and by drag and drop I could also read a CSV file.I have read the database table as a data frame. Thank you in advance!
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop '
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
multiple=True
),
html.Div([
dcc.Graph(
id='Graph2'
),
], style={'display': 'inline-block', 'width': '49%'}),
])