Scatter figure doesnt reset when updating with callback (python dash) Asked today Modified today Viewed 9 times

I have the following problem:

I try to plot a plotly.scatter plot combined with dash which should be changeable with sliders using callback.
The Sliders are working and the shown data is also changing but the old plot doesnt vanish even if i reload the page. I dont know if the problem is in the html component or in the callback.

I read thorugh the documentation (callbacks, advanced callbacks, sliders and some others) and also searched the forum for an answer.

(I asked the same question on stackoverflow, if you prefer to answer there

)

I appreciate every help and i hope the question is asked properly.
The code and picture are following:

from math import cos,sin,radians
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
from dash import Dash, dcc, html, Input, Output, callback
import pandas as pd

## DU PFOSTEN hast die Z Parameter miteinbezogen

def fE_tsaiwu(s,m):
    s1,s2,s3,s23,s13,s12=s[0],s[1],s[2],s[3],s[4],s[5]
    XT,YT,ZT,XC,YC,ZC,S12,S13,S23 = m['XT'], m['YT'], m['ZT'], m['XC'], m['YC'], m['ZC'], m['S12'], m['S13'], m['S23']  ## inputparameter
    f12, f13, f23 = m['f12'], m['f13'], m['f23']
    F1,  F2,  F3  = (1/XT)-(1/XC) , (1/YT)-(1/YC) , (1/ZT)-(1/ZC)
    F11, F22, F33 =     1/(XT*XC) ,     1/(YT*YC) ,     1/(ZT*ZC)
    F44, F55, F66 =    1/(S23**2) ,    1/(S13**2) ,     1/(S12**2)
    F12 = f12*(F11*F22)**0.5
    F13 = f13*(F11*F33)**0.5
    F23 = f23*(F22*F33)**0.5
    a=F11*(s1**2) + F22*(s2**2) + F33*(s3**2)+ 2*(F12*s1*s2 + F13*s1*s3 + F23*s2*s3)+\
    F44*(s23**2) + F55*(s13**2) + F66*(s12**2)
    if a==0:
        return 0
    b=F1*s1 + F2*s2 +F3*s3
    c=-1
    R=(-b+(b**2-4*a*c)**0.5)/(2*a)
    fE=1/R
    return fE

XTvar = 1000
YTvar = 40
ZTvar = 40
XCvar = 700
YCvar = 120
ZCvar = 120

# To pass XTvar
def getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar):
    grp = {"name": "E-glass/Epoxy", "units": "MPa-mm-Mg", "type": "UD", "fiber": "E-glass",             
        "Vf": 0.55, "rho": 2000E-12,
        "description": "Typical UD E-glass/Epoxy from TMM4175",  
        "E1": 40000, "E2": 10000, "E3": 10000, 
        "v12": 0.3, "v13": 0.3, "v23": 0.4, 
        "G12": 3800, "G13": 3800, "G23": 3400, 
        "a1": 7e-06, "a2": 2.2e-05, "a3": 2.2e-05, 
        "XT": XTvar, "YT": YTvar, "ZT": ZTvar,                                                                ## XT as Variable befroe 1000 // YT 40 ZT 40
        "XC": XCvar, "YC": YCvar, "ZC": ZCvar,                                                                      ## XC 700 YC 120 ZC 120
        "S12": 70, "S13": 70, "S23": 40,                                                                   
        "f12":-0.5, "f13":-0.5, "f23":-0.5}
    return grp

stressCases = (150, 0, 0, 0, 0, 0) , (-120,-60,0,0,0,0) , (1000,60,0,0,0,0) , (0,0,0,0,0,150)

