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

Specification of options for multiple Paths #995

Closed
mrksr opened this issue Nov 30, 2016 · 3 comments
Closed

Specification of options for multiple Paths #995

mrksr opened this issue Nov 30, 2016 · 3 comments
Milestone

Comments

@mrksr
Copy link
Contributor

mrksr commented Nov 30, 2016

Since there is currently no propagation of options for plots (see #638), I quite often find myself specifying the same plotting options for one specific element, say a Curve, and all elements which might wrap this element, such as Overlay or Layout. This results in quite some repetition when done using the %opts-magic:

%opts Curve [width=900, height=500] Overlay [width=900, height=500] NdOverlay [width=900, height=500]

Ideally, I would like to be able to specify multiple paths at once for which the following styles should be applied, like so:

%opts Curve Overlay NdOverlay [width=900, height=500]

This, I think, is legal right now, it just has different semantics: The options are only applied to NdOverlay, while for both Curve and Overlay this is a no-op. Since I do not expect the specification of no-ops to be of any use, it should not be too bad to change it.

I would be happy to get my feet wet with holoviews and implement this myself. If you can point me into the right direction, I will get started.

@jlstevens
Copy link
Contributor

jlstevens commented Nov 30, 2016

Thanks for filing this issue!

This feature is one I have considered before and would be happy to support. The place I would implement this is here in the OptsSpec parser. Here is a little demo of how it works currently:

from holoviews.ipython.parser import OptsSpec
OptsSpec.parse('Image [width=100] (s=3) Curve [width=100] (s=3)')
{'Curve': {'plot': Options(width=100), 'style': Options(s=3)},
 'Image': {'plot': Options(width=100), 'style': Options(s=3)}}

What we need for this feature to work:

from holoviews.ipython.parser import OptsSpec
OptsSpec.parse('Image Curve [width=100] (s=3)')
{'Curve': {'plot': Options(width=100), 'style': Options(s=3)},
 'Image': {'plot': Options(width=100), 'style': Options(s=3)}}

Currently the return value is this:

{'Curve': {'plot': Options(width=100), 'style': Options(s=3)}, 'Image': {}}

You shouldn't need to worry about the pyparsing stuff in that file and can probably just copy the dictionaries as appropriate at the end of the parse method (if you detect empty dictionaries).

One worry is about the semantics as I think this is a bit of a special case:

  1. This copying semantics should only apply to plot options.
  2. I guess supplying style options 'interrupts' this copying behavior so if you want to copy plot options but still specify style options you would need to do something like this:
%%opts Image Curve [width=100] Image (s=3)

(note that Image is specified once for the plot options then again just for the style options)

  1. Here is another example to consider:
%%opts Image Curve [width=100]  Spikes (lw=3)  Histogram RGB [height=200]

Here I would expect only width=100 shared between Image and Curve, Spikes would only have the lw=3 style option and then height=200 would be the only plot option for Histogram and RGB.

Anyway, hope that gets you started! I don't think it should be too hard to implement and would be a useful feature. The main reason I wouldn't want to accept this feature is if we find it breaks backwards compatibility somehow (I don't think it does).

Edit: As the output is a dictionary (unordered) and there are some ordering effects (e.g as shown in the last example above), you'll probably need to figure out how to group things while iterating over the groups in this loop:

for group in cls.opts_spec.parseString(line):
   ...

I would consider building a datastructure (e.g a list of tuples) in the loop to figure out which plot options need to be unioned. E.g in the last example this thing would be something like [('Image', 'Curve'), ('Histogram', 'RGB')] at the end of this loop. This would then specify what to do at the end of the parse method. Hope that makes sense!

@mrksr
Copy link
Contributor Author

mrksr commented Nov 30, 2016

As discussed on gitter, option grouping should work for all types of options, such that

%opts A B {x} [y] (z)

is strictly equivalent to

%opts A {x} [y] (z) B {x} [y] (z)

and also generalizes to more than two pathspecs.

Additionally, we noticed that option definitions are not properly merged right now:

hv.ipython.parser.OptsSpec.parse("Image (c='b') Image (s=3)")
{'Image': {'style': Options(s=3)}}

While we're at it, this should also be fixed to result in

{'Image': {'style': Options(c='b', s=3)}}

@philippjfr philippjfr added this to the v1.7.0 milestone Dec 7, 2016
@philippjfr
Copy link
Member

I've added the issue to the milestone so we don't forget to mention it in our release notes. But since this is now implemented I'll close.

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

No branches or pull requests

3 participants