pyAgrum-nightly 2.2.1.9.dev202510271761405498__cp310-abi3-win_amd64.whl → 2.3.0.9.dev202510291761586496__cp310-abi3-win_amd64.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.

Potentially problematic release.


This version of pyAgrum-nightly might be problematic. Click here for more details.

Files changed (37) hide show
  1. pyagrum/_pyagrum.pyd +0 -0
  2. pyagrum/common.py +1 -1
  3. pyagrum/config.py +1 -0
  4. pyagrum/explain/_ComputationCausal.py +75 -0
  5. pyagrum/explain/_ComputationConditional.py +48 -0
  6. pyagrum/explain/_ComputationMarginal.py +48 -0
  7. pyagrum/explain/_CustomShapleyCache.py +110 -0
  8. pyagrum/explain/_Explainer.py +176 -0
  9. pyagrum/explain/_Explanation.py +70 -0
  10. pyagrum/explain/_FIFOCache.py +54 -0
  11. pyagrum/explain/_ShallCausalValues.py +204 -0
  12. pyagrum/explain/_ShallConditionalValues.py +155 -0
  13. pyagrum/explain/_ShallMarginalValues.py +155 -0
  14. pyagrum/explain/_ShallValues.py +296 -0
  15. pyagrum/explain/_ShapCausalValues.py +208 -0
  16. pyagrum/explain/_ShapConditionalValues.py +126 -0
  17. pyagrum/explain/_ShapMarginalValues.py +191 -0
  18. pyagrum/explain/_ShapleyValues.py +298 -0
  19. pyagrum/explain/__init__.py +81 -0
  20. pyagrum/explain/_explGeneralizedMarkovBlanket.py +152 -0
  21. pyagrum/explain/_explIndependenceListForPairs.py +146 -0
  22. pyagrum/explain/_explInformationGraph.py +264 -0
  23. pyagrum/explain/notebook/__init__.py +54 -0
  24. pyagrum/explain/notebook/_bar.py +142 -0
  25. pyagrum/explain/notebook/_beeswarm.py +174 -0
  26. pyagrum/explain/notebook/_showShapValues.py +97 -0
  27. pyagrum/explain/notebook/_waterfall.py +220 -0
  28. pyagrum/explain/shapley.py +225 -0
  29. pyagrum/lib/explain.py +11 -490
  30. pyagrum/pyagrum.py +17 -10
  31. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/METADATA +1 -1
  32. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/RECORD +36 -12
  33. pyagrum/lib/shapley.py +0 -661
  34. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/LICENSE.md +0 -0
  35. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/LICENSES/LGPL-3.0-or-later.txt +0 -0
  36. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/LICENSES/MIT.txt +0 -0
  37. {pyagrum_nightly-2.2.1.9.dev202510271761405498.dist-info → pyagrum_nightly-2.3.0.9.dev202510291761586496.dist-info}/WHEEL +0 -0
