Tutorial 3, line 43 fails (development branch)
Describe the bug As described in the title, a flowviz-based Ig_strat.export_gate_hierarchy_image('gs.png') instruction in line 43 of the tutorial fails.
This is cleaner replacement of issue #244, I have closed #244. Unlike with issue #244, I'm am running the tutorial straight from the the built-in notebook .ipynb files in visual studio code. The actual error message differs somewhat from issue #244, so there may be additional info in that issue. In issue #244 there was a permission denied error.
Since the previous report, I independently tested flowviz, and I got appropriate renders of other unrelated dot files from within both Notepad++ and visual studio code. If it matters, I put flowviz in my user path and not the system path.
All the previous tutorial code (methods) for displaying the gating hierarchy worked fine.
Code To Reproduce
Code to reproduce the behavior:
import flowkit as fk
...
# tutorial 3 notebook line 43
g_strat.export_gate_hierarchy_image('gs.png')
...
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
Cell In[43], [line 1](vscode-notebook-cell:?execution_count=43&line=1)
----> [1](vscode-notebook-cell:?execution_count=43&line=1) g_strat.export_gate_hierarchy_image('gs.png')
File d:\VSCode_Projects\FlowKit\.venv\Lib\site-packages\flowkit\_models\gating_strategy.py:663, in GatingStrategy.export_gate_hierarchy_image(self, output_file_path)
645 def export_gate_hierarchy_image(self, output_file_path):
646 """
647 Saves an image of the gate hierarchy in many common formats
648 according to the extension given in `output_file_path`, including
(...) 661 :return: None
662 """
--> [663](file:///D:/VSCode_Projects/FlowKit/.venv/Lib/site-packages/flowkit/_models/gating_strategy.py:663) DotExporter(self._gate_tree).to_picture(output_file_path)
File d:\VSCode_Projects\FlowKit\.venv\Lib\site-packages\anytree\exporter\dotexporter.py:297, in DotExporter.to_picture(self, filename)
295 dotfile.flush()
296 cmd = ["dot", dotfilename, "-T", fileformat, "-o", filename]
--> [297](file:///D:/VSCode_Projects/FlowKit/.venv/Lib/site-packages/anytree/exporter/dotexporter.py:297) check_call(cmd)
298 try:
299 remove(dotfilename)
File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\subprocess.py:413, in check_call(*popenargs, **kwargs)
411 if cmd is None:
412 cmd = popenargs[0]
--> [413](file:///C:/Program%20Files/WindowsApps/PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0/Lib/subprocess.py:413) raise CalledProcessError(retcode, cmd)
414 return 0
CalledProcessError: Command '['dot', 'C:\\Users\\rbaer\\AppData\\Local\\Temp\\tmpdyl3xutk', '-T', 'png', '-o', 'gs.png']' returned non-zero exit status 2.
Expected behavior I thought this would produce an image file andd save it.
Other things I tried I tried using an explicit path that user has access to --> fail I tried a different image format (.svg) --> fail
Desktop (please complete the following information):
- OS: [Windows 11]
- Python version [3.12.10]
- FlowKit version [1.3.0b0]
Additional context
PATH (.venv) D:\VSCode_Projects\FlowKit>path PATH=d:\VSCode_Projects\FlowKit.venv\Scripts;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.9\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.9\libnvvp;C:\Program Files\Microsoft\jdk-11.0.22.7-hotspot\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files\dotnet;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Microsoft SQL Server\150\Tools\Binn;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files (x86)\QuickTime\QTSystem;C:\Program Files\SlikSvn\bin;C:\Program Files\NVIDIA Corporation\NVIDIA app\NvDLISR;C:\Program Files\Git\cmd;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit;C:\Program Files\NVIDIA Corporation\Nsight Compute 2025.2.0;C:\Program Files\PowerShell\7;C:\Program Files\Docker\Docker\resources\bin;C:\Users\rbaer\AppData\Local\Microsoft\WindowsApps;C:\Users\rbaer\AppData\Roaming\Python\Python310\Scripts;C:\Users\rbaer\AppData\Local\Microsoft\WinGet\Links;C:\Program Files (x86)\Nmap;C:\Users\rbaer.dotnet\tools;C:\Users\rbaer\AppData\Roaming\Python\Python312\Scripts;C:\Users\rbaer\AppData\Local\Programs\Microsoft VS Code\bin; C:\ProgramFiles\Graphviz\bin; C:\Users\rbaer\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\Scripts;
(.venv) D:\VSCode_Projects\FlowKit>pip list Package Version Editable project location
anytree 2.13.0 asttokens 3.0.0 bokeh 3.7.2 colorama 0.4.6 comm 0.2.2 contourpy 1.3.2 debugpy 1.8.14 decorator 5.2.1 executing 2.2.0 FlowIO 1.4.0b0 D:\VSCode_Projects\FlowIO FlowKit 1.3.0b0 FlowUtils 1.2.0b0 D:\VSCode_Projects\FlowUtils flowviz 0.0.1 ipykernel 6.29.5 ipython 9.3.0 ipython_pygments_lexers 1.1.1 jedi 0.19.2 Jinja2 3.1.6 jupyter_client 8.6.3 jupyter_core 5.8.1 lxml 5.3.2 MarkupSafe 3.0.2 matplotlib-inline 0.1.7 narwhals 1.35.0 nest-asyncio 1.6.0 networkx 3.4.2 numpy 2.2.5 packaging 25.0 pandas 2.2.3 parso 0.8.4 pillow 11.2.1 pip 25.1.1 platformdirs 4.3.8 prompt_toolkit 3.0.51 psutil 7.0.0 pure_eval 0.2.3 Pygments 2.19.1 python-dateutil 2.9.0.post0 pytz 2025.2 pywin32 310 PyYAML 6.0.2 pyzmq 27.0.0 scipy 1.15.2 six 1.17.0 stack-data 0.6.3 tornado 6.4.2 traitlets 5.14.3 tzdata 2025.2 wcwidth 0.2.13 xyzservices 2025.1.0
Windows 11 Visual studio code Version: 1.101.0 (user setup) Commit: dfaf44141ea9deb3b4096f7cd6d24e00c147a4b1 Date: 2025-06-11T15:00:50.123Z Electron: 35.5.1 ElectronBuildId: 11727614 Chromium: 134.0.6998.205 Node.js: 22.15.1 V8: 13.4.114.21-electron.0 OS: Windows_NT x64 10.0.27871
Hi Rob,
Not sure what the flowviz package is, did you mean to install graphviz? That package is needed for exporting the gate hierarchy as an image.
Sorry, I DID mean Graphviz 13.0.0 . Tested and working. Here's an example with the dot engine.
[ Misspeak - flowViz is an R package on Bioconductor, and I had sound-alike, brain-fart issues when I was typing]
Ok, that error indicates the Python environment is not finding the graphviz binaries. Make sure you also pip install graphviz (and install the graphviz Windows installer). Might need to restart your console/terminal as well.
I did a pip install graphviz to make sure. The installed graphviz version lists as 0.21 Before, I had only verified graphviz from the command terminal. Now I verified that graphviz works from within python.
This works from within a codeblock in the tutorial notebook
# Module from graphviz docs works
import graphviz
dot = graphviz.Digraph('round-table', comment='The Round Table')
print(dot)
dot.node('A', 'King Arthur')
dot.node('B', 'Sir Bedevere the Wise')
dot.node('L', 'Sir Lancelot the Brave')
dot.edges(['AB', 'AL'])
dot.edge('B', 'L', constraint='false')
print(dot.source)
dot.render(directory='doctest-output').replace('\\', '/') # ** A clue ?**
dot.render(directory='doctest-output', view=True)
Next, I checked to see if the text for creating the dot file was properly saved. It was saved to a file named C:\Users\rbaer\AppData\Local\Temp\tmp5_x2xvqz The structure of this file looks fine and renders properly in notepad++ so the flowkit problem would seem to +occur at the flowkit rendering step.
digraph tree {
"root";
"TimeGate";
"Singlets";
"aAmine-";
"CD3-pos";
"CD4-pos";
"CD8-pos";
"root" -> "TimeGate";
"TimeGate" -> "Singlets";
"Singlets" -> "aAmine-";
"aAmine-" -> "CD3-pos";
"CD3-pos" -> "CD4-pos";
"CD3-pos" -> "CD8-pos";
}
If you typically test on linux or macOS, one of the possible clues from the test code above is the handling of the backslashes in my Windows machine. Notice that in the working python code from the graphviz site that they replace the "escaped backslashes" with forward slashes. But maybe this is not what's happening here.
BTW on modern Windows forward slashes seem to always work properly in code paths and are much easier to work with than the archaic backslash. From a coding point of view it only makes sense to never use backslashes given its common use for escaping.
As a reminder, here is the current error readout. Note the escaped backslashes in the path. The path does not use an r'...' tag mentioned in the backslash literal section of the docuementation: https://graphviz.readthedocs.io/en/stable/manual.html Maybe this is not important.
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
Cell In[13], line 2
1 import graphviz
----> 2 g_strat.export_gate_hierarchy_image('gs.png')
File d:\VSCode_Projects\FlowKit\.venv\Lib\site-packages\flowkit\_models\gating_strategy.py:663, in GatingStrategy.export_gate_hierarchy_image(self, output_file_path)
645 def export_gate_hierarchy_image(self, output_file_path):
646 """
647 Saves an image of the gate hierarchy in many common formats
648 according to the extension given in `output_file_path`, including
(...) 661 :return: None
662 """
--> 663 DotExporter(self._gate_tree).to_picture(output_file_path)
File d:\VSCode_Projects\FlowKit\.venv\Lib\site-packages\anytree\exporter\dotexporter.py:297, in DotExporter.to_picture(self, filename)
295 dotfile.flush()
296 cmd = ["dot", dotfilename, "-T", fileformat, "-o", filename]
--> 297 check_call(cmd)
298 try:
299 remove(dotfilename)
File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.2800.0_x64__qbz5n2kfra8p0\Lib\subprocess.py:413, in check_call(*popenargs, **kwargs)
411 if cmd is None:
412 cmd = popenargs[0]
--> 413 raise CalledProcessError(retcode, cmd)
414 return 0
CalledProcessError: Command '['dot', 'C:\\Users\\rbaer\\AppData\\Local\\Temp\\tmpms1vri6l', '-T', 'png', '-o', 'gs.png']' returned non-zero exit status 2.
Looks like this may be a bug in the anytree library:
https://github.com/c0fec0de/anytree/issues/268
Another slightly weird thing I don't understand. If I do 'pip list' it says anytree is version 2.13.0, but if I **import anytree** and then do **print(anytree.__version__)** it tells me my version is 2.12.1. The latter is the version that is refereced as being defective in https://github.com/c0fec0de/anytree/issues/268 . My attempts to upgrade by unistalling and reinstalling haven't changed anything.
Is this a pip issue or something I'm doing wrong with my environment? Are we at the mercy of an anytree bump?
I've seen pip get confused before with either a cached package or multiple copies of the same version somehow installed. One thing to try is running pip uninstall anytree multiple times until it says it isn't installed. Then force an install of the specific version: pip install anytree=2.13.0. If the environment is still borked, I just obliterate it and create a new one.
I think we are at the mercy of an anytree update, and it's not the first time (recall the "." gate name problem in https://github.com/whitews/FlowKit/issues/255#issuecomment-2926017626).
Alternatively, we could try to roll our own tree graph image export code. Would make for a good PR if you wanted to have a go? It'd basically involve rewriting the innards of the GatingStrategy.export_gate_hierarchy_image() method in a new feature branch off of the develop branch.