Announcing Dash Bio 1.0.0 🎉 : a one-stop-shop for bioinformatics and drug development visualizations.

Callback error - update_component 500 internal server error

Hi, The following script is throwing an error in the console.

dash_renderer.v2_0_0m1638520705.min.js:2 POST http://dash.exergenicsportal.com/_dash-update-component 500 (INTERNAL SERVER ERROR)
and then another error message "“Callback error updating …cop-slider.value…cop-slider.min…cop-slider.max…load-slider.value…load-slider.min…load-slider.max…lift-slider.value…lift-slider.min…lift-slider.max…percent-slider.value…percent-slider.min…percent-slider.max…”

and then

“Callback error updating …render-graph.figure…download.href…download.download…r2.children…coefs.children…matlab-coefs.children…”

new to python so struggling debugging this.

import io
import os

from pandas.io.formats import style
import dash 
import dash_auth
import pathlib
import pandas as pd
from math import sqrt
from dash import dcc
from dash import html
import plotly.express as px
from base64 import b64encode
import base64
import numpy as np
import plotly.graph_objects as go
from plotly.graph_objs import *
from dash.dependencies import Input, Output, State
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
#import plotly.graph_objs.layout.Scene as Scene

import base64
import datetime

import pathlib
from app import application

PATH = pathlib.Path(__file__).parent
DATA_PATH = PATH.joinpath("../datasets").resolve()




colors = {
    'background': '#272E34',
    'text': '#ffffff'
}

bStyle = {'backgroundColor':colors['background'],'color':colors['text']}



def scatterPoints(sd,scatter):

    if sd > 0: 
        x=0
        y=1
        z=2
        poly = PolynomialFeatures(degree=2)
        Xy = poly.fit_transform(scatter[[x,y]])
        model = LinearRegression()
        model.fit(Xy, scatter[z])
        RMSE = sqrt(sum((model.predict(Xy)-scatter[z])**2)/ (len(scatter)-2))
        r_sd = abs(np.subtract(model.predict(Xy),scatter[z])) / RMSE
        scatter = scatter[r_sd < float(sd)]

    xScat = scatter[0]
    yScat = scatter[1]
    zScat = scatter[2]

    return xScat, yScat, zScat

def parse_contents(contents, filename, date, chiller_num):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # Assume that the user uploaded a CSV file
            df = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
            i=chiller_num
            x = f'Chiller {i} Lift'
            y = f'Chiller {i} Load Proportion'
            z = f'Chiller {i} COP'
            # df = df[(df[x]>0)&(df[y]>0)&(df[z]>0)]
            df = df[(df[x]>0)&(df[y]>0)&(df[z]>0)&(df[z]<20)][[x,y,z]]
    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
        ])

    return df



image_filename = DATA_PATH.joinpath('exergenics_logo.png') 
encoded_image = base64.b64encode(open(image_filename, 'rb').read())

fig = go.Figure(data=[])
fig.update_layout(title="", title_x=0.5, autosize=True,
                    #width=1200, height=1000,
                    margin=dict(l=50, r=50, b=65, t=90))
fig.add_scatter3d()
fig.update_layout(
    font_family="Montserrat",
    font_color="white",
    title_font_color="white",
    title_font_size = 32,
    legend_title_font_color="green",
    paper_bgcolor="#272E34"              
)


