graphviz.Source(dot_graph) UnicodeDecodeError

Viewed 506

After exporting a .dot file using scikit-learn's export_graphviz function.

I am trying to render the dot file using Graphviz into a cell in my Jupyter Notebook:

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

dt_clf = DecisionTreeClassifier(random_state=156)
iris_data = load_iris()
X_train , X_test , y_train , y_test = train_test_split(iris_data.data, iris_data.target,test_size=0.2,  random_state=11)
dt_clf.fit(X_train , y_train)   
from sklearn.tree import export_graphviz

export_graphviz(dt_clf, out_file='tree.dot', class_names = iris_data.target_names, feature_names=iris_data.feature_names,impurity=True,filled=True) 
import graphviz
with open("tree.dot") as f:
   dot_graph = f.read()
graphviz.Source(dot_graph)   

Everything runs fine until the line "graphviz.Source(dot_graph)". Then I get this error.

UnicodeDecodeError                        Traceback (most recent call last)
~\anaconda3\envs\tf2\lib\site-packages\IPython\core\formatters.py in __call__(self, obj)
    343             method = get_real_method(obj, self.print_method)
    344             if method is not None:
--> 345                 return method()
    346             return None
    347         else:

~\anaconda3\envs\tf2\lib\site-packages\graphviz\files.py in _repr_svg_(self)
    111 
    112     def _repr_svg_(self):
--> 113         return self.pipe(format='svg').decode(self._encoding)
    114 
    115     def pipe(self, format=None, renderer=None, formatter=None, quiet=False):

~\anaconda3\envs\tf2\lib\site-packages\graphviz\files.py in pipe(self, format, renderer, formatter, quiet)
    136         out = backend.pipe(self._engine, format, data,
    137                            renderer=renderer, formatter=formatter,
--> 138                            quiet=quiet)
    139 
    140         return out

~\anaconda3\envs\tf2\lib\site-packages\graphviz\backend.py in pipe(engine, format, data, renderer, formatter, quiet)
    244     """
    245     cmd, _ = command(engine, format, None, renderer, formatter)
--> 246     out, _ = run(cmd, input=data, capture_output=True, check=True, quiet=quiet)
    247     return out
    248 

~\anaconda3\envs\tf2\lib\site-packages\graphviz\backend.py in run(cmd, input, capture_output, check, encoding, quiet, **kwargs)
    174 
    175     if not quiet and err:
--> 176         _compat.stderr_write_bytes(err, flush=True)
    177 
    178     if encoding is not None:

~\anaconda3\envs\tf2\lib\site-packages\graphviz\_compat.py in stderr_write_bytes(data, flush)
     60         """Encode data str and write to sys.stderr (flush if requested)."""
     61         encoding = sys.stderr.encoding or sys.getdefaultencoding()
---> 62         sys.stderr.write(data.decode(encoding))
     63         if flush:
     64             sys.stderr.flush()

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 20: invalid start byte

How can I fix it?

1 Answers

I can't see what your dot file looks like, so I don't know if your error has the same cause as mine, but I am able to reproduce the error by adding a font face to an HTML-style Node.

the following dot file:

digraph "Simple Plan" {
    graph [rankdir=RL];
    node [label="\N"];
    vv_PlanSetup    [label=<<TABLE>
        <TR><TD><FONT FACE="Times New Roman">Table 1</FONT></TD></TR>
        <TR><TD><FONT FACE="Arial">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    Course  [label=<<TABLE>
        <TR><TD><FONT FACE="Times New Roman">Table 2</FONT></TD></TR>
        <TR><TD><FONT FACE="Calibri">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    vv_PlanSetup -> Course;
}

works in the Graphviz Visual Editor [http://magjac.com/graphviz-visual-editor/], but fails when loaded with pygraphviz:

Gh = pgv.AGraph()
dot_data = '''
digraph "Simple Plan" {
    graph [rankdir=RL];
    node [label="\\N"];
    vv_PlanSetup    [label=<<TABLE>
        <TR><TD><FONT FACE="Times New Roman">Table 1</FONT></TD></TR>
        <TR><TD><FONT FACE="Arial">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    Course  [label=<<TABLE>
        <TR><TD><FONT FACE="Times New Roman">Table 2</FONT></TD></TR>
        <TR><TD><FONT FACE="Calibri">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    vv_PlanSetup -> Course;
}
'''
Gh.from_string(dot_data)
Gh.layout(prog="dot")
Gh.draw("simple_plan.png")

produces the following error:


UnicodeDecodeError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_11472/611521859.py in 16 ''' 17 Gh.from_string(dot_data) ---> 18 Gh.layout(prog="dot") 19 Gh.draw("simple_plan.png")

~.conda\envs\variandb_relations\lib\site-packages\pygraphviz\agraph.py in layout(self, prog, args) 1464 """ 1465 output_fmt = "dot" -> 1466 data = self._run_prog(prog, " ".join([args, "-T", output_fmt])) 1467 self.from_string(data) 1468 self.has_layout = True

~.conda\envs\variandb_relations\lib\site-packages\pygraphviz\agraph.py in _run_prog(self, prog, args) 1388 1389 if len(errors) > 0: -> 1390 warnings.warn(b"".join(errors).decode(self.encoding), RuntimeWarning) 1391 return b"".join(data) 1392

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 76: invalid start byte A cryptic error message to say the least.

Other font settings seem to work. For example:

Gh = pgv.AGraph()
dot_data = '''
digraph "Simple Plan" {
    graph [rankdir=RL];
    node [label="\\N"];
    vv_PlanSetup    [label=<<TABLE>
        <TR><TD><FONT COLOR="red" >Table 1</FONT></TD></TR>
        <TR><TD><FONT COLOR="black">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    Course  [label=<<TABLE>
        <TR><TD><FONT COLOR="red">Table 2</FONT></TD></TR>
        <TR><TD><FONT COLOR="black">Column 1</FONT></TD></TR>
        </TABLE>>, shape=plaintext];
    vv_PlanSetup -> Course;
}
'''
Gh.from_string(dot_data)
Gh.layout(prog="dot")
Gh.draw("simple_plan.png")

results in: These HTML table nodes

Related