Source code for modeldash

try:
    import dash_interactive_graphviz
    from jupyter_dash import JupyterDash
    import dash
   #from dash.dependencies import Input, Output, State
    #import dash_html_components as html
   # import dash_core_components as dcc
    from dash import Dash, callback, html, dcc, dash_table, Input, Output, State, MATCH, ALL
    import dash_bootstrap_components as dbc
    import plotly.graph_objs as go
except:
    ...

import webbrowser
from threading import Timer

import json
import networkx as nx


from pathlib import Path
import pandas as pd

from modelclass import model 
from modelhelp import cutout


#%%
if 0:
    smallmodel      = '''
    frml <> a = c + b $ 
    frml <> d1 = x + 3 * a(-1)+ c **2 +a  $ 
    frml <> d3 = x + 3 * a(-1)+c **3 $  
    Frml <> x = 0.5 * c +a$'''
    des = {'A':'Bruttonationalprodukt i faste  priser',
           'X': 'Eksport <æøåÆØÅ>;',
           'C': 'Forbrug'}
    mmodel = model(smallmodel,var_description=des,svg=1,browser=1)
    df = pd.DataFrame({'X' : [0.2,0.2] , 'C' :[0.,0.] , 'R':[1.,0.4] , 'P':[0.,0.4]})
    df2 = pd.DataFrame({'X' : [0.2,0.2] , 'C' :[10.,10.] , 'R':[1.,0.4] , 'P':[0.,0.4]})
    
    xx = mmodel(df)
    yy = mmodel(df2)
    