layout = html.Div(style={'backgroundColor':colors['background'], "width":"100%", "height":"1250px"}, children=[
    
    ## DCC Store ids
    dcc.Store(id='raw-data'),
    dcc.Store(id='chiller-number'),

    ## Setup logo and header line 
    html.Div([
        html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode("utf-8")),
        style={
            "width":"30%",
            "height":"20%"
        }),

        html.H1(children='3D Curve-fitting and Rendering Dash App', style={
            'textAlign': 'center',
            'color':colors['text'],
        }),
    ], style={"textAlign":"center"}),


    html.Div([

        html.Div([
        ## Chiller number html block
        html.Div([
            html.H3("Step 1: Enter the chiller number that appears in the csv filename:", style=bStyle),
            dcc.Input(
                id="chiller-input", 
                type="text", 
                placeholder="", 
                style={
                    "width": "98%",
                    "height": "60px",
                    "lineHeight": "60px",
                    "borderWidth": "2px",
                    "borderRadius": "5px",
                    "textAlign": "center",
                    "margin": "5px"
            }),
        ]),

            html.H3("Step 2: Upload a single chiller csv file", style=bStyle),
        
            dcc.Upload(
                id="upload-data",
                children=html.Div(
                    ["Drag and drop or click to select a file to upload."]
                ),
                style={
                    "width": "98%",
                    "height": "60px",
                    "lineHeight": "60px",
                    "borderWidth": "2px",
                    "borderStyle": "dashed",
                    "borderRadius": "5px",
                    "textAlign": "center",
                    "margin": "5px",
                    "color":colors['text']
                },
                multiple=True,
                ),
            html.H5("* Please wait for graph to be rendered before proceeding. *", style=bStyle),
        ]),
        html.H3("Step 3: Adjust Load, Lift, COP slider for desired graph range", style=bStyle),
        ## Lift slider
        html.Div([
            html.H4(children="Lift", style={
                'textAlign': 'center',
                'color':colors['text']}),

            dcc.RangeSlider(
                id='lift-slider',
                # min=x_data.values.min(),
                # max=x_data.values.max(),
                min=0,
                max=30,
                step=0.1,
                #value=[x_data.values.min(),x_data.values.max()],
                value = [0,30],
                tooltip={"placement":"bottom", "always_visible":True},
            ),
        ],style={'width': '33%', 'display': 'inline-block'}),

        ## Load slider
        html.Div([
            html.H4(children="Load", style={
                'textAlign': 'center',
                'color':colors['text']}),
            dcc.RangeSlider(
                id='load-slider',
                # min=y_data.values.min(),
                # max=y_data.values.max(),
                min=0,
                max=1,
                step=0.1,
                #value=[y_data.values.min(),y_data.values.max()],
                value = [0,1],
                tooltip={"placement":"bottom", "always_visible":True},
        ),
        ],style={'width': '33%', 'display': 'inline-block'}),

        ## COP slider
        html.Div([
            html.H4(children="COP", style={
                'textAlign': 'center',
                'color':colors['text']}),

            dcc.RangeSlider(
                id='cop-slider',
                # min=z_data.values.min(),
                # max=z_data.values.max(),
                min=0,
                max=20,
                step=0.1,
                #value=[z_data.values.min(),z_data.values.max()],
                value = [0,20],
                tooltip={"placement":"bottom", "always_visible":True},
            ),
        ],style={'width': '33%','display': 'inline-block'}),

        ## SD slider
        html.H3("Step 4: Adjust Standard Deviation slider to re-calculate surface and observe change in r^2", style=bStyle),
        html.Div([
            html.H4(children="Standard Deviation", style={
                'textAlign': 'center',
                'color':colors['text']}),
            dcc.Slider(
                id='sd-slider',
                min=0,
                max=10,
                step=0.1,
                value=0,
                tooltip={"placement":"bottom", "always_visible":True},
        ),
        ],style={'width': '99%','display': 'inline-block'}),

        html.Div(id="r2", style={
                'textAlign': 'center',
                'color':colors['text']}),

        html.Br(),

        html.Div(id="coefs", style={
        'textAlign': 'center',
        'color':colors['text']}),

        html.Br(),

        html.Div(id="matlab-coefs", style={
        'textAlign': 'center',
        'color':colors['text']}),

        html.H3("Step 5: Change the degreee of freedom for Load and Lift fitting", style=bStyle),
        html.Div([
            html.H4(children="Lift DoF", style={
                'textAlign': 'center',
                'color':colors['text']}),
            dcc.Dropdown(
                id='lift-dof',
                options=[{'label':'1', 'value':1},
                            {'label':'2', 'value':2}], value=2,
            )
        ], style={'width': '49%', 'display': 'inline-block'}),
        
        html.Div([
            html.H4(children="Load DoF", style={
                'textAlign': 'center',
                'color':colors['text']}),
            dcc.Dropdown(
                id='load-dof',
                options=[{'label':'1', 'value':1},
                            {'label':'2', 'value':2}], value=2,
            )
        ], style={'width': '49%', 'display': 'inline-block'}),

        html.H3("Step 6: Download 3D render graph as html file", style=bStyle),
        html.Div([
            html.A(
                html.Button("Download HTML"), 
                id="download",
            )
        ], style={"textAlign":"center"}),



    ], style={'width': '39%','display': 'inline-block', "whitespace":"pre-wrap"}),

    html.Div(id='graph-container', children=[
        dcc.Graph(
            id='render-graph',
            figure = fig,
            style={
                'textAlign':'center',
            }
        ),
    ], style={'width': '60%',"display":"inline-block"})
])

