Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6143565

Browse files
authored
Merge pull request #14725 from anntzer/graphviz_dump_transform
Move the debug-mode TransformNode.write_graphviz out.
2 parents bba7763 + 007ee07 commit 6143565

File tree

2 files changed

+64
-58
lines changed

2 files changed

+64
-58
lines changed

lib/matplotlib/_internal_utils.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Internal debugging utilities, that are not expected to be used in the rest of
3+
the codebase.
4+
5+
WARNING: Code in this module may change without prior notice!
6+
"""
7+
8+
from io import StringIO
9+
from pathlib import Path
10+
import subprocess
11+
12+
from matplotlib.transforms import TransformNode
13+
14+
15+
def graphviz_dump_transform(transform, dest, *, highlight=None):
16+
"""
17+
Generate a graphical representation of the transform tree for *transform*
18+
using the :program:`dot` program (which this function depends on). The
19+
output format (png, dot, etc.) is determined from the suffix of *dest*.
20+
21+
Parameters
22+
----------
23+
transform : `~matplotlib.transform.Transform`
24+
The represented transform.
25+
dest : str
26+
Output filename. The extension must be one of the formats supported
27+
by :program:`dot`, e.g. png, svg, dot, ...
28+
(see https://www.graphviz.org/doc/info/output.html).
29+
highlight : list of `~matplotlib.transform.Transform` or None
30+
The transforms in the tree to be drawn in bold.
31+
If *None*, *transform* is highlighted.
32+
"""
33+
34+
if highlight is None:
35+
highlight = [transform]
36+
seen = set()
37+
38+
def recurse(root, buf):
39+
if id(root) in seen:
40+
return
41+
seen.add(id(root))
42+
props = {}
43+
label = type(root).__name__
44+
if root._invalid:
45+
label = f'[{label}]'
46+
if root in highlight:
47+
props['style'] = 'bold'
48+
props['shape'] = 'box'
49+
props['label'] = '"%s"' % label
50+
props = ' '.join(map('{0[0]}={0[1]}'.format, props.items()))
51+
buf.write(f'{id(root)} [{props}];\n')
52+
for key, val in vars(root).items():
53+
if isinstance(val, TransformNode) and id(root) in val._parents:
54+
buf.write(f'"{id(root)}" -> "{id(val)}" '
55+
f'[label="{key}", fontsize=10];\n')
56+
recurse(val, buf)
57+
58+
buf = StringIO()
59+
buf.write('digraph G {\n')
60+
recurse(transform, buf)
61+
buf.write('}\n')
62+
subprocess.run(
63+
['dot', '-T', Path(dest).suffix[1:], '-o', dest],
64+
input=buf.getvalue().encode('utf-8'), check=True)

lib/matplotlib/transforms.py

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,6 @@ def set_children(self, *children):
200200
self, lambda _, pop=child._parents.pop, k=id(self): pop(k))
201201
child._parents[id(self)] = ref
202202

203-
if DEBUG:
204-
_set_children = set_children
205-
206-
def set_children(self, *children):
207-
self._set_children(*children)
208-
self._children = children
209-
set_children.__doc__ = _set_children.__doc__
210-
211203
def frozen(self):
212204
"""
213205
Returns a frozen copy of this transform node. The frozen copy
@@ -217,56 +209,6 @@ def frozen(self):
217209
"""
218210
return self
219211

220-
if DEBUG:
221-
def write_graphviz(self, fobj, highlight=[]):
222-
"""
223-
For debugging purposes.
224-
225-
Writes the transform tree rooted at 'self' to a graphviz "dot"
226-
format file. This file can be run through the "dot" utility
227-
to produce a graph of the transform tree.
228-
229-
Affine transforms are marked in blue. Bounding boxes are
230-
marked in yellow.
231-
232-
*fobj*: A Python file-like object
233-
234-
Once the "dot" file has been created, it can be turned into a
235-
png easily with::
236-
237-
$> dot -Tpng -o $OUTPUT_FILE $DOT_FILE
238-
239-
"""
240-
seen = set()
241-
242-
def recurse(root):
243-
if root in seen:
244-
return
245-
seen.add(root)
246-
props = {}
247-
label = root.__class__.__name__
248-
if root._invalid:
249-
label = '[%s]' % label
250-
if root in highlight:
251-
props['style'] = 'bold'
252-
props['shape'] = 'box'
253-
props['label'] = '"%s"' % label
254-
props = ' '.join(map('{0[0]}={0[1]}'.format, props.items()))
255-
256-
fobj.write('%s [%s];\n' % (hash(root), props))
257-
258-
if hasattr(root, '_children'):
259-
for child in root._children:
260-
name = next((key for key, val in root.__dict__.items()
261-
if val is child), '?')
262-
fobj.write('"%s" -> "%s" [label="%s", fontsize=10];\n'
263-
% (hash(root), hash(child), name))
264-
recurse(child)
265-
266-
fobj.write("digraph G {\n")
267-
recurse(self)
268-
fobj.write("}\n")
269-
270212

271213
class BboxBase(TransformNode):
272214
"""

0 commit comments

Comments
 (0)