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

SVG output should preserve vertex/edge attributes #608

Open
n8willis opened this issue Nov 7, 2022 · 10 comments
Open

SVG output should preserve vertex/edge attributes #608

n8willis opened this issue Nov 7, 2022 · 10 comments
Labels
wishlist Feature request that has not been chosen for implementation yet; vote or comment to prioritize it!

Comments

@n8willis
Copy link

n8willis commented Nov 7, 2022

What is the feature or improvement you would like to see?
Graphs can currently support arbitrary attributes on each vertex and edge. Furthermore, graphs written to some external file formats (such as GraphViz .dot) support attaching id and class and other SVG attributes. But iGraph's SVG writer drops these attributes.

Preserving attributes, primarily, class, in SVG output would allow users to export their network plots with metadata that allows interactive styling in browsers (or perhaps other applications). Just preserving the class and related attributes opens up the possibility of CSS and JavaScript manipulation of vertices and edges without requiring additional work within the iGraph library itself.

Use cases for the feature
One of the major benefits of SVG output is that it permits on-the-fly styling of network elements via CSS. Such as highlighting edges with a particular attribute in their class.

Notably, GraphViz already supports this, and GraphViz-exported SVGs can be controlled in-browser with styling tools. E.g., "bolding" the edges connecting some subset of vertices or changing the color of some vertex, just by using CSS rules and a .class selector

References
This is standard CSS; nothing out of the ordinary.

@szhorvat
Copy link
Member

szhorvat commented Nov 7, 2022

Which interface of igraph are you using? The core igraph C library does not have an SVG writer. High-level interfaces have differing and independent ways to produce graphics.

@n8willis
Copy link
Author

n8willis commented Nov 7, 2022

As in bindings? Almost always Python. I've tinkered with R stuff once in a while, but although I don't particularly think I could speak for the R community, I can't see why it would have different expectations. This is exclusively about what gets written into the .svg output file.

@szhorvat
Copy link
Member

szhorvat commented Nov 7, 2022

As I said, the plotting systems of high-level interfaces are entirely separate and unrelated, so this would need to be a separate request for each. I am transferring this to the python-igraph issue tracker.

@iosonofabio Is this feasible for python-igraph? Does matplotlib support metadata that gets preserved upon export to SVG? I know that in Mathematica this is not currently possible. While the graphics system supports annotations, Mathematica's own SVG exporter does not preserve those annotations.

@szhorvat szhorvat transferred this issue from igraph/igraph Nov 7, 2022
@ntamas
Copy link
Member

ntamas commented Nov 7, 2022

SVG is actually sort of a special case in the plotting subsystem. Both the Cairo backend and the Matplotlib backend can export figures in SVG format, but at that point all references to igraph itself are lost; you only have a generic "figure" that you can save into SVG.

However, igraph also has a write_svg() method on the Graph class; the implementation currently resides in src/igraph/io/images.py in _write_graph_to_svg(). I am somewhat in favour of allowing the user to specify class attributes for elements of the graph in the exported SVG somehow - but we cannot blindly add all attributes as the result would not be valid SVG according to the SVG specification; for instance, class is an allowed attribute on <path> tags, but some-arbitrary-attribute is not.

@ntamas ntamas added the wishlist Feature request that has not been chosen for implementation yet; vote or comment to prioritize it! label Nov 7, 2022
@n8willis
Copy link
Author

n8willis commented Nov 7, 2022

As I said, the plotting systems of high-level interfaces are entirely separate and unrelated, so this would need to be a separate request for each. I am transferring this to the python-igraph issue tracker.

Well, when I was writing my reply, it just said "what interface of igraph are you using". Certainly not objecting to the move; I merely don't want to be the one that the pitchfork-wielding Rillagers come after if the feature-sets drift apart....

Back to the main point, if I can clarify this:

specify class attributes for elements of the graph in the exported SVG somehow - but we cannot blindly add all attributes as the result would not be valid SVG according

(a) The class attribute is, by far, the one that matters the most. For the CSS/JS access mentioned. It's not hard, at least in Python, to convert "foo:x" attributes into "foo_x" class components when one needs to export an SVG.

(b) Secondarily, I would also say that other "valid SVG tags" ought to be preservable. Clearly id matters there, but there might be others; drawing a line somewhere I'm sure has to be done, but I'm not expert enough at on-the-fly CSS and in-browser SVG trickery to have a perspective there.

(c) Personally, I would make a case that the "other, random/arbitrary attributes" in a vs or es should get a look at being preservable through the SVG data-* attribute mechanism. It's certainly not widely-used (in SVG or in HTML, AFAICT), but this seems like a clear application of what it's supposedly for....

Like I said, class does essentially what I need it to, but just saying "everything else gets turned into a data-* and you're on your own at that point" sounds defensible to me. After all, the whole point of data-* is supposedly that you can put non-string values into it, and I can sure see how that would be useful to some people. There could be pathological cases, but IMO that could be handled by slapping big red Warning stickers on the API and reminding everyone that the W3C invented this mechanism. For example.

@iosonofabio
Copy link
Member

@n8willis as @ntamas mentioned, there are art least two ways to get svgs out of igraph, i.e. using matplotlib or via write_svg.

Which one are you trying/have you tried to use?

@n8willis
Copy link
Author

n8willis commented Nov 7, 2022

@n8willis as @ntamas mentioned, there are art least two ways to get svgs out of igraph, i.e. using matplotlib or via write_svg.

Which one are you trying/have you tried to use?

Neither method supports preserving attributes, @iosonofabio.

This is not something I'm "trying" and failing to use; it's behavior that is not currently supported. Hence the feature request.

@iosonofabio
Copy link
Member

Ok no immediate need, that's good to know.

I recommend you also ask matplotlib whether they can include custom attributes in their SVG, that'd be the preferred route AFAIAC.

@szhorvat
Copy link
Member

szhorvat commented Nov 8, 2022

Apparently there is some support for this in matplotlib: https://stackoverflow.com/a/46040257/695132

@iosonofabio
Copy link
Member

Great to hear! @n8willis why don't you look up or ask the mpl folks about class and once we have an answer we see how to best implement it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wishlist Feature request that has not been chosen for implementation yet; vote or comment to prioritize it!
Projects
None yet
Development

No branches or pull requests

4 participants