-
Notifications
You must be signed in to change notification settings - Fork 78
Grouped svg #570
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
Grouped svg #570
Conversation
|
Note that since the label and the symbol are now quite tightly linked, the mutation labels naturally default to being displayed in red text, matching the symbols. I left this in, as it seemed possibly a better viz idea anyway, but we can style them back if necessary. |
Codecov Report
@@ Coverage Diff @@
## master #570 +/- ##
==========================================
+ Coverage 87.30% 87.32% +0.02%
==========================================
Files 22 22
Lines 16733 16760 +27
Branches 3274 3279 +5
==========================================
+ Hits 14608 14636 +28
Misses 1040 1040
+ Partials 1085 1084 -1
Continue to review full report at Codecov.
|
|
Sorry, basic question: how do we get the |
Oh, sorry, this is in a jupyter notebook: But the exported svg file should be viewable in a browser like chrome, in which case, outside of Jupyter, simply do to get |
|
Even on a medium-sized TS (200 samples) this only increases the file size by a quarter or less, so I would say it's worth it. Not sure whether to add it to #555 though - thoughts @benjeffery ? |
|
Wow, this looks great. I haven't looked into the prevoius, non-hierarchical implementation, but... pooking around at the SVG, here's a suggestion: seems like the mutation labels should be in the same |
Yep, fair point. I was wary of increasing the number of groups any more than I had already, but, in for a penny, in for a pound, as they say here. That could also apply to the node + node label, I guess. In fact, it probably will mean slightly smaller files, as I won't need to duplicate the class names: I can just put them on the enclosing group. More likely than changing individual mutations, it seems likely that people might want to do something with all the mutation labels, or all the symbols, but the classes allow us to do that anyway. [edit - done with latest commit] |
|
More improvements just committed, which give much greater flexibility. Moreover, they result in a svg file size which is smaller (in bytes) than the current versions on master, because of using transformations on the groups, which leads to integer positioning. I have also extracted most of the hard-coded positioning hacks and placed them as css transformations, which can therefore be easily overridden. The following Jupyter notebook script demos a few examples: |
|
Looking good - haven't done a line by line yet, but glad this seems to be working well. I'm trying to think of use cases where this structure is worse than the previous, can you think of anything that is harder this way? As for PRs, as #555 is close to done I say don't combine them. |
I don't think it restricts anything but some stuff may be a little more complicated, mainly because of the way I've structured it. E.g. if you want to target a particular node but not its children you need to remember to use the "child only" selector, e.g.
Right. Howvever, if we are thinking of going in the direction of this PR, I wonder if I should remove the documentation about css classes from #555 @benjeffery , as it will be obsoleted by the changes here? |
Oh, another point is that I am now using styles to position the text relative to the node, rahter than hard-coding offsets. This opens up the problem that, if the SVG is embedded in an html document, the styles will apply over the entire document. We could anticipate this and assign each SVG a unique ID (if one wasn't provided by the user) and target all the styles to that ID, which would stop the styles "spilling out", as it were. Or we could just document that this is expected to happen given the SVG specs, and provide an example like the one above for people to follow if they expect to be embedding SVGs. |
|
Also 2 more ideas on which I'd quite like your opinion, @benjeffery (and possibly @jeromekelleher).
|
Not much point, just change them with this PR.
I haven't looked at the exact way you're doing the text positioning but could you assign a unique class name and qualify all the styles that way?
I like this, but I think we should nail down the customisation API first as otherwise we'll end up with loads of flags for options like this. This example would be easy to do with a callback to customise mutation label, and could be included as an example?
I like this, separate PR? (I know there are few piling up, but generally smaller and a few is better, although not sure I'm following my own advice here with metadata!) |
Yes, I could. The question is whether we want to do this invisibly to the user, or get them do do it explicitly. It seems a bit ugly taking their SVG styles and modifying them on the fly.
Also easy to do using the
OK. Will add it to this PR though, as it's integral to this one, I think. |
Ahh, I misunderstood you meant you as a user, rather than internal to tskit. |
Shouldn't the css be embedded in the SVG? Then (I'd think?) that it wouldnt affect other SVG in the same document? - https://www.w3.org/TR/SVG/styling.html#StyleElementExample |
Gee, that'd be nice, but I'll bet it gets too busy very quickly. If there's an easy way to say "please give alleles instead of mutation ID" that might be useful?
Nice idea. So, it'd be easy to color all samples with a particular mutation, for instance. But I suppose that's already pretty easy, by looking up the mutation's node. I'm leaning towards "overkill", but not for a good reason... |
It is embedded in the SVG, but I'm afraid your gut thought is wrong - stylesheets are always taken as applying to the entire document, even if embedded deep within an element. Or as https://www.w3.org/TR/SVG/styling.html#StyleSheetsInHTMLDocuments says, "any HTML ‘style’ element used in an SVG document must also apply its style sheet to the (entire) document". Also see multiple questions on Stack Overflow, e.g. see the end of the answer at https://stackoverflow.com/questions/20078032/inline-svg-embedded-css-interpreted-at-page-level |
The specific reason I wanted this is to target the fraction of the edge that lies below a particular mutation. E.g. for focal mutation 5, I would like a picture like the one below: Not the one that we previously would have been stuck with: A minor different, but an improvement, I think. The change is coded up in 9f19cdd. It means that the styles defined at the top of this issue will need changing, however. I'll post equivalents below, although I think the class labels might need a bit or work to make styling easier (I should chat about this with @benjeffery ) |
Hah, thanks for explaining. I should have googled some more. It does seem pretty unfortunate to have one tree's svg affecting other ones: that'll cause all sorts of bad things happen when including more than one tree on a page, no? You could add a random id at the top level and modify the css to make the properties only apply to this SVG? |
|
I don't think rewriting the CSS is trivial. I'd prefer a note to the user in the docs that they should qualify their CSS if needed. |
| :type mutation_labels: dict(int, str) | ||
| :param dict root_svg_attributes: Additional attributes, such as an id, that will | ||
| be embedded in the root ``<svg>`` tag of the generated drawing. | ||
| :param str style: A |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should say here that this stuff applies to the entire doc it's in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put this as a Note in #555:
..note::
A feature of SVG style commands is that they apply not just to the contents
within the <svg> container, but to the entire file. Thus if an SVG file is
embedded in a larger document, such as an HTML file (e.g. when an SVG
is displayed inline in a Jupyter notebook), the style will apply to all SVG
drawings in the notebook. To avoid this, you can tag the SVG with a unique
SVG using ``root_svg_attributes={'id':'MY_UID'}``, and prepend this to the
style string, as in ``#MY_UID .tree .edges {stroke: gray}``.
Damn, that's really nice. I say go for it. |
|
So: how would we add a Sorry I'm a bit slow on all this, hope I'm not making too much noise. |
I guess by
Right: for the styles we create ourselves, we can add the ID. But unless we have a
The problem here is that we then need to somehow return the ID we autogenerated, so that the user can use it. Which seems a bit messy to me. Why not just let them define it themselves? |
Thanks @petrelharp . The one issue here is that @jeromekelleher mentioned he'd prefer to split this into smaller incremental PRs (e.g. (1) one for nesting nodes, and a further one (2) for nesting mutations as well as nodes). I'm happy to do this, but not so happy to document the first behaviour, when it will then be obsoleted by the second. I suspect the way you would use css to target a node in (1) vs (2) would be quite different, so documenting (1) would end up being a waste of time if we are going to go with (2) in the long term. Not sure what I should do, other that perhaps remove the documentation for the time being, until we decide on a scheme? |
|
Right, I agree with what you're saying, @hyanwong. I think we should be able to, in the future, do things like add a
My proposal lets them define it themselves if they want to use it, but does not require that they do so. Something like: edit: To be clear, we don't need to return the ID, since if anyone wants to use it they can specify it. |
This is good in general, but if splitting it would make much extra work, then it's not the right thing to do... |
|
I'm confused about why targeting mutations make targeting nodes obsolete - surely we'd want to do both? We might want to style subtrees when there are no mutations present. My suggestion is that we focus on nodes in the this PR and then follow up with another PR for mutations. There's too much going on at once otherwise. |
The way to deal with this is to have a uid class we apply and use if we need to do stuff like this. Leave the ID to be selected and used by the user. |
|
Done. I will move the mutation grouping stuff to another PR. |
cb6422e to
17210ea
Compare
|
@benjeffery if you are in SVG mode from checking #555 you might want to check this too. It's ready for review, I reckon, although an intermediate step on the way to the full mutation grouping idea, which I haven't submitted yet (just working through edge cases at the root) |
benjeffery
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple little things and a thought about numerical precision.
|
As background got merged this is now rebased to master so only the new changes are visible. I had to force push, so you'll need to |
|
By the way, when importing these SVGs into Inkscape (and presumably other SVG editors) the nested groupings become a pain. Fortunately Inkscape has a "deep ungroup" function which does recursive ungrouping, but it's in the "extra-plugins" menu, not next to "group" and "ungroup". Something to mention in a graphics vignette perhaps, but to specific for the general docs |
|
@hyanwong, @jeromekelleher I'm now happy with this PR, we have a follow up hot on its heels to add some additional testing and the mutation-hierarchy-level feature. |
|
Looks great! Can we get a few simple unit tests for Happy to merge after that. |
|
Looks like mergify isn't merging because codecov hasn't reported on the PR. Probably simplest to just merge manually. This is quite a bit behind the tip of master, so needs a rebase. |
|
I'll rebase now |
…tree Places everything using transformations, not absolute coords This is much more flexible for transformations, and allows us to get rid of the extra text positioning group.
|
Codecov status last night stated they had degraded service. |
|
Merged! Thanks @hyanwong and @benjeffery, this is a huge step forward for viz! |



This implements the idea by @benjeffery of grouping SVG components using the tree hierarchy, which should allow subtrees to be styled and even moved using SVG. It is a continuation of #555, and it could be argued that it should be rolled into that, as it will require the documentation proposed in #555 to be changed.
To see how it might work, try the following example:
The implementation means that we have to abandon the idea of putting edges, symbols, & text in different groups. Instead we ensure that text & symbols are above edges within each group by putting edges as the first group item. This seems to work OK: for instance