Black Lives Matter. Please consider donating to Black Girls Code today.

Dash server not updating through examples - not able to stop the previous server?

Working through the Dash examples. When I load one such as the “Core Components” example. I copy it into my python editor (Canopy Enthought), run, and will see it in both Chrome and Firefox. I try to then load the “Update Graphs on Hover” example and run it. Even though the debug indicates “Running on http://127.0.0.1:8050”. Neither Firefox or Chrome will reload with the new script. Using Windows Pro 7.

A reproducible example would help a lot, with very clear instructions on the actual code you used (with links so others can try), what steps you’re doing, what you expected, and what actually happened. I’m guessing, for example, that you are wondering why it didn’t reload on the fly when you pasted it into your editor?

I’m just going by when you say you “load one” and then say that you copied it into your editor and chose run. I don’t have this editor, but I did an example like so:

  • created a file, test-app.py, pasted in this components example, saved file
  • opened a terminal and went to the directory, then did python test-app.py
  • I get this output:
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 123-456-789
  • I then deleted the contents of my file, pasting in the second example from here (multi-colored scatter plot)
  • upon saving, I get this in the terminal (still running):
* Detected change in '/path/to/dash-reload-test/test-app.py', reloading
 * Restarting with stat
  • when I Ctrl-R on the screen, the component example is gone and I have the scatter plot

Hopefully that helps a little bit? Without more details, I’m guessing, but the only things that come to mind are:

  • as far as I know, you will need to reload the page to see the new app. It won’t reload itself (at least without doing something to make that happen in the code)
  • note that the second example does not feature the debug=T arg to app.run_server(). This is what provides the instant restart of the server upon a file change. When I Ctrl-c to kill my running server, then restart with python test-app.py, I get the scatter plot again (current contents of my file). When I undid my delete/paste to get back to the components example and saved, I did not get the terminal output about Restarting with stat because the first app launched didn’t enable the debugger. Refreshing the page still shows the scatter plot, even though the file now contains the component example. In this case dash is not “watching” and you’ll have to kill the process and restart to show changes.

Hope something in there is useful!

Another guess: You might need to hit “Stop” on the first script before you hit “Run” on the second script.

Thanks. So, what I was doing was saving a file ‘dash_dropdown.py’:

# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_core_components as dcc

app = dash.Dash()

app.layout = html.Div([
html.Label('Dropdown'),
dcc.Dropdown(
    options=[
        {'label': 'New York City', 'value': 'NYC'},
        {'label': u'Montréal', 'value': 'MTL'},
        {'label': 'San Francisco', 'value': 'SF'}
    ],
    value='MTL'
),

html.Label('Multi-Select Dropdown'),
dcc.Dropdown(
    options=[
        {'label': 'New York City', 'value': 'NYC'},
        {'label': u'Montréal', 'value': 'MTL'},
        {'label': 'San Francisco', 'value': 'SF'}
    ],
    value=['MTL', 'SF'],
    multi=True
),

html.Label('Radio Items'),
dcc.RadioItems(
    options=[
        {'label': 'New York City', 'value': 'NYC'},
        {'label': u'Montréal', 'value': 'MTL'},
        {'label': 'San Francisco', 'value': 'SF'}
    ],
    value='MTL'
),

html.Label('Checkboxes'),
dcc.Checklist(
    options=[
        {'label': 'New York City', 'value': 'NYC'},
        {'label': u'Montréal', 'value': 'MTL'},
        {'label': 'San Francisco', 'value': 'SF'}
    ],
    values=['MTL', 'SF']
),

html.Label('Text Input'),
dcc.Input(value='MTL', type='text'),

html.Label('Slider'),
dcc.Slider(
    min=0,
    max=9,
    marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
    value=5,
),
], style={'columnCount': 2})

if __name__ == '__main__':
    app.run_server(debug=True)

I would save this file and run it. My browser would show it as advertised. I would then save a seperate file named ‘dash_update graph.py’:

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd

app = dash.Dash()

df = pd.read_csv(
'https://gist.githubusercontent.com/chriddyp/cb5392c35661370d95f300086accea51/raw/8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/indicators.csv')

available_indicators = df['Indicator Name'].unique()

