Hello I am very new to dash and I am trying to render a graph whose outpuut would depend on the two drop down selection on the layput
I have written the below graph_update logic, however somehow it is not workig.
app.layout = html.Div([
html.Div([
html.H1('Stock Tickers'),
dcc.Dropdown(
id='my-dropdown',
options=[
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'},
{'label': 'C', 'value': 'C'}
],
value='A'
)
],
style={'width': '20%', 'display': 'inline-block'}
),
dcc.Dropdown(
id='my-dropdown1',
options=[
{'label': '250,000', 'value': '250000'},
{'label': '500,000', 'value': '500000'},
{'label': '750,000', 'value': '750000'},
{'label': '1,000,000', 'value': '1000000'}
],
value='250000'
),
dcc.Graph(id='my-graph')
], className="container")
#app.callback(Output('my-graph', 'figure'),
[Input('my-dropdown', 'value'), Input('my-dropdown1', 'value')])
def update_graph(selected_dropdown_value, selected_imp_value):
dff = df[(df['Demo'] == selected_dropdown_value) & (df['Imp_cap'] == selected_impresession_value)]
return {
'data': [{
'x': dff.Imp
'y': dff.user,
'line': {
'width': 3,
'shape': 'spline'
}
}],
'layout': {
'margin': {
'l': 30,
'r': 20,
'b': 30,
't': 20
}
}
}
I was hoping if someone can please help me to resolve the issue
Thanks a lot in advance !!
This is how we managed to do it. It was not something exceptionally genius, just the way of writing it.
def update_graph(n_clicks, input1, input2, input3, input4):
dff = df[df['Demo'] == input1]
df1 = dff[dff['Month'] == input2]
df2 = df1[df1['Imp'] == input3]
df3 = df2[df2['imp_cap'] == input4]
if n_clicks < 1:
return []
else:
return {
'data': [{
'x': df3.Variable2,
'y': df3.Variable1,
'line': {
'width': 3,
'shape': 'spline'
}
}],
'layout': dict(
# 'margin': {
# 'l': 30,
# 'r': 20,
# 'b': 30,
# 't': 50
# },
title='title',
xaxis=dict(title='x-title'),
yaxis=dict(title='y-title'),
annotations=[make_annotation_item(x=df3['Variable1'].iloc[-1], y=df3['Variable2'].iloc[-1])]
)
}
Related
I have a plotly dashboard built with dash. Some of the chart elements are set to refresh every couple of seconds. Instead of just refreshing that individual dashboard, the entire webpage refreshes and it rebuilds every element.
This is an example of how the code is written that updates the charts-
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
html.Div([
dcc.Graph(id='live-update-graph'),
dcc.Interval(
id='interval-component',
interval=1*1000, # in milliseconds
n_intervals=0
)
])
)
#app.callback(Output('live-update-graph', 'figure'),
Input('interval-component', 'n_intervals'))
def update_graph_live(n):
satellite = Orbital('TERRA')
data = {
'time': [],
'Latitude': [],
'Longitude': [],
'Altitude': []
}
# Collect some data
for i in range(180):
time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
lon, lat, alt = satellite.get_lonlatalt(
time
)
data['Longitude'].append(lon)
data['Latitude'].append(lat)
data['Altitude'].append(alt)
data['time'].append(time)
# Create the graph with subplots
fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
fig['layout']['margin'] = {
'l': 30, 'r': 10, 'b': 30, 't': 10
}
fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
fig.append_trace({
'x': data['time'],
'y': data['Altitude'],
'name': 'Altitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 1, 1)
return fig
My desired outcome is that just the plot element refreshes but not the entire webpage.
I am attempting to create gradients within the edges of a graph in dash_cytoscape using line-gradient-stop-colors (from the js.cytoscape documentation). I am doing this with a stylesheet that describes a gradient layout for all of the edges in my graph. Example code is below, however it creates a graph with just grey edges.
import dash
import dash_cytoscape as cyto
from dash import html
app = dash.Dash(__name__)
style_1 = [
{
'selector': 'node',
'style': {
'label': 'data(id)',
'background-color': 'blue',
}
},
{
'selector': 'edge',
'style': {
'line-gradient-stop-colors': 'cyan magenta yellow', # these are the lines that I have issue with
'line-gradient-stop-positions': '25 50 75',
}
}
]
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape-elements-boolean',
layout={'name': 'preset'},
style={'width': '100%', 'height': '800px'},
stylesheet=style_1,
elements=[
{
'data': {'id': 'one'},
'position': {'x': 75, 'y': 75},
},
{
'data': {'id': 'two'},
'position': {'x': 75, 'y': 200},
},
{
'data': {'id': 'three'},
'position': {'x': 200, 'y': 75},
},
{
'data': {'id': 'four'},
'position': {'x': 200, 'y': 200}
},
{'data': {'source': 'one', 'target': 'two'}},
{'data': {'source': 'two', 'target': 'three'}},
{'data': {'source': 'three', 'target': 'four'}},
{'data': {'source': 'two', 'target': 'four'}},
]
)
])
if __name__ == '__main__':
app.run_server(debug=True)
I believe the issue is how I have the line-gradient-stop-colors string set up but I've tried multiple options and none of them have worked. Any help would be greatly appreciated!
I have a dash script which has the users filling in inputs and dropdowns; first with inputs then filling in a dropdown datatable. I need to take these inputs and datatable once they are filled in, and after clicking the ‘Submit’ button, will be stored as a pandas dataframe or dictionary or stored in the database (whichever is easiest, to be frank).
I feel like I may need to use dcc.Store and callbacks of course, but I’m uncertain on how to proceed.
Any help appreciated, thank you!
app = dash.Dash(__name__)
app.config['suppress_callback_exceptions'] = True
df = pd.DataFrame(OrderedDict([
('Product', ['Benzene', 'HDPE', 'Propylene', 'Benzene']),
('Function', ['Input1', 'Input2', 'Input3', 'Input2']),
('Conversion Factor', [1, 2, 1, 3]),
('Measure Unit', ['Tonne', 'Kilo', 'Tonne', 'Gram']),
]))
app.layout = html.Div(
children=[
html.H1(children='Technology Information',
style={'font-family': 'calibri'}),
dcc.Store(id='memory'),
dbc.FormGroup([
dbc.Label('Technology Name:',
html_for='tech-name-row',
style={'font-family': 'calibri',
'margin-right': '4em'}),
dbc.Col(dbc.Input(type='technology',
id='tech-name-row',
placeholder='Enter Technology Name',
style={'display': 'inline-flex',
'verticalAlign': 'middle',
'height': '25px'}),
style={'display': 'inline-flex',
'verticalAlign': 'middle'}),
], row=True, style={'margin-bottom': '1em'}),
html.Label(["Technology Type:", dcc.Dropdown(id="tech-type-drop",
style={'display': 'inline-block',
'width': '175px',
'height': '28px',
'margin-left': '2.3em',
'verticalAlign': 'middle',
'font-size': '15px'},
placeholder='Select Type',
options=[
{"label": "Type 1", "value": "1"},
{"label": "Type 2", "value": "2"},
{"label": "Type 3", "value": "3"}])],
style={'font-family': 'calibri',
'margin-right': '4em',
'display': 'flex'}),
html.H1(' '),
html.H1(' '),
html.H2('Process Information',
style={'font-family': 'calibri',
'margin-right': '0.5em',
'margin-top': '3em',
'display': 'inline'}),
html.Button(children='+',
id='add_process_button',
style={'background-color': '#38BC23',
'display': 'inline'}),
html.Div(id='process_list', children=[]),
html.Div(id='process_output', children='No output'),
html.Button(children='Submit',
id='submit-form',
type='submit',
style={'background-color': '#0099ff',
'margin': '1em'}),
]
)
#app.callback(
Output('process_list', 'children'),
[Input('add_process_button', 'n_clicks'),
Input({'type': 'remove_process_button', 'index': ALL}, 'n_clicks')
],
[State('process_list', 'children')])
def add_step(n_clicks, _, div_list):
input_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
if "index" in input_id and n_clicks is not None:
delete_form = json.loads(input_id)["index"]
div_list = [form for form in div_list if "'index': " + str(delete_form) not in str(form)]
else:
div_list += [html.Div(children=[
dcc.Store(id='memory'),
html.Button(children='-',
id={'type': 'remove_process_button', 'index': n_clicks},
style={'background-color': 'red',
'display': 'inline',
'float': 'right',
'margin': '1em'}),
dbc.Col(
dbc.FormGroup(
[dbc.Label("Process Name",
html_for="process-name",
style={'font-family': 'calibri',
'margin-right': '2em'}),
dbc.Input(id="process-name",
placeholder="Enter Process Name")],
style={'margin': '1em'})),
html.Div(children=[
dash_table.DataTable(id='process-table',
data=[{}],
style_table={'margin': '2em', 'width': '90%', 'display': 'inline-block'},
style_cell={'font-family': 'calibri', 'textAlign': 'left'},
columns=[{'id': 'Product', 'name': 'Product', 'presentation': 'dropdown'},
{'id': 'Function', 'name': 'Function', 'presentation': 'dropdown'},
{'id': 'Conversion Factor', 'name': 'Conversion Factor',
'presentation': 'dropdown'},
{'id': 'Measure Unit', 'name': 'Measure Unit',
'presentation': 'dropdown'}],
row_deletable=True,
editable=True,
dropdown={'Product': {'options': [{'label': i, 'value': i} for i in
['Benzene', 'HDPE', 'Propylene']]},
'Function': {'options': [{'label': i, 'value': i} for i in
['Input1', 'Input2', 'Input3']]},
'Conversion Factor': {'options': [{'label': i, 'value': i} for i in
['1', '2', '3']]},
'Measure Unit': {'options': [{'label': i, 'value': i} for i in
['Tonne', 'Kilo', 'Gram']]},
}),
html.Button('Add Row',
style={'background-color': '#38BC23', 'display': 'inline', 'margin': '1em'},
id='editing-rows-button',
n_clicks=0),
html.Div(id='process-table-container')
])
], style={'border': '2px black solid',
'margin': '1em'}
)]
return div_list
#app.callback(
Output('process-table', 'data'),
[Input('editing-rows-button', 'n_clicks')],
[State('process-table', 'data'),
State('process-table', 'columns')])
def add_row(n_clicks, rows, columns):
if n_clicks > 0:
rows.append({c['id']: '' for c in columns})
return rows
If everything will be triggered by the submit button, then you can set up a callback to use the submit button as Input, and everything else as State to the function. Then that function can package the data however you need and send it off to your database, file system, or whatever.
I want to use Python plotly to mark a vertical line that can be dragged around on a time series data graph.
Share my image below.
I remember browsing the plotly or dash web pages that previously described the features of this image, but I couldn't find it when I searched again.
If my mistake is, please let me know how to realize this function.
One approach is to use a shapes object in a dcc.Graph. You have to configure the graph to editable to be able to move the shape. You can then use the relayoutData property of the dcc.Graph as input in the callback function in order to get the position of the shape on the graph. This is explained in the link below. I don't think there is a way to restrict the movement of the shape, unfortunately. So in your case, there is no way to restrict the vertical line to stay vertical. A user would be able to alter it's angle, for example.
https://community.plotly.com/t/moving-the-location-of-a-graph-point-interactively/7161/2
I've also included some starter code as an example of a movable vertical line on a dash plot.
import json
from textwrap import dedent as d
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/dZVMbK.css'})
styles = {'pre': {'border': 'thin lightgrey solid', 'overflowX': 'scroll'}}
app.layout = html.Div(className='row', children=[
dcc.Graph(
id='basic-interactions',
className='six columns',
figure={
'data': [{
'x': [1, 2, 3, 4],
'y': [4, 1, 3, 5],
'text': ['a', 'b', 'c', 'd'],
'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers',
'marker': {
'size': 12
}
}, {
'x': [1, 2, 3, 4],
'y': [9, 4, 1, 4],
'text': ['w', 'x', 'y', 'z'],
'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
'name': 'Trace 2',
'mode': 'markers',
'marker': {
'size': 12
}
}],
'layout': {
'shapes': [{
'type': 'line',
'x0': 0.5,
'x1': 0.5,
'xref': 'paper',
'y0': 0,
'y1': 9,
'yref': 'y',
'line': {
'width': 4,
'color': 'rgb(30, 30, 30)',
'dash': 'dashdot'
}
}]
}
},
config={
'editable': True,
'edits': {
'shapePosition': True
}
}
),
html.Div(
className='six columns',
children=[
html.Div(
[
dcc.Markdown(
d("""
**Zoom and Relayout Data**
""")),
html.Pre(id='relayout-data', style=styles['pre']),
]
)
]
)
])
#app.callback(
Output('relayout-data', 'children'),
[Input('basic-interactions', 'relayoutData')])
def display_selected_data(relayoutData):
print("relayoutData:" + str(relayoutData))
return json.dumps(relayoutData, indent=2)
if __name__ == '__main__':
app.run_server(debug=True)
I am trying to create a scatter plot between two metrics after asking for the dimension level drill down. However, I am getting the the error: KeyError: u’brand’(one of the column names). I am new do Dash and cannot debug the error because there is nothing wrong with the column name. Following is the code:
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
import sqlalchemy as sq
import numpy as np
from datetime import datetime
engine_prd = sq.create_engine(“connection url”)
df=pd.read_sql(“SELECT t1.date,
t1.article_type as article_type,
t1.product_gender as product_gender,
t1.brand as brand,
t1.master_category as master_category,
t1.business_unit as business_unit,
SUM(t1.revenue) as revenue,
SUM(t1.sold_quantity) as units_sold,
SUM(t1.total_discount) / NULLIF( SUM(t1.total_mrp),0) AS discount_perc,
SUM(t1.approved_po_quantity) - SUM(t1.po_inwarded_quantity) AS pending_invard_quantity,
SUM(t1.revenue) / NULLIF(SUM(t1.list_count), 0) AS rpi,
SUM(t1.list_count),
100 *ratio_to_report(SUM(t1.list_count)) OVER (PARTITION BY t1.DATE) AS lc_share
FROM fact_category_over_view_metrics t1
WHERE t1.DATE> 20180101 and is_live_style=1
GROUP BY
t1.DATE,t1.article_type,t1.product_gender,t1.brand,t1.master_category,
t1.business_unit;”,engine_prd)
df[[‘date_format’]] = df[[‘date’]].applymap(str).applymap(lambda s: “{}/{}/{}”.format(s[4:6],s[6:], s[0:4]))
df[[‘year_month’]]=df[[‘date’]].applymap(str).applymap(lambda s: “{}-{}”.format(s[0:4],s[4:6]))
df[‘year_month’]=df[‘year_month’].astype(str)
year_month=df[‘year_month’].unique()
available_indicators = np.array([‘revenue’,‘units_sold’,‘discount_perc’,‘pending_invard_quantity’,‘rpi’,‘lc_share’])
dimension_level=np.array([‘brand’,‘product_gender’,‘article_type’,‘master_category’,‘business_unit’])
#available_indicators=list(df)
app=dash.Dash()
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(
id='dimension-level',
options=[{'label': i, 'value': i} for i in dimension_level],
value='brand'
)]),
html.Div([
dcc.Dropdown(
id='crossfilter-xaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='revenue'
),
dcc.RadioItems(
id='crossfilter-xaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
],
style={'width': '48%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
id='crossfilter-yaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='units_sold'
),
dcc.RadioItems(
id='crossfilter-yaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
], style={'width': '48%', 'float': 'right', 'display': 'inline-block'})
]),
dcc.Graph(
id='crossfilter-indicator-scatter'),
dcc.Slider(
id='crossfilter-year-month--slider',
min=0,
max=len(df['year_month'].unique()),
value=0,
step=None,
marks={i : str(yearm) for i, yearm in enumerate(df['year_month'].unique())} # enumerate the dates
)
])
#app.callback(
dash.dependencies.Output(‘crossfilter-indicator-scatter’, ‘figure’),
[dash.dependencies.Input(‘dimension-level’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-year-month–slider’, ‘value’)],
[dash.dependencies.State(‘crossfilter-year-month–slider’, ‘marks’)])
def update_graph(dimension_level_name,xaxis_column_name, yaxis_column_name,xaxis_type, yaxis_type, selected_year_month_key,marks):
selected_year_month=marks[str(selected_year_month_key)]
df_filtered = df[df['year_month'] == selected_year_month]
dff=df_filtered.groupby([dimension_level_name]).sum()
return {
'data': [go.Scatter(
x=dff[xaxis_column_name],
y=dff[yaxis_column_name],
text=dff[dimension_level_name],
#customdata=dff['article_type'],
mode='markers',
marker={
'size': 15,
'opacity': 0.5,
'line': {'width': 0.5, 'color': 'white'}
}
)],
'layout': go.Layout(
xaxis={
'title': xaxis_column_name,
'type': 'linear' if xaxis_type == 'Linear' else 'log'
},
yaxis={
'title': yaxis_column_name,
'type': 'linear' if yaxis_type == 'Linear' else 'log'
},
margin={'l': 40, 'b': 30, 't': 10, 'r': 0},
height=450,
hovermode='closest'
)
}
if name == ‘main’:
app.run_server()
The errors occurs while grouping by the df using the input value from dropdown. The data frame’s head looks has been linked to The sample data:
The key error occurs in "text=dff[dimension_level_name]". It is because while grouping by the dataframe , as_index is not set to False. This will throw a key error. The problem was solved by replacing dff=df_filtered.groupby([dimension_level_name]).sum() with:
dff=df_filtered.groupby([dimension_level_name].as_index=False).sum()