[docs] class Dash_Mixin():
[docs] def modeldashexplain(self,pre_var='',selected_data_show ='baseline+last run', debug=True,jupyter=False,show_trigger=False,port=5001): def get_stack(df,v='Guess it',heading='Yes'): pv = cutout(df,5. ) trace = [go.Bar(x=pv.columns, y=pv.loc[rowname,:], name=rowname,hovertemplate = '%{y:10.0f}%',) for rowname in pv.index] out = { 'data': trace, 'layout': go.Layout(title=f'{heading}', barmode='relative',legend_itemclick='toggleothers', yaxis = {'tickformat': ',.0','ticksuffix':'%'}) } return out def get_line(pv,v='Guess it',heading='Yes'): trace = [go.Line(x=pv.columns, y=pv.loc[rowname,:], name=rowname) for rowname in pv.index] out = { 'data': trace, 'layout': go.Layout(title=f'{heading}') } return out def generate_table(dataframe, max_rows=10): return html.Table([ html.Thead( html.Tr([html.Th('var')]+[html.Th(col) for col in dataframe.columns]) ), html.Tbody([ html.Tr([html.Td(dataframe.index[i])]+[html.Td(f'{dataframe.iloc[i][col]:25.2f}') for col in dataframe.columns]) for i in range(min(len(dataframe), max_rows)) ]) ]) if jupyter: app = JupyterDash(__name__) else: app = dash.Dash(__name__) selected_var = pre_var if pre_var else sorted(self.allvar.keys())[0] app.layout = html.Div( [ html.Div([ html.Div(dash_interactive_graphviz.DashInteractiveGraphviz(id="gv",engine='dot', dot_source = self.explain(selected_var,up=0,select=False,showatt=True,lag=True,debug=0,dot=True,HR=True)) , style={'display': 'inline-block', 'vertical-align': 'bottom', 'margin-left': '3vw', 'margin-top': '3vw'} ), html.Div(dcc.Graph( id='graph', figure=get_stack(nx.get_node_attributes(self.newgraph,'att')[selected_var],selected_var,heading=f'{selected_var}')) , style={'display': 'inline-block', 'vertical-align': 'top', 'margin-left': '3vw','margin-right': '3vw', 'margin-top': '3vw'} ) , ] , style=dict()), html.Div( [ html.H3("Variable"), dcc.Markdown( id='outvar-state', children=f'{selected_var}'), dcc.Dropdown(id='var',value=selected_var,options=[ dict(label=v, value=v) for v in sorted(self.allvar.keys())], ) , html.H3("Up, preceeding levels"), dcc.Dropdown(id="up",value=1,options=[ dict(label=engine, value=engine) for engine in list(range(10))], ), html.H3("Show"), dcc.RadioItems(id='data_show', options=[ {'label': 'Variables', 'value': False}, {'label': 'Attributions', 'value': True}, ], value=False ), dcc.RadioItems(id='graph_show', options=[ {'label': 'Values', 'value': 'values'}, {'label': 'Diff', 'value': 'diff'}, {'label': 'Attributions', 'value': 'att'}, ], value='values',labelStyle={'display': 'block'} ), html.H3("Graph orientation"), dcc.RadioItems(id='orient', options=[ {'label': 'Vertical', 'value': False}, {'label': 'Horisontal', 'value': True}, ], value=True ) ], style=dict(display="flex", flexDirection="column"), ), ], style=dict(position="absolute", height="100%", width="100%", display="flex"), ) @app.callback( [Output("gv", "dot_source"),Output('outvar-state', "children"),Output('graph', "figure")], [ Input('var', "value"),Input('gv', "selected_node"),Input('gv', "selected_edge"),Input('up', "value"), Input('data_show', "value"),Input('graph_show', "value"), Input('orient', "value")], State('outvar-state','children') ) def display_output( var,select_var,select_node,up,data_show,figtype,orient,outvar_state): # value=self.drawmodel(svg=1,all=True,browser=0,pdf=0,des=True,dot=True) ctx = dash.callback_context if ctx.triggered: trigger = ctx.triggered[0]['prop_id'].split('.')[0] if trigger in ['var']: try: outvar=var[:] except: return [dash.no_update,dash.no_update,dash.no_update] elif trigger == 'gv': pass try: xvar= select_var.split('(')[0] if xvar in self.endogene or xvar in self.exogene: outvar = xvar[:] except: outvar= select_node.split('->')[0] else: outvar=outvar_state value = self.explain(outvar,up=up,select=False,showatt=data_show,lag=True,debug=0,dot=True,HR=orient) # else: # value=self.draw(outvar,dot=True,up=int(up),down=int(down),all=False) if show_trigger: ctx_msg = json.dumps({ 'states': ctx.states, 'triggered': ctx.triggered, 'inputs': ctx.inputs }, indent=2) print(ctx_msg) # print(f'{outvar=},{data_show=}') # print(value) if outvar in self.endogene: if figtype == 'values': out_graph = get_line(nx.get_node_attributes(self.newgraph,'values')[outvar].iloc[:2,:],outvar,outvar) elif figtype == 'diff': out_graph = get_line(nx.get_node_attributes(self.newgraph,'values')[outvar].iloc[[2],:],outvar,outvar) elif figtype == 'att': out_graph = get_stack(nx.get_node_attributes(self.newgraph,'att')[outvar],outvar,outvar) else: out_graph = get_line(nx.get_node_attributes(self.newgraph,'values')[outvar].iloc[[2],:],outvar,outvar) else: out_graph= dash.no_update return [value,outvar,out_graph] def open_browser(port=port): webbrowser.open_new(f"http://localhost:{port}") if jupyter: Timer(1, open_browser).start() app.run_server(debug=debug,port=port,mode='external') else: Timer(1, open_browser).start() app.run_server(debug=debug,port=port)
if __name__ == "__main__": from modelclass import model class xmodel(model,Dash_Mixin): ... if not 'baseline' in locals(): mmodel,baseline = model.modelload('../Examples/ADAM/baseline.pcim',run=1,silent=0 ) scenarie = baseline.copy() scenarie.TG = scenarie.TG + 0.05 _ = mmodel(scenarie) setattr(model, "modeldashexplain", Dash_Mixin.modeldashexplain) mmodel.modeldashexplain('FY',jupyter=False,show_trigger=True,debug=False) #%% pd.options.plotting.backend = "plotly" df = pd.DataFrame(dict(a=[1,3,2], b=[3,2,1])) fig = df.plot() fig.show()