Weird error here. A single page plotly dash shows data on my line chart but when I created a multi page dash, the line chart doesn’t show the data anymore.
just shows this.
Can’t seem to find a way to show the line chart data even though my code is the same.
index.js
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) nav_item = dbc.NavItem(dbc.NavLink("Home", href="https://www.google.com")) # make a reuseable dropdown for the different examples dropdown = dbc.DropdownMenu( children=[ dbc.DropdownMenuItem("Home", href='http://1577.6.0.1:9999/apps/main'), dbc.DropdownMenuItem(divider=True), dbc.DropdownMenuItem("Login / Sign-Up", href='http://127.0.0.1:8050/apps/test') ], nav=True, in_navbar=True, label="Important Links", ) navbar = dbc.Navbar( dbc.Container( [ html.A( # Use row and col to control vertical alignment of logo / brand dbc.Row( [ dbc.Col(dbc.NavbarBrand("something", className="ml-2",)), ], align="center", no_gutters=True, ), href="https://plot.ly", ), dbc.NavbarToggler(id="navbar-toggler2"), dbc.Collapse( dbc.Nav( [ nav_item, dropdown, ], className="ml-auto", navbar=True ), id="navbar-collapse2", navbar=True, ), ] ), color="#ED4651", dark=True, className="mb-5", ) app.layout = html.Div([ navbar, dcc.Location(id='url', refresh=False), html.H4("Some Title"), html.Div(id='page-content') ]) @app.callback(Output('page-content', 'children'), Input('url', 'pathname')) def display_page(pathname): if pathname == '/apps/login': return login.layout elif pathname == '/apps/main': return main.layout else: return '404' if __name__ == '__main__': app.run_server(debug=True)
main.py
state = pd.read_csv("/U********************.csv", index_col=None) m1 = 0 m2 = 0 m3 = 0 unique = state["Area"].unique() sq = ["< 500", "500 to 1000", "1000+", "All Sizes"] sqVal = [] external_stylesheets = ['https://codepen.io/chrisudoddyp/pen/bWLwgP.css'] app = dash.Dash(__name__, external_stylesheets=external_stylesheets) # assume you have a "long-form" data frame # see https://plotly.com/python/px-arguments/ for more options opts = [] for i in unique: opts.append({'label': i, 'value': i}) layout = html.Div(children=[ html.H1(children='stats'), html.Div(children=''' Simple stuff. '''), dcc.Dropdown( id="my-drop", options=opts, multi=True, value=[unique[0]] ), #html.Button('Update Graph', id='submit-val', n_clicks=0) dcc.Graph(id='example-graph') ]) @app.callback( Output('example-graph', 'figure'), Input('my-drop', 'value'), ) def update_output_div(input_value): check = [] figures = [] unique = input_value for i in unique: m1 = 0 m2 = 0 m3 = 0 for index, row in state.iterrows(): if (row["Area"] == i): if row["Property Type"] == "Commerical": m1 += row["Price"] if row["Property Type"] == "Residential": m2 += row["Price"] if row["Property Type"] == "Res-Rental": m3 += row["Price"] check.extend([m1, m2, m3]) frames = [] data = {'Property Type': state["Property Type"].unique()} frames.append(pd.DataFrame(data)) for a in unique: newset = [] for s in range(3): newset.append(check[s]) complete = {a: newset} frames.append(pd.DataFrame(complete)) check = check[3:] result = pd.concat(frames, axis=1) fig = go.Figure() # fig = px.line(result, x=result['Property Type'], y=result[unique[0]], title="Analysis of Price over Property Type") # unique = unique[1:] for k in unique: fig.add_trace(go.Scatter(x=result['Property Type'], y=result[k], name=k, line_shape='linear')) # fig.add_scatter(x=result['Property Type'], y=result[k], name=k) fig.update_layout(title="Price by Property Type", xaxis_title="Property Type", yaxis_title="Price", legend_title="Areas") return fig if __name__ == '__main__': app.run_server(debug=True)
New to dash so any help would be amazing. Thank you!
Advertisement
Answer
I can’t confirm because you haven’t shared your imports, but it seems index
imports main
and main
import index
.
The way you’ve set it up causes app
to not be decorated with the callback function you define inside main.py
which results in an empty graph.
There are multiple ways to do it, but one idea is to create a function that takes app
as a parameter and decorates it with your callback functions:
# inside main.py def init_callbacks(app): @app.callback( Output("example-graph", "figure"), Input("my-drop", "value"), ) def update_output_div(input_value): # Do stuff...
Then inside index.py
you could do something like this:
import main app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) main.init_callbacks(app)
This way app
is decorated by the update_output_div
callback.
Keep in mind that elements in the main
module layout
don’t yet exist in app
‘s initial layout
when main.init_callbacks(app)
is executed. So it will probably give you a warning about elements with certain ids not existing in the layout. To prevent this you could add placeholder elements with those ids as children to page-content
inside index.py
or you could set suppress_callback_exceptions
to True
.