app.layout = html.Div([
html.Div([

    html.Div([
        dcc.Dropdown(
            id='crossfilter-xaxis-column',
            options=[{'label': i, 'value': i} for i in available_indicators],
            value='Fertility rate, total (births per woman)'
        ),
        dcc.RadioItems(
            id='crossfilter-xaxis-type',
            options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
            value='Linear',
            labelStyle={'display': 'inline-block'}
        )
    ],
    style={'width': '49%', 'display': 'inline-block'}),

    html.Div([
        dcc.Dropdown(
            id='crossfilter-yaxis-column',
            options=[{'label': i, 'value': i} for i in available_indicators],
            value='Life expectancy at birth, total (years)'
        ),
        dcc.RadioItems(
            id='crossfilter-yaxis-type',
            options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
            value='Linear',
            labelStyle={'display': 'inline-block'}
        )
    ], style={'width': '49%', 'float': 'right', 'display': 'inline-block'})
], style={
    'borderBottom': 'thin lightgrey solid',
    'backgroundColor': 'rgb(250, 250, 250)',
    'padding': '10px 5px'
}),

html.Div([
    dcc.Graph(
        id='crossfilter-indicator-scatter',
        hoverData={'points': [{'customdata': 'Japan'}]}
    )
], style={'width': '49%', 'display': 'inline-block', 'padding': '0 20'}),
html.Div([
    dcc.Graph(id='x-time-series'),
    dcc.Graph(id='y-time-series'),
], style={'display': 'inline-block', 'width': '49%'}),

html.Div(dcc.Slider(
    id='crossfilter-year--slider',
    min=df['Year'].min(),
    max=df['Year'].max(),
    value=df['Year'].max(),
    step=None,
    marks={str(year): str(year) for year in df['Year'].unique()}
), style={'width': '49%', 'padding': '0px 20px 20px 20px'})
])