## Callback to set chiller number from input
@application.callback(Output("chiller-number", "value"), Input("chiller-input", "value"))

def set_chiller_number(value):
    return value


## Upload CSV callback -> save relevant csv data into 'raw-data'
@application.callback(Output('raw-data', 'data'),
        Input('chiller-number', 'value'),
        Input('upload-data', 'contents'),
        State('upload-data', 'filename'),
        State('upload-data', 'last_modified'))

def updateRawData(chiller_number, list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
        children = [
            parse_contents(c, n, d, chiller_number) for c, n, d in
            zip(list_of_contents, list_of_names, list_of_dates)]

        i=chiller_number
        x = f'Chiller {i} Lift'
        y = f'Chiller {i} Load Proportion'
        z = f'Chiller {i} COP'
        #z = f'Chiller {i} COP (from data)'
        dataDict = {y: children[0][y], x: children[0][x], z: children[0][z]}
        print(pd.DataFrame(dataDict))
        return dataDict

@application.callback(
    [Output("cop-slider", "value"), 
    Output("cop-slider", "min"),
    Output("cop-slider", "max"),
    Output("load-slider", "value"),
    Output("load-slider", "min"),
    Output("load-slider", "max"),
    Output("lift-slider", "value"),
    Output("lift-slider", "min"),
    Output("lift-slider", "max")],
    [Input("raw-data", "data"),Input("chiller-number", "value")])

def update_slider(data, chiller_num):
    
    i=chiller_num
    x = f'Chiller {i} Lift'
    y = f'Chiller {i} Load Proportion'
    z = f'Chiller {i} COP'
    df = pd.DataFrame.from_dict(data)

    x_data = df[x]
    y_data = df[y]
    z_data = df[z]

    return [z_data.values.min(), z_data.values.max()], z_data.values.min(), z_data.values.max(),[y_data.values.min(), y_data.values.max()], y_data.values.min(), y_data.values.max(), [x_data.values.min(), x_data.values.max()], x_data.values.min(), x_data.values.max()

@application.callback(
    [Output("render-graph", "figure"), 
    Output("download", "href"),
    Output("download", "download"),
    Output("r2", "children"),
    Output("coefs", "children"),
    Output("matlab-coefs", "children")],
    [Input("cop-slider", "value"),
    Input("load-slider", "value"), 
    Input("lift-slider", "value"), 
    Input("sd-slider", "value"),
    Input("lift-dof", "value"),
    Input("load-dof", "value"),
    Input("raw-data", "data"),
    Input("chiller-number", "value")])

def update3Drender(copVal, loadVal, liftVal, sd, liftDoF, loadDoF, data, chiller_num):

    i=chiller_num
    x = f'Chiller {i} Lift'
    y = f'Chiller {i} Load Proportion'
    z = f'Chiller {i} COP'

    df = pd.DataFrame.from_dict(data)
    
    ## Set Lift, Load degree of Freedom
    if liftDoF == 1:
        lift_deg_1=True
    else:
        lift_deg_1=False
    
    if loadDoF == 1:
        load_deg_1 = True
    else:
        load_deg_1 = False

    # lift_deg_1 = True # variable
    # load_deg_1 = False # variable
    dof = 6
    if lift_deg_1:
        dof -= 1
    if load_deg_1:
        dof -= 1
    # Polynomial regression and its parameters (R-squared)
    poly = PolynomialFeatures(degree=2)
    Xy = poly.fit_transform(df[[x,y]])
    if lift_deg_1:
        Xy.swapaxes(0, 1)[3] = 0
    if load_deg_1:
        Xy.swapaxes(0, 1)[5] = 0
    model = LinearRegression()
    model.fit(Xy, df[z])

    if sd > 0: 
        RMSE = sqrt(sum((model.predict(Xy)-df[z])**2)/ (len(df)-2))
        r_sd = abs(np.subtract(model.predict(Xy),df[z])) / RMSE
        df = df[r_sd < float(sd)]
        poly = PolynomialFeatures(degree=2)
        Xy = poly.fit_transform(df[[x,y]])
        if lift_deg_1:
            Xy.swapaxes(0, 1)[3] = 0
        if load_deg_1:
            Xy.swapaxes(0, 1)[5] = 0
        model = LinearRegression()
        model.fit(Xy, df[z])

    intercept=model.intercept_.round(4)
    coef=model.coef_.round(4)

    coefs = f'p00 = {intercept}, p10 = {coef[1]}, p01= {coef[2]}, p20= {coef[3]}, p11= {coef[4]}, p02= {coef[5]}'
    matlab_coefs = f'Matlab chiller coefficients: ch{chiller_num} = [{intercept} {coef[1]} {coef[2]} {coef[3]} {coef[4]} {coef[5]}]'

    # R^2 for original data polynomial regression
    r2 = model.score(Xy,df[z])
    print(r2)
    # Plot original regression data
    x_data = df[x]
    y_data = df[y]
    z_data = df[z]

    mesh_size = .02
    margin = 0
    x_min, x_max = x_data.min() - margin, x_data.max() + margin
    y_min, y_max = y_data.min() - margin, y_data.max() + margin
    xrange = np.arange(x_min, x_max, mesh_size)
    yrange = np.arange(y_min, y_max, mesh_size)
    xx, yy = np.meshgrid(xrange, yrange)
    data = np.c_[xx.ravel(), yy.ravel()]
    data = poly.fit_transform(data)
    pred = model.predict(data)
    pred = pred.reshape(xx.shape)

    exergenicsColor = [[0, "rgb(122,181,215)"], [0.5, "rgb(34,177,238)"],[1.0, "rgb(34,42,42)"]]

    fig = go.Figure(data=[go.Surface(x=xrange, y=yrange, z=pred,name='Predicted',colorscale = exergenicsColor)])
    fig.update_traces(showscale=False)
    figure_title= f"Chiller {i}: COP vs Lift/Load"
    fig.update_layout(title=figure_title, title_x=0.5, autosize=True,
                    width=1150, height=950,
                    margin=dict(l=50, r=50, b=50, t=50))
    fig.add_scatter3d(x=x_data.values.flatten(), y=y_data.values.flatten(), z=z_data.values.flatten(),name='Data', mode='markers',marker=dict(size=1,              
                                color='rgb(0,0,0)'))

    fig.update_layout(
        font_family="Montserrat",
        font_color="white",
        title_font_color="white",
        title_font_size = 32,
        legend_title_font_color="green",
        paper_bgcolor="#272E34"              
    )

    fig.update_layout(scene = Scene(
                    xaxis = dict(nticks=6,range=[liftVal[-1],liftVal[0]]),
                    yaxis = dict(nticks=10,range=[loadVal[0],loadVal[-1]],tickformat='.00%'),
                    zaxis = dict(nticks=10,range=[copVal[0],copVal[-1]]),
                    xaxis_title="Lift (°C)",
                    yaxis_title="Load",
                    zaxis_title="COP"))

    fig.update_traces(hovertemplate="<br>".join([
        "Lift (°C): %{x:.2f}<extra></extra>",
        "Load: %{y}",
        "COP: %{z}"
    ]))
    camera = dict(
    eye=dict(x=2, y=0, z=.1)
    )

    

    config = dict({'scrollZoom': False,'displaylogo': False,'modeBarButtonsToRemove': ['resetCameraLastSave3d']})     

    fig.update_layout(scene_camera=camera)

    buffer = io.StringIO()

    fig.write_html(buffer, config=config)

    html_bytes = buffer.getvalue().encode()
    encoded = b64encode(html_bytes).decode()

    href="data:text/html;base64," + encoded

    return fig, href, figure_title+".html", "R2 = {:.2f}%".format(r2*100), coefs, matlab_coefs

Hi,

Just to help the readers out, could you try to run your application in debug mode using:

application.run_server(debug=True)

I can see the error comes from the last callback, but not more than that.

Hi,

I ran it in debug mode but no additional information came from the terminal after restart.

Here’s the javascript console log.

Screen Shot 2021-12-06 at 9.10.54 pm