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

CarioPlot with vertex labels has plots interact within a Jupyter Notebook in VSCode #638

Open
8uurg opened this issue Feb 5, 2023 · 17 comments
Labels
plotting Issues related to plotting graphs in igraph in general stale

Comments

@8uurg
Copy link

8uurg commented Feb 5, 2023

Describe the bug
CarioPlot with vertex labels has plots interact within a Jupyter Notebook in VSCode. For example, the labels on the second plot are messed up (should state "hi!" instead of a 0 and what looks like a 1 & 2 merged together) - if I clear the cell above, removing the plot, the second plot fixes itself:
Screenshot
(Sidenote, it seems to mess up on Gist as well. I have not been able to reproduce the issue in jupyter lab.)

Possibly related to #623.

To reproduce
See the following gist.

https://gist.github.com/8uurg/9b443d1e1d790349e6ca09ef81cccb7a

Version information

igraph==0.10.4
@ntamas
Copy link
Member

ntamas commented Feb 5, 2023

I think it's related to #145 and #243, both of which are related to the fact that Cairo-generated SVG files do not use unique IDs for the text nodes; well, the IDs are unique within one figure, but if you embed two Cairo-generated SVG files in the same DOM tree, the IDs would clash. A workaround was implemented in #148 where we instructed Jupyter to isolate each SVG file in an iframe to prevent the IDs from affecting each other. The question is whether VSCode respects this or not; probably not, and this is also the reason why you cannot reproduce it in Jupyter Lab.

Is there a way to check the DOM in VS Code and confirm that the two figures are not placed in separate iframe tags?

@8uurg
Copy link
Author

8uurg commented Feb 5, 2023

I've used the developer tools, and it seems like they are simply being embedded using svg tags only, no iframes. So that would explain it - vscode does not isolate svg's in notebooks, I'll send an issue their way. Thanks for the information.

@ntamas
Copy link
Member

ntamas commented Feb 7, 2023

Yes, that's most likely the reason, but it's good to know that our workaround does not work for VS Code. Given the growing popularity of VS Code's embedded Jupyter notebook, I'll keep this issue open in case we come up with a suitable workaround.

One possibility is to manually replace the glyph IDs in the generated SVG snippet with simple search-and-replace (similarly to how it's done here in a Julia library), but I'm a bit worried that we accidentally replace something that is not a glyph ID, or that the whole solution breaks if Cairo suddenly starts to use some other format for glyph IDs.

@iosonofabio
Copy link
Member

iosonofabio commented Feb 7, 2023

@8uurg are you aware that igraph supports matplotlib and plotly now? Would that be an option for you?

Edit: typo

@8uurg
Copy link
Author

8uurg commented Feb 11, 2023

@iosonofabio I have switched to matplotlib for visualizations in the notebook as a workaround, which I can confirm works just fine. :)

@iosonofabio
Copy link
Member

Fantastic. We're debating switching on matplotlib as the default plotting backend, this would be a +1 I guess

@alex180500
Copy link

alex180500 commented May 7, 2023

I'm getting the same problem but with edge_label with the cairo backend in vscode jupyter notebooks.

@iosonofabio
Copy link
Member

Have you tried the matplotlib backed? Esp. the current main version from GitHub has that logic strenghtened

@alex180500
Copy link

Yeah matplotlib works (release 0.10.4). The only issue I have is that the figsize setting doesn't work properly (it always forces a square figure size for some reason?).
Also the output in matplotlib is a bit blurry unless forcing the dpi of the figure to a higher amount. But that forces a bigger output? It's a bit of a weird behaviour... (it would be nice if it just followed the bbox value).

@iosonofabio
Copy link
Member

Great to hear. Matplotlib itself has many backends including vector graphics ones, so if you choose one of those (e g. Qt) it will have infinite resolution.

The aspect ratio of the axes can also be set easily, just Google matplotlib set aspect.

@alex180500
Copy link

Yeah I know but this is not the case when you use matplotlib inline (which is the default in jupyter notebooks). This results in a blurrier image than Cairo.

Axes.set_aspect() is not what I'm looking for... When I set the figure size and the dpi I expect the plot to occupy all that space.

Cairo correct behaviour: I set the bbox and the network is correctly sized inside the bbox.
image

Weird behaviour with matplotlib, the set_aspect makes the vertices ovals, also the edge labels dont work (but I think this is an already known issue).
image

@iosonofabio
Copy link
Member

even when using inline, you can specify matplotlib's dpi resolution at the beginning of the notebook AFAIK. As for the aspect ratio, fair enough. let me look into it

@iosonofabio iosonofabio added the plotting Issues related to plotting graphs in igraph in general label May 7, 2023
@iosonofabio
Copy link
Member

@alex180500 could you please share a minimal example so I can run it on my machine?

@alex180500
Copy link

alex180500 commented May 7, 2023

Trying to separate the jupyter blocks here!

import igraph as ig
import matplotlib.pyplot as plt

g = ig.Graph.Lattice([4, 4], circular=False)
g.es["label"] = [edge.tuple for edge in g.es]
g.es["label_size"] = 8
g.vs["label"] = g.vs.indices
g.vs["label_size"] = 8
# cairo
ig.plot(g, layout="grid", vertex_size=15, bbox=(500, 250))

image

# matplotlib
fig, ax = plt.subplots(figsize=(8, 8), dpi=100)
ig.plot(g, target=ax, layout="grid", vertex_size=0.2)
ax.set_aspect(0.5)

image

It would be nice that in the end matplotlib could output the same as Cairo by using an argument like bbox or something similar. There should be an "easy" way to have the same output as Cairo.

@iosonofabio
Copy link
Member

iosonofabio commented May 7, 2023

Thanks!

Agreed, this could be improved. Matplotlib is quite a little more complex than the way we use Cairo, because of its interactive nature, so bboxing is not that easy. But I'm testing options right now, will keep you posted.

edit: perhaps useful https://stackoverflow.com/questions/11995148/plot-circle-on-unequal-axes-with-pyplot

@iosonofabio
Copy link
Member

@alex180500 I opened #665 to discuss this issue specifically, so let's stop that discussion here (theoretically, this issue is about labels, not stretchy circles) and continue over there. If Thomas Caswell from matplotlib intervenes that'd be useful, in any case let's hear from a few more devs what they think and plan ahead.

@stale
Copy link

stale bot commented Sep 18, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
plotting Issues related to plotting graphs in igraph in general stale
Projects
None yet
Development

No branches or pull requests

4 participants