@app.callback(
    dash.dependencies.Output('crossfilter-indicator-scatter', 'figure'),
   [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--slider', 'value')])
def update_graph(xaxis_column_name, yaxis_column_name,
             xaxis_type, yaxis_type,
             year_value):
dff = df[df['Year'] == year_value]

return {
    'data': [go.Scatter(
        x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'],
        y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'],
        text=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],
        customdata=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],
        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'
    )
}

def create_time_series(dff, axis_type, title):
return {
    'data': [go.Scatter(
        x=dff['Year'],
        y=dff['Value'],
        mode='lines+markers'
    )],
    'layout': {
        'height': 225,
        'margin': {'l': 20, 'b': 30, 'r': 10, 't': 10},
        'annotations': [{
            'x': 0, 'y': 0.85, 'xanchor': 'left', 'yanchor': 'bottom',
            'xref': 'paper', 'yref': 'paper', 'showarrow': False,
            'align': 'left', 'bgcolor': 'rgba(255, 255, 255, 0.5)',
            'text': title
        }],
        'yaxis': {'type': 'linear' if axis_type == 'Linear' else 'log'},
        'xaxis': {'showgrid': False}
    }
}

@app.callback(
     dash.dependencies.Output('x-time-series', 'figure'),
     [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
    dash.dependencies.Input('crossfilter-xaxis-column', 'value'),
    dash.dependencies.Input('crossfilter-xaxis-type', 'value')])
    def update_y_timeseries(hoverData, xaxis_column_name, axis_type):
 country_name = hoverData['points'][0]['customdata']
dff = df[df['Country Name'] == country_name]
dff = dff[dff['Indicator Name'] == xaxis_column_name]
title = '<b>{}</b><br>{}'.format(country_name, xaxis_column_name)
return create_time_series(dff, axis_type, title)

@app.callback(
   dash.dependencies.Output('y-time-series', 'figure'),
  [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
  dash.dependencies.Input('crossfilter-yaxis-column', 'value'),
 dash.dependencies.Input('crossfilter-yaxis-type', 'value')])
def update_x_timeseries(hoverData, yaxis_column_name, axis_type):
dff = df[df['Country Name'] == hoverData['points'][0]['customdata']]
dff = dff[dff['Indicator Name'] == yaxis_column_name]
return create_time_series(dff, axis_type, yaxis_column_name)

if __name__ == '__main__':
app.run_server(debug = True)

When I would save this second file, and run it from IPython, it would indicate that it was running at 127.0.0:8050, but not matter what I did, my browser wouldn’t pick it up. I would refresh, delete history, delete web cache. Nothing would update the web browser portion.

You did give me an idea though, I copied and pasted the code from the update graph file, and pasted in over the dropdown file. When I ran the dropdown file it like that, it ran fine and updated with whatever code I entered. So once I run a certain file, that is the file I am running I guess. Also, this wouldn’t allow me to use Ctl - C to stop it. I had to restart the kernel every time I wanted to make updates. I don’t think this will do what I am wanting to for this project. I may try and pick this up again later to see if I can make it more robust.

Thanks for the assistance.

Hmmm. Based on your description, is it fair to say:

  • you create dash_dropdown.py, then do python ./dash_dropdown.py, and leave it running
  • you create dash_update_graph.py and then do python ./dash_update_graph.py

?

I’d expect that shouldn’t work, as they can’t both run at the same address (127.0.0.1:8050 is already in use from the first file launched)? I just tried this and get OSError: [Errno 98] Address already in use.

Maybe try outside of Ipython? Just manually run it with python file.py from a terminal/command prompt and you should be able to kill with Ctrl-C. This will remove a layer of potential complexity/pitfalls.

Lastly, maybe someone with more experience can help you with the true aim you’re going for… Like when you say “I don’t think this will do what I am wanting,” what is your project need that you need either two concurrent dash instances running, or reload-on-the-fly, or pasting over a file with another? I would guess eventually you’d just launch/deploy these and not touch them once running.

If you just need two different servers running, see this github issue. I just made one of my files feature the port option:

if __name__ == '__main__':
    app.run_server(debug=True, port=8000)

I can now run both at the same time, one at 127.0.0.1:8000 and the other at 127.0.0.1:8050 (default).

1 Like

No, I am not needing to run two different servers at the same time. I would try to stop the dropdown file BEFORE trying to run the update_graph file. I could never get it to shutdown as advertised. Always had to restart the kernel before I could run a different file, and then the server wouldn’t update. Am I missing a crucial bit of information here? If I stop the program and/or restart the kernel, does that effectively shutdown the server?

I tried running it from the command line prompt and received “lookuperror no codec search functions registered”. I confirmed that Python is added to my ‘Path’ and was able to start an IPython session from the command line.

What I am trying to do, is I have a python script that analyzes data from a couple of different files and then displays several graphs about that information. I am currently using a Jupyter Notebook, pandas, and plot.ly with some file dialog boxes courtesy of PyQt4.

I am needing to push this to other users that may not be as ‘tech nerd’ as I am, so I am trying to make it a little more robust and polished, and easy to use. I was hoping Dash would do this.

Thank you for the time in trying to help.

Ah, that’s helpful. I’m going to guess it’s some interaction between dash and jupyter/ipython, but I don’t have much experience. I just tried to replicate like so:

  • run jupyter lab from command line
  • paste in your dash_dropdown.py code from above
  • click run button
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
 * Restarting with stat
An exception has occurred, use %tb to see the full traceback.

SystemExit: 1
~/.local/lib/python3.6/site-packages/IPython/core/interactiveshell.py:2918: UserWarning:

To exit: use 'exit', 'quit', or Ctrl-D.

So I’m not even able to replicate at the moment. If this is an issue with dash and jupyter interaction, I found some posts that might be helpful (also indicates special things are required, which makes me think this is, indeed, why you’re having troubles):

Wow! So, that last link is a github issue and I just tried @chriddyp’s suggestion to just run with debug=False and it seems to work! Check it out. I’ve got two dash apps pasted, and the play/stop buttons work as expected, provided I reload after starting the second. The sequence is play, show it’s working, go back and stop, refresh to show it’s dead, start the second, reload to show it’s changed.

1 Like

I’m having the same Problem. Basically, after running one file, the Server only runs on that file, and running another file will not update the Server. Even restarting the ipython console or restarting anaconda does not help. Only restarting the PC solves the Problem.

I would appreciate any help on this

How are you running the file? In the terminal, in Jupyter Notebook, or in something else?

In iPython (Anaconda 3)

Hi all, I am having a similar issue however the above does not seem to fix it.

I have followed the tutorial step by step: https://dash.plot.ly/getting-started

Once I run the app through terminal I get the graph in my browser at 127.0.0.1:8050 as shown in the tutorial - so far so good.

However, when I make any changes to the code and save it - I can’t get the webpage to update the graph.

In contrast to answers above, restarting my laptop has not solved the issue.

I appreciate this may be an issue with the port however I cannot work out how to solve this.

Thanks,

Dudley

Same issue here. I change the tutorial code, save it but dash doesnt seem to register the changes. Refreshing the browser just shows the original page. Sentdex also seems to struggle with similar issues in his video tutorial series on Youtube.

I had the same problem with dash. Then I realized that when I have more than one jupyter notebook open it happens. So I closed all other jupyter notebook instances and the problem was solved.

plz close the jupyter kernel , it will work properly

Same issue here. It worked for the first hour then after messing with an assets folder stopped working. Has to do with that probably. Will try deleting it.

@EnjoysMath - we’re having a similar issue that you’re describing on our end. Can’t pinpoint the source either. did you find any resolution? TIA

@jezlax I would get the latest source code. Last time I tried a dash example it was reloading properly. I was running the example in the usual way with Wingware IDE. This was about a month ago that it was working properly.

good to know. we’re seeing this in our production app (not the sample code). happening across multiple IDEs. we’ve got a bunch of custom CSS and JS so it could be related to that. doesn’t break anything in the source code, but simply just a PITA to develop as ctrl+c won’t kill the app from the CMD and the hot reload doesn’t work for us.

@jezlax Can you post a minimal working example here that demonstrates the failure to switch example apps?

@jezlax

I have pip show dash giving:

Version: 1.7.0

So you might want to try:

pip install dash==1.7.0

I’m running a complex cytoscape example with a cities graph and deleting a node, and although there are some reload errors that show up, the app finally loads with the missing city reflected properly.

import dash
import dash_cytoscape as cyto
import dash_html_components as html
from dash.dependencies import Input, Output, State
import json

app = dash.Dash(__name__)

default_stylesheet = [
    {
        'selector': 'node',
        'style': {
            'background-color': '#BFD7B5',
            'label': 'data(label)'
        }
    }
]

nodes = [
    {
        'data': {'id': short, 'label': label},
        'position': {'x': 20*lat, 'y': -20*long}
    }
    for short, label, long, lat in (
        ('la', 'Los Angeles', 34.03, -118.25),
        ('nyc', 'New York', 40.71, -74),
        ('to', 'Toronto', 43.65, -79.38),
        ('mtl', 'Montreal', 45.50, -73.57),
        ('van', 'Vancouver', 49.28, -123.12),
        ('chi', 'Chicago', 41.88, -87.63),
        ('bos', 'Boston', 42.36, -71.06),
        ('hou', 'Houston', 29.76, -95.37)
    )
]

edges = [
    {'data': {'source': source, 'target': target}}
    for source, target in (
        ('van', 'la'),
        ('la', 'chi'),
        ('hou', 'chi'),
        ('to', 'mtl'),
        ('mtl', 'bos'),
        ('nyc', 'bos'),
        ('to', 'hou'),
        ('to', 'nyc'),
        ('la', 'nyc'),
        ('nyc', 'bos')
    )
]

app.layout = html.Div([
    html.Div([
        html.Button('Add Node', id='btn-add-node', n_clicks_timestamp=0),
        html.Button('Remove Node', id='btn-remove-node', n_clicks_timestamp=0)
    ]),    
    cyto.Cytoscape(
        id='cytoscape-elements-callbacks',
        layout={'name': 'preset'},
        elements=edges+nodes,
        stylesheet=default_stylesheet,
        style={'width': '100%', 'height': '450px'}
    ),
    html.P(id='cytoscape-tapNodeData-output'),
    html.P(id='cytoscape-tapEdgeData-output'),
    html.P(id='cytoscape-mouseoverNodeData-output'),
    html.P(id='cytoscape-mouseoverEdgeData-output')
])


@app.callback(Output('cytoscape-tapNodeData-output', 'children'),
              [Input('cytoscape-elements-callbacks', 'tapNodeData')])
def displayTapNodeData(data):
    if data:
        return "You recently clicked/tapped the city: " + data['label']


@app.callback(Output('cytoscape-tapEdgeData-output', 'children'),
              [Input('cytoscape-elements-callbacks', 'tapEdgeData')])
def displayTapEdgeData(data):
    if data:
        return "You recently clicked/tapped the edge between " + data['source'].upper() + " and " + data['target'].upper()


@app.callback(Output('cytoscape-mouseoverNodeData-output', 'children'),
              [Input('cytoscape-elements-callbacks', 'mouseoverNodeData')])
def displayTapNodeData(data):
    if data:
        return "You recently hovered over the city: " + data['label']


@app.callback(Output('cytoscape-mouseoverEdgeData-output', 'children'),
              [Input('cytoscape-elements-callbacks', 'mouseoverEdgeData')])
def displayTapEdgeData(data):
    if data:
        return "You recently hovered over the edge between " + data['source'].upper() + " and " + data['target'].upper()


@app.callback(Output('cytoscape-elements-callbacks', 'elements'),
              [Input('btn-add-node', 'n_clicks_timestamp'),
               Input('btn-remove-node', 'n_clicks_timestamp')],
              [State('cytoscape-elements-callbacks', 'elements')])
def update_elements(btn_add, btn_remove, elements):
    # If the add button was clicked most recently
    if int(btn_add) > int(btn_remove):
        next_node_idx = len(elements) - len(edges)

        # As long as we have not reached the max number of nodes, we add them
        # to the cytoscape elements
        if next_node_idx < len(nodes):
            return edges + nodes[:next_node_idx+1]

    # If the remove button was clicked most recently
    elif int(btn_remove) > int(btn_add):
        if len(elements) > len(edges):
            return elements[:-1]

    # Neither have been clicked yet (or fallback condition)
    return elements



if __name__ == '__main__':
    app.run_server(debug=True)