modelflowib 2.79__tar.gz → 2.80__tar.gz
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.
- {modelflowib-2.79 → modelflowib-2.80}/PKG-INFO +1 -1
- {modelflowib-2.79 → modelflowib-2.80}/modelclass.py +79 -35
- {modelflowib-2.79 → modelflowib-2.80}/modelflowib.egg-info/PKG-INFO +1 -1
- {modelflowib-2.79 → modelflowib-2.80}/pyproject.toml +1 -1
- {modelflowib-2.79 → modelflowib-2.80}/README.md +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/license.md +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelBLfunk.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_Excel.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_cvx.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_dynare.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_financial_stability.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_latex.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_latex_class.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/model_parquet_mixin.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelconstruct.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelconstruct_estimation.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldash.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldashboot.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldashsidebar.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldekom.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldiff.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeldisplay.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelestimation.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelestimator_new.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelflowib.egg-info/SOURCES.txt +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelflowib.egg-info/dependency_links.txt +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelflowib.egg-info/requires.txt +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelflowib.egg-info/top_level.txt +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelgrab.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelgrabgdx.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelgrabwf2.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelhelp.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelhtml.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelinvert.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeljupyter.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeljupytermagic.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelmacrograb.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelmanipulation.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelmf.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelnet.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelnewton.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelnormalize.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelpattern.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelreport.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelsolver_ng.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modeluserfunk.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelvis.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelwidget.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/modelwidget_input.py +0 -0
- {modelflowib-2.79 → modelflowib-2.80}/setup.cfg +0 -0
|
@@ -3907,20 +3907,20 @@ class Graph_Draw_Mixin():
|
|
|
3907
3907
|
|
|
3908
3908
|
def drawendo(self, **kwargs):
|
|
3909
3909
|
'''draws a graph of of the whole model'''
|
|
3910
|
-
alllinks =
|
|
3911
|
-
return self.
|
|
3910
|
+
alllinks = [node(0, n[1], n[0]) for n in self.endograph.edges()]
|
|
3911
|
+
return self.draw_links(alllinks, **kwargs)
|
|
3912
3912
|
|
|
3913
3913
|
def drawendo_lag_lead(self, **kwargs):
|
|
3914
3914
|
'''draws a graph of of the whole model'''
|
|
3915
|
-
alllinks =
|
|
3916
|
-
for n in self.endograph_lag_lead.edges()
|
|
3917
|
-
return self.
|
|
3915
|
+
alllinks = [node(0, n[1], n[0])
|
|
3916
|
+
for n in self.endograph_lag_lead.edges()]
|
|
3917
|
+
return self.draw_links(alllinks, **kwargs)
|
|
3918
3918
|
|
|
3919
3919
|
def drawmodel(self, lag=True, **kwargs):
|
|
3920
3920
|
'''draws a graph of of the whole model'''
|
|
3921
3921
|
graph = self.totgraph if lag else self.totgraph_nolag
|
|
3922
|
-
alllinks =
|
|
3923
|
-
return self.
|
|
3922
|
+
alllinks = [node(0, n[1], n[0]) for n in graph.edges()]
|
|
3923
|
+
return self.draw_links(alllinks, **kwargs)
|
|
3924
3924
|
|
|
3925
3925
|
def plotadjacency(self, size=(5, 5), title='Structure', nolag=False):
|
|
3926
3926
|
'''
|
|
@@ -3970,14 +3970,26 @@ class Graph_Draw_Mixin():
|
|
|
3970
3970
|
self.upwalk(graph, navn.upper(), maxlevel=down, lpre=False,filter=filter))
|
|
3971
3971
|
return list(chain(uplinks, downlinks))
|
|
3972
3972
|
|
|
3973
|
-
|
|
3973
|
+
# in a browser (jupyterlite) there is no graphviz program, and the svg drawing
|
|
3974
|
+
# is the one which can be zoomed and has tooltips
|
|
3975
|
+
if sys.platform == 'emscripten':
|
|
3976
|
+
#: the engine of draw: dot for graphviz, else an engine of draw_nx
|
|
3977
|
+
draw_engine = 'svg'
|
|
3978
|
+
#: the engine of draw_nx: mpl for matplotlib or svg
|
|
3979
|
+
nx_engine = 'svg'
|
|
3980
|
+
else:
|
|
3981
|
+
draw_engine = 'dot'
|
|
3982
|
+
nx_engine = 'mpl'
|
|
3983
|
+
|
|
3984
|
+
def draw(self, navn, down=1, up=1, lag=False, endo=False, filter=0, engine='', **kwargs):
|
|
3974
3985
|
'''draws a graph of dependensies of navn up to maxlevel
|
|
3975
3986
|
|
|
3976
3987
|
:lag: show the complete graph including lagged variables else only variables.
|
|
3977
3988
|
:endo: Show only the graph for current endogenous variables
|
|
3978
3989
|
:down: level downstream
|
|
3979
3990
|
:up: level upstream
|
|
3980
|
-
:engine: dot draws with graphviz, mpl and svg are the engines of draw_nx
|
|
3991
|
+
:engine: dot draws with graphviz, mpl and svg are the engines of draw_nx,
|
|
3992
|
+
default self.draw_engine which is svg in a browser else dot
|
|
3981
3993
|
|
|
3982
3994
|
If graphviz fails - the dot program is for instance not there when running
|
|
3983
3995
|
in a browser - or if self.no_graphviz is True, draw_nx draws the graph
|
|
@@ -3985,19 +3997,40 @@ class Graph_Draw_Mixin():
|
|
|
3985
3997
|
'''
|
|
3986
3998
|
alllinks = self.get_alllinks(navn, down=down, up=up, lag=lag, endo=endo,
|
|
3987
3999
|
filter=filter)
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
4000
|
+
return self.draw_links(alllinks, navn=navn.upper(), engine=engine,
|
|
4001
|
+
down=down, up=up, filter=filter, **kwargs)
|
|
4002
|
+
|
|
4003
|
+
def draw_links(self, alllinks, navn='', engine='', **kwargs):
|
|
4004
|
+
'''Draws the links from get_alllinks, drawmodel, drawendo ... with the engine
|
|
4005
|
+
|
|
4006
|
+
:engine: dot draws with graphviz, mpl and svg are the engines of draw_nx,
|
|
4007
|
+
default self.draw_engine which is svg in a browser else dot
|
|
4008
|
+
|
|
4009
|
+
If graphviz fails - the dot program is for instance not there when running
|
|
4010
|
+
in a browser - or if self.no_graphviz is True, networkx draws the graph.
|
|
4011
|
+
'''
|
|
4012
|
+
if kwargs.get('dot', False):
|
|
4013
|
+
# the caller wants the dot source itself, for instance the dash apps.
|
|
4014
|
+
# The dot program is not needed for that, and networkx can not make it
|
|
4015
|
+
return self.todot2(alllinks, navn=navn, **kwargs)
|
|
4016
|
+
|
|
4017
|
+
engine = engine or self.draw_engine
|
|
4018
|
+
if engine == 'dot' and not self.no_graphviz:
|
|
3991
4019
|
try:
|
|
3992
|
-
return self.todot2(alllinks, navn=navn
|
|
4020
|
+
return self.todot2(alllinks, navn=navn, **kwargs)
|
|
3993
4021
|
except Exception as e:
|
|
3994
4022
|
print(f'Graphviz did not draw the graph: {e}\nDrawing with networkx')
|
|
3995
|
-
engine =
|
|
4023
|
+
engine = self.nx_engine
|
|
3996
4024
|
elif engine == 'dot':
|
|
3997
|
-
engine =
|
|
4025
|
+
engine = self.nx_engine # no_graphviz is set, then networkx draws it
|
|
3998
4026
|
|
|
3999
|
-
|
|
4000
|
-
|
|
4027
|
+
if not len(alllinks):
|
|
4028
|
+
print(f'No graph {navn}')
|
|
4029
|
+
if kwargs.get('filter', 0):
|
|
4030
|
+
print('Perhaps filter prunes to much')
|
|
4031
|
+
return
|
|
4032
|
+
G = self.alllinks_to_nx(alllinks, navn=navn, **kwargs)
|
|
4033
|
+
return self.display_nx(G, navn=navn, engine=engine, **kwargs)
|
|
4001
4034
|
|
|
4002
4035
|
#: Set to True on a model instance to make draw use draw_nx, so the networkx
|
|
4003
4036
|
#: drawing can be tested on a machine where graphviz works
|
|
@@ -4085,18 +4118,26 @@ class Graph_Draw_Mixin():
|
|
|
4085
4118
|
except Exception:
|
|
4086
4119
|
G.nodes[v]['values'] = None
|
|
4087
4120
|
|
|
4088
|
-
# the layer
|
|
4121
|
+
# the layer places the node in a column, so the drawing is layered like rankdir=LR
|
|
4089
4122
|
if navn in G:
|
|
4123
|
+
# the layer is the distance to navn, upstream to the left of it
|
|
4090
4124
|
upstream = nx.single_source_shortest_path_length(G.reverse(copy=False), navn)
|
|
4091
4125
|
downstream = nx.single_source_shortest_path_length(G, navn)
|
|
4126
|
+
for v in G.nodes:
|
|
4127
|
+
up_len, down_len = upstream.get(v), downstream.get(v)
|
|
4128
|
+
if up_len is not None and (down_len is None or up_len <= down_len):
|
|
4129
|
+
G.nodes[v]['layer'] = -up_len
|
|
4130
|
+
else:
|
|
4131
|
+
G.nodes[v]['layer'] = 0 if down_len is None else down_len
|
|
4092
4132
|
else:
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4133
|
+
# no variable in the center, like drawmodel, then the layer is the logical
|
|
4134
|
+
# order. The simultaneous blocks are condensed to one node, else there is
|
|
4135
|
+
# no order, and a node of such a block gets the layer of its block
|
|
4136
|
+
condensed = nx.condensation(G)
|
|
4137
|
+
for layer, blocks in enumerate(nx.topological_generations(condensed)):
|
|
4138
|
+
for block in blocks:
|
|
4139
|
+
for v in condensed.nodes[block]['members']:
|
|
4140
|
+
G.nodes[v]['layer'] = layer
|
|
4100
4141
|
|
|
4101
4142
|
for child, parent in G.edges:
|
|
4102
4143
|
try:
|
|
@@ -4166,23 +4207,21 @@ class Graph_Draw_Mixin():
|
|
|
4166
4207
|
if alllinks is None:
|
|
4167
4208
|
alllinks = self.get_alllinks(navn, down=down, up=up, lag=lag, endo=endo,
|
|
4168
4209
|
filter=filter)
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
print('Perhaps filter prunes to much')
|
|
4173
|
-
return
|
|
4174
|
-
G = self.alllinks_to_nx(alllinks, navn=navn.upper(), **kwargs)
|
|
4175
|
-
return self.display_nx(G, navn=navn.upper(), **kwargs)
|
|
4210
|
+
engine = kwargs.pop('engine', '') or self.nx_engine
|
|
4211
|
+
return self.draw_links(alllinks, navn=navn.upper(), engine=engine,
|
|
4212
|
+
down=down, up=up, filter=filter, **kwargs)
|
|
4176
4213
|
|
|
4177
|
-
def display_nx(self, G, navn='', engine='
|
|
4214
|
+
def display_nx(self, G, navn='', engine='', **kwargs):
|
|
4178
4215
|
'''Draws a graph made by alllinks_to_nx
|
|
4179
4216
|
|
|
4180
|
-
:engine: mpl draws with matplotlib, svg makes a svg drawing
|
|
4217
|
+
:engine: mpl draws with matplotlib, svg makes a svg drawing,
|
|
4218
|
+
default self.nx_engine which is svg in a browser else mpl
|
|
4181
4219
|
|
|
4182
4220
|
Each engine is the method display_nx_<engine>, so a new engine is made by
|
|
4183
4221
|
writing a new method. They all take the same graph and the positions from
|
|
4184
4222
|
nx_layout, and only do the drawing itself.
|
|
4185
4223
|
'''
|
|
4224
|
+
engine = engine or self.nx_engine
|
|
4186
4225
|
try:
|
|
4187
4226
|
displayer = getattr(self, f'display_nx_{engine}')
|
|
4188
4227
|
except AttributeError:
|
|
@@ -4330,7 +4369,12 @@ class Graph_Draw_Mixin():
|
|
|
4330
4369
|
svgname.write_text(svg, encoding='utf-8')
|
|
4331
4370
|
if browser:
|
|
4332
4371
|
# the same as display_graph, a separate window where the svg can be zoomed
|
|
4333
|
-
|
|
4372
|
+
try:
|
|
4373
|
+
wb.open(f'file://{svgname.resolve()}', new=2)
|
|
4374
|
+
except Exception as e:
|
|
4375
|
+
# in a browser (jupyterlite) there is no window to open from
|
|
4376
|
+
print(f'No separate window here: {e}')
|
|
4377
|
+
print(f'The drawing is saved as {svgname} and is shown below')
|
|
4334
4378
|
|
|
4335
4379
|
display(HTML(svg))
|
|
4336
4380
|
self.last_svg = svg
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "modelflowib" # PyPI distribution name
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.80" # OVERWRITTEN at build time from MF_VERSION
|
|
8
8
|
# (set_pyproject_version.py / make_pip.py -v)
|
|
9
9
|
description = "A tool to solve and manage dynamic economic and financial models"
|
|
10
10
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|