Open gazzar opened 4 years ago
The easiest way to control the ordering of the images is to use separate "figures", rather than axes within one figure. Each figure is rendered to a separate layer, which you can then order as you like in Inkscape. After running your code to populate the template with the layers, and reordering the layers, you can subsequently use that svg as your template and the order of the layers will remain the way you set it, so you only need to relayer once. Or if you create the layers with figurefirst the order you want them then they should be set. But if you have a lot of these that you're trying to do, that could be cumbersome.
Within a figure, the axes are, I'm pretty sure, layered according to the order of their dictionary keys (line 1047 in svg_to_axes.py). That means it should, in principle, be possible for you to determine the order they appear in by prescribing the order of the keys. The easiest way to do this would be to add functionality to make_mplfigures so you can optionally tell it the order of the axes you would like. To make this robust might be a challenge. A harder thing to do would be to have the key order match the layer order in inkscape (harder because it would require digging deeper into the xml parsing code). The first option is something I can probably implement over the next few days, as I've run into wanting that functionality as well..
On Thu, May 21, 2020 at 5:48 AM Gary Ruben notifications@github.com wrote:
I'm trying to use fifi to layout images. It's common to inset images, colourbars etc. within other images or build figures where images overlay other images. This should be possible if there is a way to control the ordering of rectangles within a template layer, or render into separate template layers but I can't work out if this is possible. In fact the output from fifi seems nondeterministic, rendering some plot elements above or below others regardless of the ordering of the template rectangles, and ordered differently when rerunning the identical script+template.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/FlyRanch/figurefirst/issues/53, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB4EPAUIL2JRL2QCS2JEW3RSUPK7ANCNFSM4NGZ6TCA .
-- Floris van Breugel | http://www.florisvanbreugel.com Assistant Professor of Mechanical Engineering & Graduate Program for Neuroscience Palmer 226, University of Nevada, Reno
Wildlife and Landscape Photography Galleries: http://www.ArtInNaturePhotography.com/ http://www.artinnaturephotography.com/ Blog: http://www.ArtInNaturePhotography.com/wordpress/ http://www.artinnaturephotography.com/wordpress/
Turned out to be pretty easy to implement the ability to specify the order of the axes. I didn't verify that it works in every possible scenario, but give it a try:
This code would ensure that axis 'a' ends up on top of axis 'b'. Any other axes will end up below 'b' in their "natural" order: layout = fifi.svg_to_axes.FigureLayout('fifi_axis_order.svg', autogenlayers=True, make_mplfigures=False, hide_layers=[]) layout.make_mplfigures(hide=False, axes_order={'fig': ['a', 'b']})
While not as intuitive as following the order of the rectangles in the svg itself, it gives you more control on the programmatic end..
On Thu, May 21, 2020 at 1:12 PM Floris van Breugel fvanbreugel@unr.edu wrote:
The easiest way to control the ordering of the images is to use separate "figures", rather than axes within one figure. Each figure is rendered to a separate layer, which you can then order as you like in Inkscape. After running your code to populate the template with the layers, and reordering the layers, you can subsequently use that svg as your template and the order of the layers will remain the way you set it, so you only need to relayer once. Or if you create the layers with figurefirst the order you want them then they should be set. But if you have a lot of these that you're trying to do, that could be cumbersome.
Within a figure, the axes are, I'm pretty sure, layered according to the order of their dictionary keys (line 1047 in svg_to_axes.py). That means it should, in principle, be possible for you to determine the order they appear in by prescribing the order of the keys. The easiest way to do this would be to add functionality to make_mplfigures so you can optionally tell it the order of the axes you would like. To make this robust might be a challenge. A harder thing to do would be to have the key order match the layer order in inkscape (harder because it would require digging deeper into the xml parsing code). The first option is something I can probably implement over the next few days, as I've run into wanting that functionality as well..
- Floris
On Thu, May 21, 2020 at 5:48 AM Gary Ruben notifications@github.com wrote:
I'm trying to use fifi to layout images. It's common to inset images, colourbars etc. within other images or build figures where images overlay other images. This should be possible if there is a way to control the ordering of rectangles within a template layer, or render into separate template layers but I can't work out if this is possible. In fact the output from fifi seems nondeterministic, rendering some plot elements above or below others regardless of the ordering of the template rectangles, and ordered differently when rerunning the identical script+template.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/FlyRanch/figurefirst/issues/53, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB4EPAUIL2JRL2QCS2JEW3RSUPK7ANCNFSM4NGZ6TCA .
-- Floris van Breugel | http://www.florisvanbreugel.com Assistant Professor of Mechanical Engineering & Graduate Program for Neuroscience Palmer 226, University of Nevada, Reno
Wildlife and Landscape Photography Galleries: http://www.ArtInNaturePhotography.com/ http://www.artinnaturephotography.com/ Blog: http://www.ArtInNaturePhotography.com/wordpress/ http://www.artinnaturephotography.com/wordpress/
-- Floris van Breugel | http://www.florisvanbreugel.com Assistant Professor of Mechanical Engineering & Graduate Program for Neuroscience Palmer 226, University of Nevada, Reno
Wildlife and Landscape Photography Galleries: http://www.ArtInNaturePhotography.com/ http://www.artinnaturephotography.com/ Blog: http://www.ArtInNaturePhotography.com/wordpress/ http://www.artinnaturephotography.com/wordpress/
Thanks for looking at this so quickly Floris! I pip installed your modified version directly from github, verified that I have the version with your changes, and made the changes to the layout and make_mplfigures in my script but I actually don't see any change in behaviour. However, I suspected maybe the nondeterministic behaviour was something to do with the dictionary key ordering changes made in Python 3.6 since you have been mentioning key ordering. I observe the nondeterministic behaviour in my Python 3.5 conda environment. I can't remember why I decided to use 3.5; probably because the figurefirst readme says python 3.5+. Now I've created a Python 3.8 environment and the nondeterminism has gone. However, the axes_order dict is not being respected for me and it seems to simply use the rectangle object ordering in Inkscape. I reverted to the original vanilla layout and make_mplfigures calls: layout = FigureLayout(str(TEMPLATE)) layout.make_mplfigures() and the behaviour is the same. To be honest, this is what I had hoped the default behaviour would be originally. For now, specifying the order in the template makes more sense for what I am doing, although I understand it would be nice to have control over that from the other side. I guess the take-home is you may need to use an OrderedDict if you want to maintain backward compatibility for Python 3.5, but I personally don't think it's worth bothering.
I'm happy to send you my figure or try things out on my system if you want to get to the bottom of why the axes_order isn't being respected for me.
Interesting. I can't honestly say I understand what is going on. I'm on python 3.5.
Would you be willing to share your template svg, or a stripped down version of it, since I'm curious to see what's going on? (you can send directly to florisvb@gmail.com)
Glad to hear your use case is at least working. In my experience the default has usually been to order the axes in the order they were created, but I wonder if in python 3.8 it is actually going in the layer order?
On Thu, May 21, 2020 at 6:55 PM Gary Ruben notifications@github.com wrote:
Thanks for looking at this so quickly Floris! I pip installed your modified version directly from github, verified that I have the version with your changes, and made the changes to the layout and make_mplfigures in my script but I actually don't see any change in behaviour. However, I suspected maybe the nondeterministic behaviour was something to do with the dictionary key ordering changes made in Python 3.6 since you have been mentioning key ordering. I observe the nondeterministic behaviour in my Python 3.5 conda environment. I can't remember why I decided to use 3.5; probably because the figurefirst readme says python 3.5+. Now I've created a Python 3.8 environment and the nondeterminism has gone. However, the axes_order dict is not being respected for me and it seems to simply use the rectangle object ordering in Inkscape. I reverted to the original vanilla layout and make_mplfigures calls: layout = FigureLayout(str(TEMPLATE)) layout.make_mplfigures() and the behaviour is the same. To be honest, this is what I had hoped the default behaviour would be originally. For now, specifying the order in the template makes more sense for what I am doing, although I understand it would be nice to have control over that from the other side. I guess the take-home is you may need to use an OrderedDict if you want to maintain backward compatibility for Python 3.5, but I personally don't think it's worth bothering.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/FlyRanch/figurefirst/issues/53#issuecomment-632434991, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB4EPAH6QORGUVPXKU7GU3RSXLPVANCNFSM4NGZ6TCA .
-- Floris van Breugel | http://www.florisvanbreugel.com Assistant Professor of Mechanical Engineering & Graduate Program for Neuroscience University of Nevada, Reno
Wildlife and Landscape Photography Galleries: http://www.ArtInNaturePhotography.com/ Blog: http://www.ArtInNaturePhotography.com/wordpress/
Although it's not stated in the lifecycle PEP, Django claims 3.5 is going EOL in September, so I would personally not be too upset if it had to fall by the wayside a little early. Alternatively we could throw in a shim like
import sys
if sys.version_info < (3, 6):
from collections import OrderedDict as dict
I'm trying to use fifi to layout images. It's common to inset images, colourbars etc. within other images or build figures where images overlay other images. This should be possible if there is a way to control the ordering of rectangles within a template layer, or render into separate template layers but I can't work out if this is possible. In fact the output from fifi seems nondeterministic, rendering some plot elements above or below others regardless of the ordering of the template rectangles, and ordered differently when rerunning the identical script+template.