for s in stressCases:
    fE=fE_tsaiwu(s,getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
    # print(fE)

s1,s2=[],[]

for a in np.linspace(0,360,3600):
    s1i=cos(radians(a))
    s2i=sin(radians(a))
    fe=fE_tsaiwu((s1i,s2i,0,0,0,0),getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
    s1.append(s1i/fe)
    s2.append(s2i/fe)

def s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar):
    for a in np.linspace(0,360,3600):
        s1i=cos(radians(a))
        s2i=sin(radians(a))
        fe=fE_tsaiwu((s1i,s2i,0,0,0,0),getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
        s1.append(s1i/fe)
        s2.append(s2i/fe)
    return s1, s2

s1, s2 = s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar)

app = Dash(__name__)

app.layout = html.Div([
    dcc.Graph(
        id='Tsai',
        # figure=fig
        figure = {}
    ),
    html.H3(children='XTvar'),
    html.H5(children='Der Wert des Sliders wird hier direkt unter dem momentanen Punkt angezeigt'),
    dcc.Slider(
        id= "XTvar",
        min = 1,
        max = 1500,
        value = 1000,
           tooltip={"placement": "bottom", "always_visible": True}
    ),
    html.H3(children='YTvar'),
    dcc.Slider(
        id= "YTvar",
        min = 1,
        max = 50,
        value = 40,
    ),
    html.H3(children='ZTvar'),
    dcc.Slider(
        id= "ZTvar",
        min = 1,
        max = 50,
        value = 40,
    ),
    html.H3(children='XCvar'),
    dcc.Slider(
        id= "XCvar",
        min = 500,
        max = 1000,
        value = 700,
    ),
    html.H3(children='YCvar'),
    dcc.Slider(
        id= "YCvar",
        min = 100,
        max = 150,
        value = 120,
    ),
    html.H3(children='ZCvar'),
    dcc.Slider(
        id= "ZCvar",
        min = 100,
        max = 150,
        value = 120,
    )
])
@app.callback(
    Output(component_id='Tsai', component_property='figure'),
    Input(component_id='XTvar', component_property='value'),
    Input(component_id='YTvar', component_property='value'),
    Input(component_id='ZTvar', component_property='value'),
    Input(component_id='XCvar', component_property='value'),
    Input(component_id='YCvar', component_property='value'),
    Input(component_id='ZCvar', component_property='value')
)
def updatefigure(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar):
    df = zip(s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
    fig = px.scatter(df,s1, s2)
    return fig

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


Okay, so s1 and s2 keep getting appended, so the previous traces are going to remain.

The problem was with the callback and the way your were defining s1 and s2

Here is what to do:


# this seems redundant (just a repeat of the s_out function  below)
#for a in np.linspace(0,360,3600):
    #s1i=cos(radians(a))
    #s2i=sin(radians(a))
    #fe=fE_tsaiwu((s1i,s2i,0,0,0,0),getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
    #s1.append(s1i/fe)
    #s2.append(s2i/fe)

def s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar):
    # you need to instantiate empty lists at the beginning of the function call
    s1,s2=[],[]
    for a in np.linspace(0,360,3600):
        s1i=cos(radians(a))
        s2i=sin(radians(a))
        fe=fE_tsaiwu((s1i,s2i,0,0,0,0),getm(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
        s1.append(s1i/fe)
        s2.append(s2i/fe)
    return s1, s2


@app.callback(
    Output(component_id='Tsai', component_property='figure'),
    Input(component_id='XTvar', component_property='value'),
    Input(component_id='YTvar', component_property='value'),
    Input(component_id='ZTvar', component_property='value'),
    Input(component_id='XCvar', component_property='value'),
    Input(component_id='YCvar', component_property='value'),
    Input(component_id='ZCvar', component_property='value')
)
def updatefigure(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar):
    df = zip(s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar))
    # create s1 and s2 within the callback function
    s1, s2 = s_out(XTvar, YTvar, ZTvar, XCvar, YCvar, ZCvar)
    fig = px.scatter(df,s1, s2)
    return fig

 

I think this addresses your question

2 Likes

Thank you. I was working on it for days and couldnt figure it out yet it was so simple.
And also thank you for pointing out the redundancy, it was a relict from the calculation tests.

1 Like