modelflowib 2.73__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modelBLfunk.py +180 -0
- model_Excel.py +332 -0
- model_cvx.py +139 -0
- model_dynare.py +173 -0
- model_financial_stability.py +88 -0
- model_latex.py +497 -0
- model_latex_class.py +808 -0
- model_parquet_mixin.py +424 -0
- modelclass.py +9828 -0
- modelconstruct.py +1496 -0
- modelconstruct_estimation.py +2872 -0
- modeldash.py +265 -0
- modeldashboot.py +202 -0
- modeldashsidebar.py +456 -0
- modeldekom.py +651 -0
- modeldiff.py +561 -0
- modeldisplay.py +550 -0
- modelestimation.py +1776 -0
- modelestimator_new.py +2613 -0
- modelflowib-2.73.dist-info/METADATA +156 -0
- modelflowib-2.73.dist-info/RECORD +44 -0
- modelflowib-2.73.dist-info/WHEEL +5 -0
- modelflowib-2.73.dist-info/licenses/license.md +10 -0
- modelflowib-2.73.dist-info/top_level.txt +39 -0
- modelgrab.py +318 -0
- modelgrabgdx.py +584 -0
- modelgrabwf2.py +1107 -0
- modelhelp.py +543 -0
- modelhtml.py +606 -0
- modelinvert.py +250 -0
- modeljupyter.py +824 -0
- modeljupytermagic.py +813 -0
- modelmacrograb.py +98 -0
- modelmanipulation.py +1461 -0
- modelmf.py +349 -0
- modelnet.py +114 -0
- modelnewton.py +2178 -0
- modelnormalize.py +430 -0
- modelpattern.py +428 -0
- modelreport.py +2187 -0
- modeluserfunk.py +97 -0
- modelvis.py +1038 -0
- modelwidget.py +718 -0
- modelwidget_input.py +1933 -0
modeljupyter.py
ADDED
|
@@ -0,0 +1,824 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Sat Jun 22 21:26:13 2019
|
|
4
|
+
|
|
5
|
+
@author: hanseni
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import ipywidgets as widgets
|
|
10
|
+
from IPython.display import display, clear_output,Latex, Markdown
|
|
11
|
+
import matplotlib.pylab as plt
|
|
12
|
+
import seaborn as sns
|
|
13
|
+
import os
|
|
14
|
+
import webbrowser as wb
|
|
15
|
+
import sys
|
|
16
|
+
import re
|
|
17
|
+
import fnmatch
|
|
18
|
+
import matplotlib.ticker as ticker
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
#import qgrid
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
from modelhelp import insertModelVar, finddec
|
|
27
|
+
import modelpattern as pt
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def vis_alt3(dfs,model,title='Show variables',basename='Baseline',altname='Alternative',trans={},legend=True):
|
|
31
|
+
''' display tabbed widget with results from different dataframes, usuallly 2 but more can be shown
|
|
32
|
+
|
|
33
|
+
dfs is a list of dataframes. They should be of same dimensionalities
|
|
34
|
+
|
|
35
|
+
'''
|
|
36
|
+
avar = dfs[0].columns
|
|
37
|
+
outlist = [widgets.Output() for var in avar]
|
|
38
|
+
outdiflist = [widgets.Output() for var in avar]
|
|
39
|
+
deplist = [widgets.Output() for var in avar]
|
|
40
|
+
reslist = [widgets.Output() for var in avar]
|
|
41
|
+
attlist = [widgets.Output() for var in avar]
|
|
42
|
+
varouttablist = [widgets.Tab(children = [out,outdif,att,dep,res])
|
|
43
|
+
for out,outdif,att,dep,res in zip(outlist,outdiflist,attlist,deplist,reslist)]
|
|
44
|
+
for var,varouttab in zip(avar,varouttablist):
|
|
45
|
+
for i,tabtext in enumerate(['Level','Impact','Attribution','Dependencies','Results']):
|
|
46
|
+
varouttab.set_title(i,tabtext)
|
|
47
|
+
|
|
48
|
+
controllist = [widgets.VBox([varouttab]) for varouttab in varouttablist]
|
|
49
|
+
tab = widgets.Tab(children = controllist)
|
|
50
|
+
for i,(var,out) in enumerate(zip(avar,controllist)):
|
|
51
|
+
tab.set_title(i, var)
|
|
52
|
+
|
|
53
|
+
def showvar(b):
|
|
54
|
+
sel = b['new']
|
|
55
|
+
out = outlist[sel]
|
|
56
|
+
outdif = outdiflist[sel]
|
|
57
|
+
dep = deplist[sel]
|
|
58
|
+
res = reslist[sel]
|
|
59
|
+
att = attlist[sel]
|
|
60
|
+
var = avar[sel]
|
|
61
|
+
with out:
|
|
62
|
+
clear_output()
|
|
63
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
64
|
+
ax.set_title(trans.get(var,var),fontsize=14)
|
|
65
|
+
ax.spines['right'].set_visible(False)
|
|
66
|
+
# ax.spines['top'].set_visible(False)
|
|
67
|
+
for i,df in enumerate(dfs):
|
|
68
|
+
alt=i if len(dfs) >= 3 else ''
|
|
69
|
+
data = df.loc[:,var]
|
|
70
|
+
data.name = f'{basename}' if i ==0 else f'{altname}{alt}'
|
|
71
|
+
data.plot(ax=ax,legend=legend,fontsize=14)
|
|
72
|
+
x_pos = data.index[-1]
|
|
73
|
+
if not legend:
|
|
74
|
+
if i == 0:
|
|
75
|
+
basevalue = data.values[-1]
|
|
76
|
+
else:
|
|
77
|
+
if (abs(data.values[-1]-basevalue) < 0.01 or
|
|
78
|
+
(abs(basevalue) > 100. and (1.-abs(data.values[-1]/basevalue) < 0.008))):
|
|
79
|
+
if i == 1:
|
|
80
|
+
ax.text(x_pos, data.values[-1] ,f' {basename} and {altname}{alt}',fontsize=14)
|
|
81
|
+
else:
|
|
82
|
+
ax.text(x_pos, data.values[-1] ,f' {altname}{alt}',fontsize=14)
|
|
83
|
+
ax.text(x_pos, basevalue ,f' {basename}',fontsize=14)
|
|
84
|
+
plt.show(fig)
|
|
85
|
+
with outdif:
|
|
86
|
+
clear_output()
|
|
87
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
88
|
+
ax.set_title(trans.get(var,var),fontsize=14)
|
|
89
|
+
ax.spines['right'].set_visible(False)
|
|
90
|
+
for i,df in enumerate(dfs):
|
|
91
|
+
if i == 0:
|
|
92
|
+
basedata = df.loc[:,var]
|
|
93
|
+
x_pos = data.index[-1]
|
|
94
|
+
else:
|
|
95
|
+
data = df.loc[:,var]-basedata
|
|
96
|
+
data.plot(ax=ax,legend=False,fontsize=14)
|
|
97
|
+
x_pos = data.index[-1]
|
|
98
|
+
alt=i if len(dfs) >= 3 else ''
|
|
99
|
+
ax.text(x_pos, data.values[-1] ,f' Impact of {altname}{alt}',fontsize=14)
|
|
100
|
+
plt.show(fig)
|
|
101
|
+
with dep:
|
|
102
|
+
clear_output()
|
|
103
|
+
model.draw(var,up=2,down=2,svg=1)
|
|
104
|
+
with res:
|
|
105
|
+
clear_output()
|
|
106
|
+
out = model.get_values(var).T.rename(columns={'Base':basename,'Last':altname})
|
|
107
|
+
out.style.set_caption(trans.get(var,var))
|
|
108
|
+
print(trans.get(var,var))
|
|
109
|
+
print(out)
|
|
110
|
+
with att:
|
|
111
|
+
clear_output()
|
|
112
|
+
#model.smpl(N-20,N)
|
|
113
|
+
if var in model.endogene:
|
|
114
|
+
print(f'What explains the difference between the {basename} and the {altname} run ')
|
|
115
|
+
print(model.allvar[var]['frml'])
|
|
116
|
+
model.explain(var,up=0,dec=1,size=(9,12),svg=1,HR=0)
|
|
117
|
+
else:
|
|
118
|
+
print(f'{var} is exogeneous and attribution can not be performed')
|
|
119
|
+
|
|
120
|
+
display(tab)
|
|
121
|
+
|
|
122
|
+
showvar({'new':0})
|
|
123
|
+
tab.observe(showvar,'selected_index')
|
|
124
|
+
return tab
|
|
125
|
+
|
|
126
|
+
def vis_alt4(dfs,model,title='Show variables',trans={},legend=True):
|
|
127
|
+
''' display tabbed widget with results from different dataframes, usuallly 2 but more can be shown
|
|
128
|
+
|
|
129
|
+
dfs is a list of dataframes. They should be of same dimensionalities
|
|
130
|
+
|
|
131
|
+
'''
|
|
132
|
+
avar = dfs[list(dfs.keys())[0]].columns
|
|
133
|
+
outlist = [widgets.Output() for var in avar]
|
|
134
|
+
outdiflist = [widgets.Output() for var in avar]
|
|
135
|
+
deplist = [widgets.Output() for var in avar]
|
|
136
|
+
reslist = [widgets.Output() for var in avar]
|
|
137
|
+
attlist = [widgets.Output() for var in avar]
|
|
138
|
+
varouttablist = [widgets.Tab(children = [out,outdif,att,dep,res])
|
|
139
|
+
for out,outdif,att,dep,res in zip(outlist,outdiflist,attlist,deplist,reslist)]
|
|
140
|
+
for var,varouttab in zip(avar,varouttablist):
|
|
141
|
+
for i,tabtext in enumerate(['Level','Impact','Attribution','Dependencies','Results']):
|
|
142
|
+
varouttab.set_title(i,tabtext)
|
|
143
|
+
|
|
144
|
+
controllist = [widgets.VBox([varouttab]) for varouttab in varouttablist]
|
|
145
|
+
tab = widgets.Tab(children = controllist)
|
|
146
|
+
for i,(var,out) in enumerate(zip(avar,controllist)):
|
|
147
|
+
tab.set_title(i, var)
|
|
148
|
+
|
|
149
|
+
def showvar(b):
|
|
150
|
+
sel = b['new']
|
|
151
|
+
out = outlist[sel]
|
|
152
|
+
outdif = outdiflist[sel]
|
|
153
|
+
dep = deplist[sel]
|
|
154
|
+
res = reslist[sel]
|
|
155
|
+
att = attlist[sel]
|
|
156
|
+
var = avar[sel]
|
|
157
|
+
with out:
|
|
158
|
+
clear_output()
|
|
159
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
160
|
+
ax.set_title(trans.get(var,var),fontsize=14)
|
|
161
|
+
ax.spines['right'].set_visible(False)
|
|
162
|
+
# ax.spines['top'].set_visible(False)
|
|
163
|
+
for i,(k,df) in enumerate(dfs.items()):
|
|
164
|
+
data = df.loc[:,var]
|
|
165
|
+
data.name = k
|
|
166
|
+
data.plot(ax=ax,legend=legend,fontsize=14)
|
|
167
|
+
x_pos = data.index[-1]
|
|
168
|
+
if not legend:
|
|
169
|
+
if i == 0:
|
|
170
|
+
basevalue = data.values[-1]
|
|
171
|
+
else:
|
|
172
|
+
if (abs(data.values[-1]-basevalue) < 0.01 or
|
|
173
|
+
(abs(basevalue) > 100. and (1.-abs(data.values[-1]/basevalue) < 0.008))):
|
|
174
|
+
if i == 1:
|
|
175
|
+
ax.text(x_pos, data.values[-1] ,f' {basename} and {altname}{alt}',fontsize=14)
|
|
176
|
+
else:
|
|
177
|
+
ax.text(x_pos, data.values[-1] ,f' {altname}{alt}',fontsize=14)
|
|
178
|
+
ax.text(x_pos, basevalue ,f' {basename}',fontsize=14)
|
|
179
|
+
plt.show(fig)
|
|
180
|
+
with outdif:
|
|
181
|
+
clear_output()
|
|
182
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
183
|
+
ax.set_title(trans.get(var,var),fontsize=14)
|
|
184
|
+
ax.spines['right'].set_visible(False)
|
|
185
|
+
for i,(k,df) in enumerate(dfs.items()):
|
|
186
|
+
if i == 0:
|
|
187
|
+
basedata = df.loc[:,var]
|
|
188
|
+
x_pos = data.index[-1]
|
|
189
|
+
else:
|
|
190
|
+
data = df.loc[:,var]-basedata
|
|
191
|
+
data.name = f' Impact of: {k}'
|
|
192
|
+
data.plot(ax=ax,legend=legend,fontsize=14)
|
|
193
|
+
x_pos = data.index[-1]
|
|
194
|
+
if not legend:
|
|
195
|
+
ax.text(x_pos, data.values[-1] ,f' Impact of: {k}',fontsize=14)
|
|
196
|
+
plt.show(fig)
|
|
197
|
+
with dep:
|
|
198
|
+
clear_output()
|
|
199
|
+
model.draw(var,up=2,down=2,svg=1)
|
|
200
|
+
with res:
|
|
201
|
+
clear_output()
|
|
202
|
+
out = pd.concat([df.loc[:,var] for k,df in dfs.items()],axis=1)
|
|
203
|
+
out.columns = [k for k in dfs.keys()]
|
|
204
|
+
out.style.set_caption(trans.get(var,var))
|
|
205
|
+
print(trans.get(var,var))
|
|
206
|
+
print(out.to_string())
|
|
207
|
+
with att:
|
|
208
|
+
clear_output()
|
|
209
|
+
#model.smpl(N-20,N)
|
|
210
|
+
if var in model.endogene:
|
|
211
|
+
print(f'What explains the difference between the {basename} and the {altname} run ')
|
|
212
|
+
print(model.allvar[var]['frml'])
|
|
213
|
+
model.explain(var,up=0,dec=1,size=(9,12),svg=1,HR=0)
|
|
214
|
+
else:
|
|
215
|
+
print(f'{var} is exogeneous and attribution can not be performed')
|
|
216
|
+
|
|
217
|
+
display(tab)
|
|
218
|
+
|
|
219
|
+
showvar({'new':0})
|
|
220
|
+
tab.observe(showvar,'selected_index')
|
|
221
|
+
|
|
222
|
+
class jup_keepviz() :
|
|
223
|
+
''' Class to vizualize a number of runs, primary in Jupyter
|
|
224
|
+
:dfs: A dict with runs {name :{'result' : df}}
|
|
225
|
+
:title: A title
|
|
226
|
+
:trans: a translation of variable names to more redable names
|
|
227
|
+
:legend: if legends has to be shown
|
|
228
|
+
|
|
229
|
+
'''
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def __init__(self,dfs,title='Show variables',trans={},legend=True,showfig=False):
|
|
234
|
+
self.dfs = dfs
|
|
235
|
+
self.title = title
|
|
236
|
+
self.trans = trans
|
|
237
|
+
self.legend = legend
|
|
238
|
+
self.showfig = showfig
|
|
239
|
+
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
def plot_level(self,var):
|
|
243
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
244
|
+
ax.set_title(f'Level: {self.trans.get(var,var)}',fontsize=14)
|
|
245
|
+
if self.legend :
|
|
246
|
+
ax.spines['right'].set_visible(True)
|
|
247
|
+
else:
|
|
248
|
+
ax.spines['right'].set_visible(False)
|
|
249
|
+
ax.spines['top'].set_visible(False)
|
|
250
|
+
|
|
251
|
+
# ax.spines['top'].set_visible(False)
|
|
252
|
+
for i,(k,df) in enumerate(self.dfs.items()):
|
|
253
|
+
data = df.loc[:,var]
|
|
254
|
+
data.name = k
|
|
255
|
+
data.plot(ax=ax,legend=self.legend,fontsize=14)
|
|
256
|
+
dec=finddec(df)
|
|
257
|
+
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda value,number: f'{value:,.{dec}f}'))
|
|
258
|
+
|
|
259
|
+
x_pos = data.index[-1]
|
|
260
|
+
if not self.legend:
|
|
261
|
+
if i == 0:
|
|
262
|
+
basename = k
|
|
263
|
+
basevalue = data.values[-1]
|
|
264
|
+
ax.text(x_pos, basevalue ,f' {basename}',fontsize=14)
|
|
265
|
+
else:
|
|
266
|
+
if (abs(data.values[-1]-basevalue) < 0.01 or
|
|
267
|
+
(abs(basevalue) > 100. and (1.-abs(data.values[-1]/basevalue) < 0.008))):
|
|
268
|
+
if i == 1:
|
|
269
|
+
ax.text(x_pos, data.values[-1] ,f' {basename} and {k}',fontsize=14)
|
|
270
|
+
else:
|
|
271
|
+
ax.text(x_pos, data.values[-1] ,f' {k}',fontsize=14)
|
|
272
|
+
|
|
273
|
+
else:
|
|
274
|
+
ax.text(x_pos, data.values[-1] ,f' {k}',fontsize=14)
|
|
275
|
+
return fig
|
|
276
|
+
|
|
277
|
+
def plot_dif(self,var):
|
|
278
|
+
fig,ax = plt.subplots(figsize=(10,6))
|
|
279
|
+
ax.set_title(f'{self.trans.get(var,var)}',fontsize=14)
|
|
280
|
+
if self.legend :
|
|
281
|
+
ax.spines['right'].set_visible(True)
|
|
282
|
+
else:
|
|
283
|
+
ax.spines['right'].set_visible(False)
|
|
284
|
+
for i,(k,df) in enumerate(self.dfs.items()):
|
|
285
|
+
if i == 0:
|
|
286
|
+
basedata = df.loc[:,var]
|
|
287
|
+
else:
|
|
288
|
+
data = df.loc[:,var]-basedata
|
|
289
|
+
data.name = f' Impact of: {k}'
|
|
290
|
+
dec=finddec(data)
|
|
291
|
+
|
|
292
|
+
data.plot(ax=ax,legend=self.legend,fontsize=14)
|
|
293
|
+
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda value,number: f'{value:,.{dec}f}'))
|
|
294
|
+
|
|
295
|
+
x_pos = basedata.index[-1]
|
|
296
|
+
if not self.legend:
|
|
297
|
+
ax.text(x_pos, data.values[-1] ,f' Impact of: {k}',fontsize=14)
|
|
298
|
+
return fig
|
|
299
|
+
|
|
300
|
+
def formatnumber(self,var,out):
|
|
301
|
+
if out.abs().max(axis=1).max() >= 30.0:
|
|
302
|
+
return lambda number : f'{number:,.0f}'
|
|
303
|
+
else:
|
|
304
|
+
return lambda number : f'{number:,.6f}'
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class jupviz(jup_keepviz) :
|
|
308
|
+
'''
|
|
309
|
+
Class to vizualize a number of experiments in an tabbed ipywidget in a jupyter notebook
|
|
310
|
+
'''
|
|
311
|
+
|
|
312
|
+
def __call__(self):
|
|
313
|
+
self.vis()
|
|
314
|
+
|
|
315
|
+
def vis(self):
|
|
316
|
+
''' display tabbed widget with results from different dataframes, usuallly 2 but more can be shown
|
|
317
|
+
|
|
318
|
+
dfs is a list of dataframes. They should be of same dimensionalities
|
|
319
|
+
|
|
320
|
+
'''
|
|
321
|
+
self.basekey = [key for key in self.dfs.keys()][0]
|
|
322
|
+
|
|
323
|
+
wexperiment_name = widgets.Text(value=self.basekey,placeholder='Type something',description='Name of these experiments:',
|
|
324
|
+
layout={'width':'55%'},style={'description_width':'45%'})
|
|
325
|
+
|
|
326
|
+
wsavefig = widgets.Button(description="Save figure")
|
|
327
|
+
wbut = widgets.HBox([wsavefig,wexperiment_name])
|
|
328
|
+
|
|
329
|
+
wfile_folder = widgets.Text(value = 'test2',placeholder='Type something',description='Figure saved in:',
|
|
330
|
+
layout={'width':'65%'},style={'description_width':'25%'},visible=False,disabled=True)
|
|
331
|
+
wfile_folder.layout.visibility = 'hidden'
|
|
332
|
+
|
|
333
|
+
wopen = widgets.Button(description="Open the saved figures")
|
|
334
|
+
wopen.layout.visibility = 'hidden'
|
|
335
|
+
|
|
336
|
+
winputstring = widgets.VBox([wfile_folder,wopen])
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
avar = self.dfs[list(self.dfs.keys())[0]].columns
|
|
340
|
+
outlist = [widgets.Output() for var in avar]
|
|
341
|
+
outdiflist = [widgets.Output() for var in avar]
|
|
342
|
+
reslist = [widgets.Output() for var in avar]
|
|
343
|
+
resdiflist = [widgets.Output() for var in avar]
|
|
344
|
+
varouttablist = [widgets.Tab(children = [out,outdif,res,resdif])
|
|
345
|
+
for out,outdif,res,resdif in zip(outlist,outdiflist,reslist,resdiflist)]
|
|
346
|
+
for var,varouttab in zip(avar,varouttablist):
|
|
347
|
+
for i,tabtext in enumerate(['Level','Impact','Level data','Impact data']):
|
|
348
|
+
varouttab.set_title(i,tabtext)
|
|
349
|
+
|
|
350
|
+
controllist = [widgets.VBox([varouttab]) for varouttab in varouttablist]
|
|
351
|
+
tab = widgets.Tab(children = controllist)
|
|
352
|
+
|
|
353
|
+
for i,(var,out) in enumerate(zip(avar,controllist)):
|
|
354
|
+
tab.set_title(i, var)
|
|
355
|
+
|
|
356
|
+
def showvar(b):
|
|
357
|
+
wfile_folder.layout.visibility = 'hidden'
|
|
358
|
+
wopen.layout.visibility = 'hidden'
|
|
359
|
+
|
|
360
|
+
sel = b['new']
|
|
361
|
+
out = outlist[sel]
|
|
362
|
+
outdif = outdiflist[sel]
|
|
363
|
+
res = reslist[sel]
|
|
364
|
+
resdif = resdiflist[sel]
|
|
365
|
+
var = avar[sel]
|
|
366
|
+
self.selected = sel
|
|
367
|
+
self.selected_var = var
|
|
368
|
+
with out:
|
|
369
|
+
clear_output()
|
|
370
|
+
self.fig_level = self.plot_level(var)
|
|
371
|
+
plt.show(self.fig_level)
|
|
372
|
+
with outdif:
|
|
373
|
+
clear_output()
|
|
374
|
+
self.fig_dif = self.plot_dif(var)
|
|
375
|
+
plt.show(self.fig_dif)
|
|
376
|
+
with res:
|
|
377
|
+
clear_output()
|
|
378
|
+
out = pd.concat([df.loc[:,var] for k,df in self.dfs.items()],axis=1)
|
|
379
|
+
out.columns = [k for k in self.dfs.keys()]
|
|
380
|
+
print(self.trans.get(var,var))
|
|
381
|
+
print(out.to_string(float_format= self.formatnumber(var,out)))
|
|
382
|
+
with resdif:
|
|
383
|
+
clear_output()
|
|
384
|
+
try:
|
|
385
|
+
baseline = self.dfs[[k for i,k in enumerate(self.dfs.keys()) if i == 0][0]].loc[:,[var]]
|
|
386
|
+
out = pd.concat([df.loc[:,[var]]-baseline for i,(k,df) in enumerate(self.dfs.items()) if i >= 1],axis=1)
|
|
387
|
+
out.columns = [k for i,k in enumerate(self.dfs.keys()) if i >= 1]
|
|
388
|
+
# out.style.set_caption(self.trans.get(var,var))
|
|
389
|
+
print(self.trans.get(var,var))
|
|
390
|
+
print(out.to_string(float_format= self.formatnumber(var,out)))
|
|
391
|
+
except:
|
|
392
|
+
print('No Data')
|
|
393
|
+
|
|
394
|
+
outtab = widgets.VBox([tab,wbut,winputstring])
|
|
395
|
+
def savefig(s):
|
|
396
|
+
self.graph_folde=os.path.join(os.getcwd(),'experiments',wexperiment_name.value,'graph')
|
|
397
|
+
self.figlocation = os.path.join(self.graph_folde,f'{self.selected_var}')
|
|
398
|
+
self.figlocation_impact = os.path.join(self.graph_folde,f'{self.selected_var}-impact')
|
|
399
|
+
wfile_folder.layout.visibility = 'visible'
|
|
400
|
+
if self.showfig:
|
|
401
|
+
wopen.layout.visibility = 'visible'
|
|
402
|
+
else:
|
|
403
|
+
wopen.layout.visibility = 'hidden'
|
|
404
|
+
|
|
405
|
+
try:
|
|
406
|
+
if not os.path.exists(self.graph_folde):
|
|
407
|
+
os.makedirs(self.graph_folde)
|
|
408
|
+
except:
|
|
409
|
+
wfile_folder.value = f"Can't create {self.graph_folde}"
|
|
410
|
+
return
|
|
411
|
+
|
|
412
|
+
try:
|
|
413
|
+
self.fig_level.savefig(self.figlocation+'.svg')
|
|
414
|
+
self.fig_dif.savefig(self.figlocation_impact+'.svg')
|
|
415
|
+
self.fig_level.savefig(self.figlocation+'.pdf')
|
|
416
|
+
self.fig_dif.savefig(self.figlocation_impact+'.pdf')
|
|
417
|
+
wfile_folder.value = self.graph_folde
|
|
418
|
+
except:
|
|
419
|
+
wfile_folder.value = f"Can't write to {self.graph_folde}, remember to close"
|
|
420
|
+
|
|
421
|
+
def openfig_svg(s):
|
|
422
|
+
try:
|
|
423
|
+
wb.open(self.figlocation_impact+'.svg',new=2)
|
|
424
|
+
wb.open(self.figlocation+'.svg',new=2)
|
|
425
|
+
# os.system(self.figlocation)
|
|
426
|
+
# os.system(self.figlocation_impact)
|
|
427
|
+
except:
|
|
428
|
+
wfile_folder.layout.visibility = 'visible'
|
|
429
|
+
wfile_folder.value = f"Can't open to {self.figlocation}.svg Try to download the file"
|
|
430
|
+
|
|
431
|
+
def openfig_pdf(s):
|
|
432
|
+
try:
|
|
433
|
+
wb.open(self.figlocation_impact+'.pdf')
|
|
434
|
+
wb.open(self.figlocation+'.pdf')
|
|
435
|
+
except:
|
|
436
|
+
wfile_folder.layout.visibility = 'visible'
|
|
437
|
+
wfile_folder.value = f"Can't open to {self.figlocation}.svg Try to download the file"
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
if self.showfig : wopen.on_click(openfig_svg)
|
|
442
|
+
|
|
443
|
+
wsavefig.on_click(savefig)
|
|
444
|
+
|
|
445
|
+
display(outtab)
|
|
446
|
+
|
|
447
|
+
showvar({'new':0})
|
|
448
|
+
tab.observe(showvar,'selected_index')
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
# Define data extraction
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def get_alt(mmodel,pat,onlyendo=False):
|
|
456
|
+
''' Retrieves variables matching pat from a model '''
|
|
457
|
+
varnames = mmodel.vlist(pat)
|
|
458
|
+
modelvar = mmodel.endogene if onlyendo else mmodel.exogene | mmodel.endogene
|
|
459
|
+
modelvarnames = list(dict.fromkeys([v for v in varnames if v in modelvar])) # to awoid dublicate names
|
|
460
|
+
per = mmodel.current_per
|
|
461
|
+
return [mmodel.basedf.loc[per,modelvarnames],mmodel.lastdf.loc[per,modelvarnames]]
|
|
462
|
+
|
|
463
|
+
def get_alt_dic(mmodel,pat,dfs,onlyendo=False):
|
|
464
|
+
''' Retrieves variables matching pat from a model '''
|
|
465
|
+
varnames = mmodel.vlist(pat)
|
|
466
|
+
modelvar = mmodel.endogene if onlyendo else mmodel.exogene | mmodel.endogene
|
|
467
|
+
modelvarnames = list(dict.fromkeys([v for v in varnames if v in modelvar])) # to awoid dublicate names
|
|
468
|
+
per = mmodel.current_per
|
|
469
|
+
return {k: df_dic['results'].loc[per,modelvarnames] for k,df_dic in dfs.items()}
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def inputwidget(model,basedf,slidedef={},radiodef=[],checkdef=[],modelopt={},varpat='RFF XGDPN RFFMIN GFSRPN DMPTRSH XXIBDUMMY'
|
|
477
|
+
,showout=1,trans={},base1name='',alt1name='',go_now=True,showvar=False):
|
|
478
|
+
'''Creates an input widgets for updating variables
|
|
479
|
+
|
|
480
|
+
:df: Baseline dataframe
|
|
481
|
+
:slidedef: dict with definition of variables to be updated by slider
|
|
482
|
+
:radiodef: dict of lists. each at first level defines a collection of radiobuttoms
|
|
483
|
+
second level defines the text for each leved and the variable to set or reset to 0
|
|
484
|
+
:varpat: the variables to show in the output widget
|
|
485
|
+
:showout: 1 if the output widget is to be called '''
|
|
486
|
+
|
|
487
|
+
lradiodef= len(radiodef)
|
|
488
|
+
lslidedef = len(slidedef)
|
|
489
|
+
lcheckdef = len(checkdef)
|
|
490
|
+
basename = base1name if base1name else 'Baseline'
|
|
491
|
+
altname = alt1name if alt1name else 'Alternative'
|
|
492
|
+
|
|
493
|
+
if lradiodef:
|
|
494
|
+
wradiolist = [widgets.RadioButtons(options=[i for i,j in cont],description=des,layout={'width':'70%'},
|
|
495
|
+
style={'description_width':'37%'}) for des,cont in radiodef.items()]
|
|
496
|
+
if len(wradiolist) <=2:
|
|
497
|
+
wradio = widgets.HBox(wradiolist)
|
|
498
|
+
else:
|
|
499
|
+
wradio = widgets.VBox(wradiolist)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
# define slidesets
|
|
504
|
+
if lslidedef:
|
|
505
|
+
wexp = widgets.Label(value="Input new parameter ",layout={'width':'52%'})
|
|
506
|
+
walt = widgets.Label(value=f'{altname}',layout={'width':'10%'})
|
|
507
|
+
wbas = widgets.Label(value=f'{basename}',layout={'width':'20%'})
|
|
508
|
+
whead = widgets.HBox([wexp,walt,wbas])
|
|
509
|
+
|
|
510
|
+
wset = [widgets.FloatSlider(description=des,
|
|
511
|
+
min=cont['min'],max=cont['max'],value=cont['value'],step=cont.get('step',0.01),
|
|
512
|
+
layout={'width':'60%'},style={'description_width':'40%'},readout_format = f":<,.{cont.get('dec',2)}f")
|
|
513
|
+
for des,cont in slidedef.items()]
|
|
514
|
+
formattest = ':>.2f'
|
|
515
|
+
waltval= [widgets.Label(value=f"{cont['value']:<,.{cont.get('dec',2)}f}",layout={'width':'10%'})
|
|
516
|
+
for des,cont in slidedef.items()]
|
|
517
|
+
wslide = [widgets.HBox([s,v]) for s,v in zip(wset,waltval)]
|
|
518
|
+
|
|
519
|
+
# cheklist
|
|
520
|
+
if lcheckdef:
|
|
521
|
+
wchecklist = [widgets.Checkbox(description=des,value=val) for des,var,val in checkdef]
|
|
522
|
+
wcheck = widgets.HBox(wchecklist)
|
|
523
|
+
|
|
524
|
+
# some buttons and text
|
|
525
|
+
wname = widgets.Text(value=basename,placeholder='Type something',description='Scenario name:',
|
|
526
|
+
layout={'width':'30%'},style={'description_width':'50%'})
|
|
527
|
+
wpat = widgets.Text(value=varpat,placeholder='Type something',description='Output variables:',
|
|
528
|
+
layout={'width':'65%'},style={'description_width':'30%'})
|
|
529
|
+
if showvar:
|
|
530
|
+
wpat.layout.visibility = 'visible'
|
|
531
|
+
else:
|
|
532
|
+
wpat.layout.visibility = 'hidden'
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
winputstring = widgets.HBox([wname,wpat])
|
|
536
|
+
|
|
537
|
+
wgo = widgets.Button(description="Run scenario")
|
|
538
|
+
wreset = widgets.Button(description="Reset to start")
|
|
539
|
+
wzero = widgets.Button(description="Set all to 0")
|
|
540
|
+
wsetbas = widgets.Button(description="Use as baseline")
|
|
541
|
+
wbut = widgets.HBox([wgo,wreset,wzero,wsetbas])
|
|
542
|
+
|
|
543
|
+
wvar = [whead]+wslide if lslidedef else []
|
|
544
|
+
if lradiodef: wvar = wvar + [wradio]
|
|
545
|
+
if lcheckdef: wvar = wvar + [wcheck]
|
|
546
|
+
|
|
547
|
+
w = widgets.VBox(wvar+[winputstring] +[wbut])
|
|
548
|
+
|
|
549
|
+
# This function is run when the button is clecked
|
|
550
|
+
firstrun = True
|
|
551
|
+
model.rundic = {}
|
|
552
|
+
|
|
553
|
+
def run(b):
|
|
554
|
+
nonlocal firstrun
|
|
555
|
+
nonlocal altname
|
|
556
|
+
# mulstart = model.basedf.copy()
|
|
557
|
+
mulstart = insertModelVar(basedf.copy(deep=True),model)
|
|
558
|
+
# model.smpl(df=mulstart)
|
|
559
|
+
|
|
560
|
+
# First update from the sliders
|
|
561
|
+
if lslidedef:
|
|
562
|
+
for i,(des,cont) in enumerate(slidedef.items()):
|
|
563
|
+
op = cont.get('op','=')
|
|
564
|
+
var = cont['var']
|
|
565
|
+
for var in cont['var'].split():
|
|
566
|
+
if op == '+':
|
|
567
|
+
mulstart.loc[model.current_per,var] = mulstart.loc[model.current_per,var] + wset[i].value
|
|
568
|
+
elif op == '%':
|
|
569
|
+
mulstart.loc[model.current_per,var] = mulstart.loc[model.current_per,var] * (1+wset[i].value/100)
|
|
570
|
+
elif op == '+impulse':
|
|
571
|
+
mulstart.loc[model.current_per[0],var] = mulstart.loc[model.current_per[0],var] + wset[i].value
|
|
572
|
+
elif op == '=start-':
|
|
573
|
+
startindex = mulstart.index.get_loc(model.current_per[0])
|
|
574
|
+
varloc = mulstart.columns.get_loc(var)
|
|
575
|
+
mulstart.iloc[:startindex,varloc] = wset[i].value
|
|
576
|
+
elif op == '=':
|
|
577
|
+
mulstart.loc[model.current_per,var] = wset[i].value
|
|
578
|
+
elif op == '=impulse':
|
|
579
|
+
mulstart.loc[model.current_per[0],var] = wset[i].value
|
|
580
|
+
else:
|
|
581
|
+
print(f'Wrong operator in {cont}.\nNot updated')
|
|
582
|
+
assert 1==3,'wRONG OPERATOR'
|
|
583
|
+
|
|
584
|
+
# now update from the radio buttons
|
|
585
|
+
if lradiodef:
|
|
586
|
+
for wradio,(des,cont) in zip(wradiolist,radiodef.items()):
|
|
587
|
+
# print(des,wradio.value,wradio.index,cont[wradio.index])
|
|
588
|
+
for v in cont:
|
|
589
|
+
mulstart.loc[model.current_per,v[1]] = 0.0
|
|
590
|
+
mulstart.loc[model.current_per,cont[wradio.index][1]] = 1.0
|
|
591
|
+
|
|
592
|
+
if lcheckdef:
|
|
593
|
+
for box,(des,var,_) in zip(wchecklist,checkdef):
|
|
594
|
+
mulstart.loc[model.current_per,var] = 1.0 * box.value
|
|
595
|
+
|
|
596
|
+
#with out:
|
|
597
|
+
clear_output()
|
|
598
|
+
mul = model(mulstart,**modelopt)
|
|
599
|
+
# model.mulstart=mulstart
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
clear_output()
|
|
603
|
+
display(w)
|
|
604
|
+
#_ = mfrbus['XGDPN RFF RFFMIN GFSRPN'].dif.rename(trans).plot(colrow=1,sharey=0)
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
if firstrun:
|
|
608
|
+
model.experiment_results = {}
|
|
609
|
+
model.experiment_results[basename] = {'results':model.lastdf.copy()}
|
|
610
|
+
firstrun = False
|
|
611
|
+
wname.value = f'{altname}'
|
|
612
|
+
else:
|
|
613
|
+
altname = wname.value
|
|
614
|
+
walt.value = f'{altname}'
|
|
615
|
+
model.experiment_results[altname] = {'results':model.lastdf.copy()}
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
if showout:
|
|
619
|
+
varpat_this = wpat.value
|
|
620
|
+
resdic = get_alt_dic(model,varpat_this,model.experiment_results)
|
|
621
|
+
a = jupviz(resdic,trans=trans)()
|
|
622
|
+
else:
|
|
623
|
+
a = vis_alt4(get_alt_dic(model,wpat.value,model.experiment_results),model,trans=trans)
|
|
624
|
+
|
|
625
|
+
def reset(b):
|
|
626
|
+
|
|
627
|
+
if lslidedef:
|
|
628
|
+
for i,(des,cont) in enumerate(slidedef.items()):
|
|
629
|
+
wset[i].value = cont['value']
|
|
630
|
+
|
|
631
|
+
if lradiodef:
|
|
632
|
+
for wradio in wradiolist:
|
|
633
|
+
wradio.index = 0
|
|
634
|
+
|
|
635
|
+
if lcheckdef:
|
|
636
|
+
for box,(des,var,defvalue) in zip(wchecklist,checkdef):
|
|
637
|
+
box.value = defvalue
|
|
638
|
+
|
|
639
|
+
def zeroset(b):
|
|
640
|
+
basename = base1name if base1name else 'Baseline'
|
|
641
|
+
walt.value = f'{altname}'
|
|
642
|
+
wbas.value = f'{basename}'
|
|
643
|
+
|
|
644
|
+
if lslidedef:
|
|
645
|
+
for i,(des,cont) in enumerate(slidedef.items()):
|
|
646
|
+
wset[i].value = type(cont['value'])(0.0)
|
|
647
|
+
|
|
648
|
+
if lradiodef:
|
|
649
|
+
for wradio in wradiolist:
|
|
650
|
+
wradio.index = 0
|
|
651
|
+
|
|
652
|
+
if lcheckdef:
|
|
653
|
+
for box,(des,var,defvalue) in zip(wchecklist,checkdef):
|
|
654
|
+
box.value = defvalue
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def setbas(b):
|
|
660
|
+
nonlocal basename
|
|
661
|
+
nonlocal firstrun
|
|
662
|
+
model.basedf = model.lastdf.copy(deep=True)
|
|
663
|
+
basename = wname.value
|
|
664
|
+
walt.value = f'{altname}'
|
|
665
|
+
wbas.value = f'{basename}'
|
|
666
|
+
wname.value = f'{basename}'
|
|
667
|
+
model.rundic = {}
|
|
668
|
+
firstrun = True
|
|
669
|
+
|
|
670
|
+
if lslidedef:
|
|
671
|
+
for i,(des,cont) in enumerate(slidedef.items()):
|
|
672
|
+
waltval[i].value= f"{cont['value']:<,.{cont.get('dec',2)}f}"
|
|
673
|
+
|
|
674
|
+
if lradiodef:
|
|
675
|
+
for wradio in wradiolist:
|
|
676
|
+
wradio.index = 0
|
|
677
|
+
|
|
678
|
+
if lcheckdef:
|
|
679
|
+
for box,(des,var,defvalue) in zip(wchecklist,checkdef):
|
|
680
|
+
box.value = defvalue
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
# Assign the function to the button
|
|
684
|
+
wgo.on_click(run)
|
|
685
|
+
wreset.on_click(reset)
|
|
686
|
+
wzero.on_click(zeroset)
|
|
687
|
+
wsetbas.on_click(setbas)
|
|
688
|
+
# out = widgets.Output()
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
if go_now:
|
|
692
|
+
run(None)
|
|
693
|
+
return w
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
def get_att_gui(totdif,var='FY',spat = '*',desdic={},use='level',kind='bar',perselect='per',ysize=10):
|
|
700
|
+
'''Creates a jupyter ipywidget to display model level
|
|
701
|
+
attributions '''
|
|
702
|
+
xvar=var
|
|
703
|
+
# print(f'{var=} {xvar}')
|
|
704
|
+
def show_all2(Variable,Periode,Save,Use):
|
|
705
|
+
global fig1,fig2
|
|
706
|
+
fig1 = totdif.totexplain(pat=Variable,top=0.87,use=Use,axvline=Periode,kind=kind)
|
|
707
|
+
display(fig1)
|
|
708
|
+
fig2 = totdif.totexplain(pat=Variable,vtype='per',per = Periode,top=0.85,use=Use,ysize=ysize)
|
|
709
|
+
display(fig2)
|
|
710
|
+
if Save:
|
|
711
|
+
fig1.savefig(f'Attribution-{Variable}-{use}.pdf')
|
|
712
|
+
fig2.savefig(f'Attribution-{Variable}-{Periode}-{use}.pdf')
|
|
713
|
+
print(f'Attribution-{Variable}-{use}.pdf and Attribution-{Variable}-{Periode}-{use}.pdf aare saved' )
|
|
714
|
+
plt.close('all')
|
|
715
|
+
show = widgets.interactive(show_all2,
|
|
716
|
+
Variable = widgets.Dropdown(options = sorted(totdif.model.endogene),value=xvar),
|
|
717
|
+
Periode = widgets.Dropdown(options = totdif.model.current_per) if perselect=='per'
|
|
718
|
+
else [f'{t.year}-{t.month}-{t.day}' for t in totdif.model.current_per],
|
|
719
|
+
Use = widgets.RadioButtons(options= ['level', 'growth'],description='Use'),
|
|
720
|
+
Save = widgets.Checkbox(description='Save the charts',value=False)
|
|
721
|
+
)
|
|
722
|
+
return show
|
|
723
|
+
|
|
724
|
+
def get_att_gui2(totdif,var='RP',spat = '*',desdic={},use='level',kind='bar'):
|
|
725
|
+
'''Creates a jupyter ipywidget to display model level
|
|
726
|
+
attributions for datily dates '''
|
|
727
|
+
def show_all2(Variable,Periode,Save,Use):
|
|
728
|
+
global fig1,fig2
|
|
729
|
+
fig1 = totdif.explain_all(pat=Variable,top=0.87,use=Use,kind='line',stacked=False,axvline=Periode,threshold=0.01,resample='m')
|
|
730
|
+
fig2 = totdif.totexplain(pat=Variable,vtype='per',per = Periode,top=0.85,use=Use,threshold=0.01)
|
|
731
|
+
if Save:
|
|
732
|
+
fig1.savefig(f'Attribution-{Variable}-{use}.pdf')
|
|
733
|
+
fig2.savefig(f'Attribution-{Variable}-{Periode}-{use}.pdf')
|
|
734
|
+
print(f'Attribution-{Variable}-{use}.pdf and Attribution-{Variable}-{Periode}-{use}.pdf aare saved' )
|
|
735
|
+
|
|
736
|
+
show = widgets.interactive(show_all2,
|
|
737
|
+
Variable = widgets.Dropdown(options = sorted(totdif.model.endogene),value=var),
|
|
738
|
+
Periode = widgets.Dropdown(options = [f'{t.year}-{t.month}-{t.day}' for t in mddm.totdekomp.model.current_per]),
|
|
739
|
+
Use = widgets.RadioButtons(options= ['level', 'growth'],description='Use'),
|
|
740
|
+
Save = widgets.Checkbox(description='Save the charts',value=False)
|
|
741
|
+
)
|
|
742
|
+
return show
|
|
743
|
+
|
|
744
|
+
def vtol(var):
|
|
745
|
+
''' replaces special characters in variable name to latex'''
|
|
746
|
+
return var.replace(r'_',r'\_').replace('{',r'\{').replace('}',r'\}')
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
def an_expression_to_latex(exp,funks=[]):
|
|
750
|
+
''' Returns a latex string from a list of terms (defined in the modelpattern module)
|
|
751
|
+
|
|
752
|
+
funks is a list of localy defines functions
|
|
753
|
+
'''
|
|
754
|
+
def t_to_latex(t):
|
|
755
|
+
if t.var:
|
|
756
|
+
var =vtol(t.var)
|
|
757
|
+
if t.lag:
|
|
758
|
+
return f'{var}_{{t{t.lag}}}'
|
|
759
|
+
else:
|
|
760
|
+
return f'{var}_t'
|
|
761
|
+
elif t.number:
|
|
762
|
+
return t.number
|
|
763
|
+
else:
|
|
764
|
+
if t.op == '*':
|
|
765
|
+
op=r'\times'
|
|
766
|
+
elif t.op == '$':
|
|
767
|
+
op=''
|
|
768
|
+
else:
|
|
769
|
+
op = t.op
|
|
770
|
+
return op
|
|
771
|
+
|
|
772
|
+
return ' '.join([t_to_latex(t) for t in pt.udtryk_parse(exp,funks=funks)])
|
|
773
|
+
|
|
774
|
+
def expressions_to_latex(expressions,funks=[],allign = True, disp = False):
|
|
775
|
+
''' Returns a latex string from a list of a list of terms
|
|
776
|
+
|
|
777
|
+
:funks: a list of local functions in the model
|
|
778
|
+
:allign: the first = is enclosed in & for alligning several equations in latex
|
|
779
|
+
:disp: the result is displayed
|
|
780
|
+
'''
|
|
781
|
+
|
|
782
|
+
texp = expressions if type(expressions) == list else [expressions ]
|
|
783
|
+
latex_list = [an_expression_to_latex(exp,funks=funks) for exp in texp]
|
|
784
|
+
if allign:
|
|
785
|
+
latex_list = [l.replace('=',' & = & ',1) for l in latex_list]
|
|
786
|
+
latex_out = r'\\'.join(latex_list)
|
|
787
|
+
latex_out = r'\begin{eqnarray*}'+latex_out+r'\end{eqnarray*}'
|
|
788
|
+
|
|
789
|
+
if disp:
|
|
790
|
+
display(Latex('$'+latex_out+'$'))
|
|
791
|
+
else:
|
|
792
|
+
return latex_out
|
|
793
|
+
|
|
794
|
+
def frml_as_latex(frml_in,funks=[],allign= True, name=True,disp=True,linespace = False):
|
|
795
|
+
''' Display formula
|
|
796
|
+
|
|
797
|
+
:funks: local functions
|
|
798
|
+
:allign: allign =
|
|
799
|
+
:name: also display the frml name
|
|
800
|
+
'''
|
|
801
|
+
frmls = frml_in if type(frml_in) == list else [frml_in ]
|
|
802
|
+
out = []
|
|
803
|
+
for i,frml in enumerate(frmls):
|
|
804
|
+
a,fr,n,udtryk= pt.split_frml(frml)
|
|
805
|
+
out_udtryk = an_expression_to_latex(udtryk,funks = funks)
|
|
806
|
+
out_frmlname = vtol(n) if name and n != '<>' else ''
|
|
807
|
+
if allign:
|
|
808
|
+
out_udtryk = out_udtryk.replace('=',' & = & ',1)+(r'\\[1em]' if linespace else '')
|
|
809
|
+
out.append(f'{out_frmlname} {out_udtryk}')
|
|
810
|
+
latex_out = r'\\'.join(out)
|
|
811
|
+
if allign:
|
|
812
|
+
latex_out = r'\begin{eqnarray*}'+latex_out+r'\end{eqnarray*}'
|
|
813
|
+
|
|
814
|
+
if disp:
|
|
815
|
+
display(Latex('$'+latex_out+'$'))
|
|
816
|
+
else:
|
|
817
|
+
return latex_out
|
|
818
|
+
|
|
819
|
+
def get_frml_latex(model,pat='*',name=True):
|
|
820
|
+
|
|
821
|
+
variabler = [var for p in pat.split() for var in fnmatch.filter(model.nrorder,p)]
|
|
822
|
+
frmls = [model.allvar[var]['frml'] for var in variabler if not model.allvar[var]['dropfrml']]
|
|
823
|
+
_=frml_as_latex(frmls,funks=model.funks,name=name)
|
|
824
|
+
|