Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Glyph symbol ids create corrupted labels in Jupyter notebook #222

Closed
dpdoughe opened this issue May 17, 2019 · 10 comments
Closed

Glyph symbol ids create corrupted labels in Jupyter notebook #222

dpdoughe opened this issue May 17, 2019 · 10 comments

Comments

@dpdoughe
Copy link

Make sure that these boxes are checked before submitting your issue -- thank you!

  • [ X] This issue is for the Python interface of igraph.
  • [ X] This issue is a bug report or a feature request, not a support question.

The following code cells from a Jupyter notebook reproduce a bug. The second image will have garbled text labels. Inspecting the DOM I can see what the issue is. Igraph’s SVG uses xlinks to defined glyphs for its vertex labels. The glyphs are always labeled sequentially in the same way e.g. glyph0-1, glyph0-2, in any image it creates. So the browser is bound by web standards to cache the first instance of the symbols for hrefs . Thus when the second image references hrefs by the same name the corruption occurs.

Cell #1

g1=igraph.Graph.Barabasi(3)
g1.vs["name"] = ['foo','bar','goo']
visual_style = {}
visual_style["vertex_label"] = g1.vs["name"]
visual_style["vertex_label_dist"]=1.5
visual_style["vertex_label_size"]=50
visual_style["margin"]=70
igraph.plot(g1, **visual_style)

#Cell #2
g2=igraph.Graph.Barabasi(3)
g2.vs["name"] = ['fooly','barly','gooly'] # Note these are different names….
visual_style = {}
visual_style["vertex_label"] = g2.vs["name"]
visual_style["vertex_label_dist"]=1.5
visual_style["vertex_label_size"]=50
visual_style["margin"]=70
igraph.plot(g2, **visual_style)

@dpdoughe
Copy link
Author

Capture

@dpdoughe
Copy link
Author

Capture of the DOM showing the glyph labels that lead to corruption.

Capture2

@ntamas
Copy link
Member

ntamas commented May 17, 2019

Could jupyter/notebook#333 be related to this?

@dpdoughe
Copy link
Author

Possibly related to this iPython issue as well:
ipython/ipython#1866 (comment)

@dpdoughe
Copy link
Author

It does seem like a more general solution would be for igraph to use uuid's for all of its ids instead of the serial glyph ids.

@ntamas
Copy link
Member

ntamas commented May 18, 2019

Unfortunately there's not much we can do about it on our side; SVG drawing is done by sending drawing instructions to the Cairo library, which in turn produces an SVG for us. igraph itself does not even know whether it's drawing on the screen, into an SVG file, a PDF file or a PNG file. ID generation is entirely up to Cairo. Switching Cairo to something else would be a bigger task.

@ntamas
Copy link
Member

ntamas commented May 18, 2019

One thing that we can attempt (but it's admittedly a hack) is that we parse the generated SVG in _repr_svg_() before passing it back to Jupyter, and replace the IDs there. Not sure how hard the parsing would be.

@dpdoughe
Copy link
Author

Perhaps such functionality would be worthy of its own Python project (err "obfuscate_svg"??) or something. Which would solve this problem in general. One can imagine this even happening in any web app (not Jupyter per se) so might be nice to provide functionality to protect the SVG by obfuscating their symbol ids using UUID or some such approach. I guess there may be cases (e.g. site-specific CSS styling etc) where one does not want this "on". So having some code to selectively obfuscate an image/diagram's symbol ids would be nice.

It looked to me that igraph returns an instance of its own Plot class to Jupyter though. Where does the _repr_svg() get called?

@ntamas
Copy link
Member

ntamas commented May 21, 2019

_repr_svg_ is called by IPython or Jupyter (not sure which). Basically, you type in an expression that returns some value. IPython / Jupyter then looks for the presence of some special methods (such as _repr_svg_() and _repr_png_()) to see whether it can provide an alternative representation of the object instead of just calling repr() on it.

Wrapping the SVG in an iframe could be a simpler solution than re-writing the IDs. The iframe would create an ID-space of its own for the SVG representation. However, the weird thing is that it seems that this has been proposed and added to IPython a long time ago (see this PR). I don't have time to trace it down further, but I guess that there should be some way to give a hint to IPython that it should use an iframe around the SVG.

@vtraag
Copy link
Member

vtraag commented Aug 24, 2019

Closed, see discussion in #243.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants