-
Notifications
You must be signed in to change notification settings - Fork 542
Description
Describe the bug
First of all, thanks a lot for this fantastic toolbox! I just found out about the possibility to generate dotfiles and visualize the structure of a robot. I tried this notebook from the official GitHub: https://github.com/petercorke/robotics-toolbox-python/blob/master/notebooks/branched-robot.ipynb. However, displaying the generated SVG file fails unfortunately.
It happens here:
from IPython.core.display import SVG
robot.dotfile('planar_y.dot')
!dot -Tsvg planar_y.dot -x > planar_y.svg
display(SVG(filename='planar_y.svg'))I'm not very familiar with XML in python, but claude.ai says: The roboticstoolbox appears to be monkey-patching or overriding XML writing functionality, but it's using an outdated call signature for _write_data(). In newer versions of Python's minidom, _write_data() expects three arguments, but the code is only providing two.
An alternative way to display the SVG works:
from IPython.display import display, HTML
with open('planar_y.svg', 'r') as f:
svg_content = f.read()
display(HTML(svg_content))So it's not a big deal at all, I just wanted to document it here, maybe someone is facing it as well.
Version information
I installed the toolbox using pip.
Python version: 3.13.7
rbt version: 1.1.1
numpy version: 1.26.4
To Reproduce
Steps to reproduce the behavior:
Create a new venv:
python -m venv .venv
. .venv/Scripts/activate
pip install numpy==1.26.4 roboticstoolbox-python- The shortest, complete, Python script that exhibits the bug.
In JupyterLab or VS Code, create a new notebook with this code:
import roboticstoolbox as rtb
from IPython.core.display import SVG
robot = rtb.models.ETS.Planar_Y()
robot.dotfile('planar_y.dot')
!dot -Tsvg planar_y.dot -x > planar_y.svg
SVG(filename='planar_y.svg')- The script output, including error messages.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[1], line 7
5 robot.dotfile('planar_y.dot')
6 get_ipython().system('dot -Tsvg planar_y.dot -x > planar_y.svg')
----> 7 SVG(filename='planar_y.svg')
File c:\Data\rbt_bugreport\.venv\Lib\site-packages\IPython\core\display.py:343, in DisplayObject.__init__(self, data, url, filename, metadata)
340 elif self.metadata is None:
341 self.metadata = {}
--> 343 self.reload()
344 self._check_data()
File c:\Data\rbt_bugreport\.venv\Lib\site-packages\IPython\core\display.py:370, in DisplayObject.reload(self)
368 encoding = None if "b" in self._read_flags else "utf-8"
369 with open(self.filename, self._read_flags, encoding=encoding) as f:
--> 370 self.data = f.read()
371 elif self.url is not None:
372 # Deferred import
373 from urllib.request import urlopen
File c:\Data\rbt_bugreport\.venv\Lib\site-packages\IPython\core\display.py:511, in SVG.data(self, svg)
509 found_svg = x.getElementsByTagName('svg')
510 if found_svg:
--> 511 svg = found_svg[0].toxml()
512 else:
513 # fallback on the input, trust the user
514 # but this is probably an error.
515 pass
File ~\scoop\apps\python\current\Lib\xml\dom\minidom.py:47, in Node.toxml(self, encoding, standalone)
46 def toxml(self, encoding=None, standalone=None):
---> 47 return self.toprettyxml("", "", encoding, standalone)
File ~\scoop\apps\python\current\Lib\xml\dom\minidom.py:62, in Node.toprettyxml(self, indent, newl, encoding, standalone)
60 self.writexml(writer, "", indent, newl, encoding, standalone)
61 else:
---> 62 self.writexml(writer, "", indent, newl)
63 if encoding is None:
64 return writer.getvalue()
File c:\Data\rbt_bugreport\.venv\Lib\site-packages\roboticstoolbox\tools\xacro\xmlutils.py:124, in fixed_writexml(self, writer, indent, addindent, newl)
122 for a_name in a_names:
123 writer.write(" %s=\"" % a_name)
--> 124 xml.dom.minidom._write_data(writer, attrs[a_name].value)
125 writer.write("\"")
126 if self.childNodes:
TypeError: _write_data() missing 1 required positional argument: 'attr'
Expected behavior
The SVG should be displayed in the notebook. The is nothing wrong with the SVG file itself, you can verify it using this alternative displaying method:
from IPython.display import display, HTML
with open('planar_y.svg', 'r') as f:
svg_content = f.read()
display(HTML(svg_content))Environment (please complete the following information):
- Windows 11
- Python 3.13.7
Additional context
Here is the full output of pip freeze:
ansitable==0.11.4
asttokens==3.0.0
cfgv==3.4.0
colorama==0.4.6
colored==2.3.1
comm==0.2.3
contourpy==1.3.3
cycler==0.12.1
debugpy==1.8.17
decorator==5.2.1
distlib==0.4.0
executing==2.2.1
filelock==3.20.0
fonttools==4.60.1
identify==2.6.15
ipykernel==7.1.0
ipython==9.7.0
ipython_pygments_lexers==1.1.1
jedi==0.19.2
jupyter_client==8.6.3
jupyter_core==5.9.1
kiwisolver==1.4.9
matplotlib==3.10.7
matplotlib-inline==0.2.1
nest-asyncio==1.6.0
nodeenv==1.9.1
numpy==1.26.4
packaging==25.0
parso==0.8.5
pgraph-python==0.6.3
pillow==12.0.0
platformdirs==4.5.0
pre_commit==4.4.0
progress==1.6.1
prompt_toolkit==3.0.52
psutil==7.1.3
pure_eval==0.2.3
Pygments==2.19.2
pyparsing==3.2.5
python-dateutil==2.9.0.post0
PyYAML==6.0.3
pyzmq==27.1.0
roboticstoolbox-python==1.1.1
rtb-data==1.0.1
scipy==1.16.3
six==1.17.0
spatialgeometry==1.1.0
spatialmath-python==1.1.15
stack-data==0.6.3
swift-sim==1.1.0
tornado==6.5.2
traitlets==5.14.3
typing_extensions==4.15.0
virtualenv==20.35.4
wcwidth==0.2.14
websockets==15.0.1