@@ -0,0 +1,152 @@
1
+ ############################################################################
2
+ # This file is part of the aGrUM/pyAgrum library. #
3
+ # #
4
+ # Copyright (c) 2005-2025 by #
5
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
6
+ # - Christophe GONZALES(_at_AMU) #
7
+ # #
8
+ # The aGrUM/pyAgrum library is free software; you can redistribute it #
9
+ # and/or modify it under the terms of either : #
10
+ # #
11
+ # - the GNU Lesser General Public License as published by #
12
+ # the Free Software Foundation, either version 3 of the License, #
13
+ # or (at your option) any later version, #
14
+ # - the MIT license (MIT), #
15
+ # - or both in dual license, as here. #
16
+ # #
17
+ # (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
18
+ # #
19
+ # This aGrUM/pyAgrum library is distributed in the hope that it will be #
20
+ # useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
22
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
23
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
24
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
25
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
26
+ # OTHER DEALINGS IN THE SOFTWARE. #
27
+ # #
28
+ # See LICENCES for more details. #
29
+ # #
30
+ # SPDX-FileCopyrightText: Copyright 2005-2025 #
31
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
32
+ # - Christophe GONZALES(_at_AMU) #
33
+ # SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
34
+ # #
35
+ # Contact : info_at_agrum_dot_org #
36
+ # homepage : http://agrum.gitlab.io #
37
+ # gitlab : https://gitlab.com/agrumery/agrum #
38
+ # #
39
+ ############################################################################
40
+
41
+ import pyagrum.lib._colors as gumcols
42
+ import matplotlib.pyplot as plt
43
+ import pydot as dot
44
+
45
+
46
+ def _buildMB(model, x: int, k: int = 1):
47
+ """
48
+ Build the nodes and arcs of Markov Blanket (of order k) of node x
49
+
50
+ Parameters
51
+ ----------
52
+ model: pyagrum.DirectedGraphicalModel
53
+ i.e. a class with methods parents, children, variable(i), idFromName(name)
54
+ x : int
55
+ the nodeId of the node for the Markov blanket
56
+ k: int
57
+ the order of the Markov blanket. If k=2, build the MarkovBlanket(MarkovBlanket())
58
+
59
+ Returns
60
+ -------
61
+ (nodes,arcs,depth) : the set of nodes, the set of arcs of the Markov Blanket and a dict[Str,int] that gives the MB-depth of each node in nodes.
62
+ """
63
+ nodes = {x}
64
+ arcs = set()
65
+ depth = dict()
66
+
67
+ def _internal_build_markov_blanket(bn, x: int, k: int):
68
+ nodes.add(x)
69
+ depth[x] = k
70
+ if k == 0:
71
+ return
72
+ for y in bn.parents(x):
73
+ visit(y, k - 1)
74
+ arcs.add((y, x))
75
+ for y in bn.children(x):
76
+ visit(y, k - 1)
77
+ arcs.add((x, y))
78
+ for z in bn.parents(y):
79
+ visit(z, k - 1)
80
+ arcs.add((z, y))
81
+
82
+ def visit(x, k):
83
+ if x in nodes and depth[x] >= k:
84
+ return
85
+ _internal_build_markov_blanket(model, x, k)
86
+
87
+ _internal_build_markov_blanket(model, x, k)
88
+ return nodes, arcs, depth
89
+
90
+
91
+ def generalizedMarkovBlanket(bn, var: int | str, k: int = 1, cmapNode=None):
92
+ """
93
+ Build a pydot.Dot representation of the nested Markov Blankets (of order k) of node x
94
+
95
+ Warnings
96
+ --------
97
+ It is assumed that k<=8. If not, every thing is fine except that the colorscale will change in order to accept more colors.
98
+
99
+ Parameters
100
+ ----------
101
+ bn: pyagrum.DirectedGraphicalModel
102
+ i.e. a class with methods parents, children, variable(i), idFromName(name)
103
+ var : str|int
104
+ the name or nodeId of the node for the Markov blanket
105
+ k: int
106
+ the order of the Markov blanket. If k=1, build the MarkovBlanket(MarkovBlanket())
107
+ cmap: maplotlib.ColorMap
108
+ the colormap used (if not, inferno is used)
109
+
110
+ Returns
111
+ -------
112
+ pydotplus.Dot object
113
+ """
114
+ if cmapNode is None:
115
+ cmapNode = plt.get_cmap("inferno") # gum.config["notebook", "default_arc_cmap"])
116
+
117
+ maxcols = max(
118
+ 8, k
119
+ ) # It is assumed that k<=8. If not, every thing is fine except that the colorscale will change in order to accept more colors.
120
+
121
+ mb = dot.Dot(f"MB({var},{k}", graph_type="digraph", bgcolor="transparent")
122
+
123
+ if isinstance(var, str):
124
+ nx = bn.idFromName(var)
125
+ else:
126
+ nx = var
127
+ nodes, arcs, visited = _buildMB(bn, nx, k)
128
+ names = dict()
129
+
130
+ for n in nodes:
131
+ protected_name = f'"{bn.variable(n).name()}"'
132
+ pnode = dot.Node(protected_name, style="filled")
133
+ if n == var:
134
+ bgcol = "#99FF99"
135
+ fgcol = "black"
136
+ else:
137
+ bgcol = gumcols.proba2bgcolor(1 - (k - visited[n]) / maxcols, cmapNode)
138
+ fgcol = gumcols.proba2fgcolor(1 - (k - visited[n]) / maxcols, cmapNode)
139
+ pnode.set_fillcolor(bgcol)
140
+ pnode.set_fontcolor(fgcol)
141
+ mb.add_node(pnode)
142
+ names[n] = protected_name
143
+ for n in nodes:
144
+ for u in bn.parents(n).intersection(nodes):
145
+ edge = dot.Edge(names[u], names[n])
146
+ if (u, n) in arcs:
147
+ edge.set_color("black")
148
+ else:
149
+ edge.set_color("#DDDDDD")
150
+ mb.add_edge(edge)
151
+
152
+ return mb
@@ -0,0 +1,146 @@
1
+ ############################################################################
2
+ # This file is part of the aGrUM/pyAgrum library. #
3
+ # #
4
+ # Copyright (c) 2005-2025 by #
5
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
6
+ # - Christophe GONZALES(_at_AMU) #
7
+ # #
8
+ # The aGrUM/pyAgrum library is free software; you can redistribute it #
9
+ # and/or modify it under the terms of either : #
10
+ # #
11
+ # - the GNU Lesser General Public License as published by #
12
+ # the Free Software Foundation, either version 3 of the License, #
13
+ # or (at your option) any later version, #
14
+ # - the MIT license (MIT), #
15
+ # - or both in dual license, as here. #
16
+ # #
17
+ # (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
18
+ # #
19
+ # This aGrUM/pyAgrum library is distributed in the hope that it will be #
20
+ # useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
22
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
23
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
24
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
25
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
26
+ # OTHER DEALINGS IN THE SOFTWARE. #
27
+ # #
28
+ # See LICENCES for more details. #
29
+ # #
30
+ # SPDX-FileCopyrightText: Copyright 2005-2025 #
31
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
32
+ # - Christophe GONZALES(_at_AMU) #
33
+ # SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
34
+ # #
35
+ # Contact : info_at_agrum_dot_org #
36
+ # homepage : http://agrum.gitlab.io #
37
+ # gitlab : https://gitlab.com/agrumery/agrum #
38
+ # #
39
+ ############################################################################
40
+
41
+ import pyagrum as gum
42
+ import pylab
43
+ import matplotlib as mpl
44
+ import itertools
45
+
46
+
47
+ def _independenceListForPairs(bn, target=None):
48
+ """
49
+ returns a list of triples `(i,j,k)` for each non arc `(i,j)` such that `i` is independent of `j` given `k`.
50
+
51
+ Parameters
52
+ ----------
53
+ bn: gum.BayesNet
54
+ the Bayesian Network
55
+
56
+ target: (optional) str or int
57
+ the name or id of the target variable. If a target is given, only the independence given a subset of the markov blanket of the target are tested.
58
+
59
+ Returns
60
+ -------
61
+ List[(str,str,List[str])]
62
+ A list of independence found in the structure of BN.
63
+ """
64
+
65
+ def powerset(iterable):
66
+ xs = list(iterable)
67
+ # note we return an iterator rather than a list
68
+ return itertools.chain.from_iterable(itertools.combinations(xs, n) for n in range(len(xs) + 1))
69
+
70
+ # testing every d-separation
71
+ l = []
72
+ nams = sorted(bn.names())
73
+ if target is None:
74
+ firstnams = nams.copy()
75
+ indepnodes = bn.names()
76
+ else:
77
+ indepnodes = {bn.variable(i).name() for i in gum.MarkovBlanket(bn, target).nodes()}
78
+ if isinstance(target, str):
79
+ firstnams = [target]
80
+ else:
81
+ firstnams = [bn.variable(target).name()]
82
+
83
+ for i in firstnams:
84
+ nams.remove(i)
85
+ for j in nams:
86
+ if not (bn.existsArc(i, j) or bn.existsArc(j, i)):
87
+ for k in powerset(sorted(indepnodes - {i, j})):
88
+ if bn.isIndependent(i, j, k):
89
+ l.append((i, j, tuple(k)))
90
+ break
91
+ return l
92
+
93
+
94
+ def independenceListForPairs(bn, filename, target=None, plot=True, alphabetic=False):
95
+ """
96
+ get the p-values of the chi2 test of a (as simple as possible) independence proposition for every non arc.
97
+
98
+ Parameters
99
+ ----------
100
+ bn : gum.BayesNet
101
+ the Bayesian network
102
+
103
+ filename : str
104
+ the name of the csv database
105
+
106
+ alphabetic : bool
107
+ if True, the list is alphabetically sorted else it is sorted by the p-value
108
+
109
+ target: (optional) str or int
110
+ the name or id of the target variable
111
+
112
+ plot : bool
113
+ if True, plot the result
114
+
115
+ Returns
116
+ -------
117
+ the list
118
+ """
119
+
120
+ learner = gum.BNLearner(filename, bn)
121
+ vals = {}
122
+ for indep in _independenceListForPairs(bn, target):
123
+ vals[indep] = learner.chi2(*indep)[1]
124
+
125
+ if plot:
126
+ plotvals = dict()
127
+ for indep in vals:
128
+ key = "$" + indep[0] + " \\perp " + indep[1]
129
+ if len(indep[2]) > 0:
130
+ key += " \\mid " + ",".join(indep[2])
131
+ key += "$"
132
+ plotvals[key] = vals[indep]
133
+
134
+ if not alphabetic:
135
+ sortedkeys = sorted(plotvals, key=plotvals.__getitem__, reverse=False)
136
+ else:
137
+ sortedkeys = list(plotvals.keys())
138
+
139
+ fig = pylab.figure(figsize=(10, 1 + 0.25 * len(plotvals)))
140
+ ax = fig.add_subplot(1, 1, 1)
141
+ ax.plot([plotvals[k] for k in sortedkeys], sortedkeys, "o")
142
+ ax.grid(True)
143
+ ax.vlines(x=0.05, ymin=-0.5, ymax=len(vals) - 0.5, colors="purple")
144
+ ax.add_patch(mpl.patches.Rectangle((0, -0.5), 0.05, len(vals), color="yellow"))
145
+
146
+ return vals
@@ -0,0 +1,264 @@
1
+ ############################################################################
2
+ # This file is part of the aGrUM/pyAgrum library. #
3
+ # #
4
+ # Copyright (c) 2005-2025 by #
5
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
6
+ # - Christophe GONZALES(_at_AMU) #
7
+ # #
8
+ # The aGrUM/pyAgrum library is free software; you can redistribute it #
9
+ # and/or modify it under the terms of either : #
10
+ # #
11
+ # - the GNU Lesser General Public License as published by #
12
+ # the Free Software Foundation, either version 3 of the License, #
13
+ # or (at your option) any later version, #
14
+ # - the MIT license (MIT), #
15
+ # - or both in dual license, as here. #
16
+ # #
17
+ # (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
18
+ # #
19
+ # This aGrUM/pyAgrum library is distributed in the hope that it will be #
20
+ # useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
22
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
23
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
24
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
25
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
26
+ # OTHER DEALINGS IN THE SOFTWARE. #
27
+ # #
28
+ # See LICENCES for more details. #
29
+ # #
30
+ # SPDX-FileCopyrightText: Copyright 2005-2025 #
31
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
32
+ # - Christophe GONZALES(_at_AMU) #
33
+ # SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
34
+ # #
35
+ # Contact : info_at_agrum_dot_org #
36
+ # homepage : http://agrum.gitlab.io #
37
+ # gitlab : https://gitlab.com/agrumery/agrum #
38
+ # #
39
+ ############################################################################
40
+
41
+ import pyagrum as gum
42
+ import pyagrum.lib._colors as gumcols
43
+ from pyagrum.lib.bn2graph import BN2dot
44
+
45
+ # Matplotlib
46
+ import matplotlib as mpl
47
+
48
+ # GL
49
+ import warnings
50
+
51
+ _cdict = {
52
+ "red": ((0.0, 0.1, 0.3), (1.0, 0.6, 1.0)),
53
+ "green": ((0.0, 0.0, 0.0), (1.0, 0.6, 0.8)),
54
+ "blue": ((0.0, 0.0, 0.0), (1.0, 1, 0.8)),
55
+ }
56
+ _INFOcmap = mpl.colors.LinearSegmentedColormap("my_colormap", _cdict, 256)
57
+
58
+
59
+ def _normalizeVals(vals, hilightExtrema=False):
60
+ """
61
+ normalisation if vals is not a proba (max>1)
62
+ """
63
+ ma = float(max(vals.values()))
64
+ mi = float(min(vals.values()))
65
+ if ma == mi:
66
+ return None
67
+
68
+ if not hilightExtrema:
69
+ vmi = 0.01
70
+ vma = 0.99
71
+ else:
72
+ vmi = 0
73
+ vma = 1
74
+
75
+ res = {name: vmi + (val - mi) * (vma - vmi) / (ma - mi) for name, val in vals.items()}
76
+ return res
77
+
78
+
79
+ def getInformationGraph(bn, evs=None, size=None, cmap=_INFOcmap, withMinMax=False):
80
+ """
81
+ Create a dot representation of the information graph for this BN
82
+
83
+ Parameters
84
+ ----------
85
+ bn: gum.BayesNet
86
+ the BN
87
+ evs : Dict[str,str|int|List[float]]
88
+ map of evidence
89
+ size: str|int
90
+ size of the graph
91
+ cmap: matplotlib.colors.Colormap
92
+ color map
93
+ withMinMax: bool
94
+ min and max in the return values ?
95
+
96
+ Returns
97
+ -------
98
+ dot.Dot | Tuple[dot.Dot,float,float,float,float]
99
+ graph as a dot representation and if asked, min_information_value, max_information_value, min_mutual_information_value, max_mutual_information_value
100
+ """
101
+ if size is None:
102
+ size = gum.config["notebook", "default_graph_size"]
103
+
104
+ if evs is None:
105
+ evs = {}
106
+
107
+ ie = gum.LazyPropagation(bn)
108
+ ie.setEvidence(evs)
109
+ ie.makeInference()
110
+
111
+ idEvs = ie.hardEvidenceNodes() | ie.softEvidenceNodes()
112
+
113
+ nodevals = dict()
114
+ for n in bn.nodes():
115
+ if n not in idEvs:
116
+ v = ie.H(n)
117
+ if v != v: # is NaN
118
+ warnings.warn(f"For {bn.variable(n).name()}, entropy is NaN.")
119
+ v = 0
120
+ nodevals[bn.variable(n).name()] = v
121
+
122
+ arcvals = dict()
123
+ for x, y in bn.arcs():
124
+ v = ie.jointMutualInformation({x, y})
125
+ if v != v: # is NaN
126
+ warnings.warn(f"For {bn.variable(x).name()}->{bn.variable(y).name()}, mutual information is Nan.")
127
+ v = 0
128
+ arcvals[(x, y)] = v
129
+
130
+ gr = BN2dot(
131
+ bn,
132
+ size,
133
+ nodeColor=_normalizeVals(nodevals, hilightExtrema=False),
134
+ arcWidth=arcvals,
135
+ cmapNode=cmap,
136
+ cmapArc=cmap,
137
+ showMsg=nodevals,
138
+ )
139
+
140
+ if withMinMax:
141
+ mi_node = min(nodevals.values())
142
+ ma_node = max(nodevals.values())
143
+ mi_arc = min(arcvals.values())
144
+ ma_arc = max(arcvals.values())
145
+ return gr, mi_node, ma_node, mi_arc, ma_arc
146
+ else:
147
+ return gr
148
+
149
+
150
+ def _reprInformation(bn, evs=None, size=None, cmap=_INFOcmap, asString=False):
151
+ """
152
+ repr a bn annotated with results from inference : Information and mutual information
153
+
154
+ Parameters
155
+ ----------
156
+ bn: pyagrum.BayesNet
157
+ the model
158
+ evs: Dict[str|int,str|int|List[float]]
159
+ the observations
160
+ size: int|str
161
+ size of the rendered graph
162
+ cmap: matplotlib.colours.Colormap
163
+ the cmap
164
+ asString: bool
165
+ returns the string or display the HTML
166
+
167
+ Returns
168
+ -------
169
+ str|None
170
+ return the HTML string or directly display it.
171
+ """
172
+ import IPython.display
173
+ import IPython.core.pylabtools
174
+ from base64 import encodebytes
175
+ from matplotlib.backends.backend_agg import FigureCanvasAgg as fc
176
+
177
+ if size is None:
178
+ size = gum.config["notebook", "default_graph_size"]
179
+
180
+ if evs is None:
181
+ evs = {}
182
+
183
+ gr, mi, ma, _, _ = getInformationGraph(bn, evs, size, cmap, withMinMax=True)
184
+ gumcols.prepareDot(gr, size=size)
185
+
186
+ # dynamic member makes pylink unhappy
187
+ # pylint: disable=no-member
188
+ gsvg = IPython.display.SVG(gr.create_svg(encoding="utf-8"))
189
+ width = (
190
+ int(gsvg.data.split("width=")[1].split('"')[1].split("pt")[0]) / mpl.pyplot.rcParams["figure.dpi"]
191
+ ) # pixel in inches
192
+ if width < 5:
193
+ width = 5
194
+
195
+ fig = mpl.figure.Figure(figsize=(width, 1))
196
+ fig.patch.set_alpha(0)
197
+ canvas = fc(fig)
198
+ ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
199
+ norm = mpl.colors.Normalize(vmin=mi, vmax=ma)
200
+ cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, orientation="horizontal")
201
+ cb1.set_label("Entropy")
202
+ cb1.ax.text(mi, -2, f"{mi:.4f}", ha="left", va="top", color=gumcols.proba2bgcolor(0.01, cmap))
203
+ cb1.ax.text(ma, -2, f"{ma:.4f}", ha="right", va="top", color=gumcols.proba2bgcolor(0.99, cmap))
204
+ png = IPython.core.pylabtools.print_figure(canvas.figure, "png") # from IPython.core.pylabtools
205
+ png_legend = f"<img style='vertical-align:middle' src='data:image/png;base64,{encodebytes(png).decode('ascii')}'>"
206
+
207
+ sss = f"<div align='center'>{gsvg.data}<br/>{png_legend}</div>"
208
+
209
+ if asString:
210
+ return sss
211
+
212
+ return IPython.display.display(IPython.display.HTML(sss))
213
+
214
+
215
+ def getInformation(bn, evs=None, size=None, cmap=_INFOcmap) -> str:
216
+ """
217
+ get a HTML string for a bn annotated with results from inference : entropy and mutual information
218
+
219
+ Parameters
220
+ ----------
221
+ bn: pyagrum.BayesNet
222
+ the model
223
+ evs: Dict[str|int,str|int|List[float]]
224
+ the observations
225
+ size: int|str
226
+ size of the rendered graph
227
+ cmap: matplotlib.colours.Colormap
228
+ the cmap
229
+
230
+ Returns
231
+ -------
232
+ str
233
+ return the HTML string
234
+ """
235
+ if size is None:
236
+ size = gum.config["notebook", "default_graph_size"]
237
+
238
+ if evs is None:
239
+ evs = {}
240
+
241
+ return _reprInformation(bn, evs, size, cmap, asString=True)
242
+
243
+
244
+ def showInformation(bn, evs=None, size=None, cmap=_INFOcmap):
245
+ """
246
+ diplay a bn annotated with results from inference : entropy and mutual information
247
+
248
+ Parameters
249
+ ----------
250
+ bn: pyagrum.BayesNet
251
+ the model
252
+ evs: Dict[str|int,str|int|List[float]]
253
+ the observations
254
+ size: int|str
255
+ size of the rendered graph
256
+ cmap: matplotlib.colours.Colormap
257
+ the cmap
258
+ """
259
+ if evs is None:
260
+ evs = {}
261
+
262
+ if size is None:
263
+ size = gum.config["notebook", "default_graph_size"]
264
+ return _reprInformation(bn, evs, size, cmap, asString=False)
@@ -0,0 +1,54 @@
1
+ ############################################################################
2
+ # This file is part of the aGrUM/pyAgrum library. #
3
+ # #
4
+ # Copyright (c) 2005-2025 by #
5
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
6
+ # - Christophe GONZALES(_at_AMU) #
7
+ # #
8
+ # The aGrUM/pyAgrum library is free software; you can redistribute it #
9
+ # and/or modify it under the terms of either : #
10
+ # #
11
+ # - the GNU Lesser General Public License as published by #
12
+ # the Free Software Foundation, either version 3 of the License, #
13
+ # or (at your option) any later version, #
14
+ # - the MIT license (MIT), #
15
+ # - or both in dual license, as here. #
16
+ # #
17
+ # (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
18
+ # #
19
+ # This aGrUM/pyAgrum library is distributed in the hope that it will be #
20
+ # useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
21
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
22
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
23
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
24
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
25
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
26
+ # OTHER DEALINGS IN THE SOFTWARE. #
27
+ # #
28
+ # See LICENCES for more details. #
29
+ # #
30
+ # SPDX-FileCopyrightText: Copyright 2005-2025 #
31
+ # - Pierre-Henri WUILLEMIN(_at_LIP6) #
32
+ # - Christophe GONZALES(_at_AMU) #
33
+ # SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
34
+ # #
35
+ # Contact : info_at_agrum_dot_org #
36
+ # homepage : http://agrum.gitlab.io #
37
+ # gitlab : https://gitlab.com/agrumery/agrum #
38
+ # #
39
+ ############################################################################
40
+
41
+ __author__ = "Pierre-Henri Wuillemin"
42
+ __copyright__ = "(c) 2019-2025 PARIS"
43
+
44
+ from ._bar import bar
45
+ from ._beeswarm import beeswarm
46
+ from ._waterfall import waterfall
47
+ from ._showShapValues import showShapValues
48
+
49
+ __all__ = [
50
+ "bar",
51
+ "beeswarm",
52
+ "waterfall",
53
+ "showShapValues",
54
+ ]