holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.69k stars 402 forks source link

Layouting a Curve next to an NdLayout fails #365

Open mrksr opened 8 years ago

mrksr commented 8 years ago

The following code creates a HoloMap containing four Curve objects. These Curves should be displayed next to a fifth Curve object using an Ndlayout.

ys = np.cumsum(np.random.normal(size=(5, 50)), axis=1)

hmap = hv.HoloMap({
            i: hv.Curve(ys[i, :])
            for i in range(4)
        })

hv.Curve(ys[4, :]) + hv.NdLayout(hmap).cols(2)

This gives the following TypeError when executed in a notebook with the notebook_extension enabled:

Traceback (most recent call last):
  File "(...)\holoviews\ipython\display_hooks.py", line 99, in wrapped
    max_branches = OutputMagic.options['max_branches'])
  File "(...)\holoviews\ipython\display_hooks.py", line 156, in layout_display
    return render(layout)
  File "(...)\holoviews\ipython\display_hooks.py", line 50, in render
    return Store.renderers[backend].html(obj, **kwargs)
  File "(...)\holoviews\plotting\renderer.py", line 211, in html
    plot, fmt =  self._validate(obj, fmt)
  File "(...)\holoviews\plotting\renderer.py", line 171, in _validate
    plot = self.get_plot(obj)
  File "(...)\holoviews\plotting\renderer.py", line 157, in get_plot
    plot = self_or_cls.plotting_class(obj)(obj, **plot_opts)
  File "(...)\holoviews\plotting\mpl\plot.py", line 712, in __init__
    self.subplots, self.subaxes, self.layout = self._compute_gridspec(layout)
  File "(...)\holoviews\plotting\mpl\plot.py", line 876, in _compute_gridspec
    num=0 if empty else layout_count)
  File "(...)\holoviews\plotting\mpl\plot.py", line 1014, in _create_subplots
    **plotopts)
  File "(...)\holoviews\plotting\mpl\plot.py", line 711, in __init__
    super(LayoutPlot, self).__init__(layout=layout, **params)
  File "(...)\holoviews\plotting\plot.py", line 815, in __init__
    **dict(plotopts, **params))
TypeError: __init__() got multiple values for keyword argument 'uniform'

I am using the most recent Anaconda3 python distribution with Python 3.5 and tired both v1.4.0 and the current master branch of holoviews.

philippjfr commented 8 years ago

Thanks @mrksr, I'll have a look at this today. Should be a straightforward fix.

philippjfr commented 8 years ago

Sorry @mrksr, I was wrong before. This is an actual restriction of our current layout system, but the error message is obviously confusing. Currently NdLayouts cannot be nested inside Layouts and vice versa. It should be possible to simply concatenate them all into a big layout, and I'll target that for a v1.5 release. Actually nesting Layouts to achieve more complex plot arrangements is also on our roadmap but probably won't happen in the near future.

Until either of those happen NdLayouts are restricted to displaying collections of Elements or Overlays, which are uniform in type and can't be used inside another Layout. For now I'll catch this a bit earlier and provide a better exception.

mrksr commented 8 years ago

I see. Is there a way to achieve these tree-like arrangements of plots through other means? By this I mean to have a plot which is the same size as a collection of other plots, something like this (in pseudo code):

bigplot + (smallplot + smallplot + smallplot + smallplot).cols(2)

Or is this what you mean by "nesting Layouts to achieve more complex plot arrangements"? If so then I'm looking forward to seeing that :). If I have some free time over the holidays I can also try working on this if it is not too hard.

jlstevens commented 8 years ago

For this purpose, we sometimes resort to abusing GridSpace to hold the smaller plots. It isn't quite the same as an NdLayout but it can be made to work. The real solution is the proposal to implement the nested Layout proposal though...

philippjfr commented 8 years ago

Or is this what you mean by "nesting Layouts to achieve more complex plot arrangements"? If so then I'm looking forward to seeing that :).

That is what I mean by more complex plot arrangements yes, currently everything is forced into a regular grid with the only exception being that GridSpaces may be nested in a Layout. You can see some of our previous discussion on the topic here: https://github.com/ioam/holoviews/issues/91.

If I have some free time over the holidays I can also try working on this if it is not too hard.

The Layout code is some of the hairiest code in all of HoloViews so I wouldn't want to inflict that on you. I think with the release of matplotlib 2.0 we'll start work on a major refactor of our matplotlib backend, which may also be a good opportunity to redesign the layout system.

mrksr commented 8 years ago

Thanks for the tip, @jlstevens! I thought about doing this, but I was not quite sure as to how to get the two columns in the Grid Space. In the example above, there is only one key dimension (the "number" of the plot). Is there a way of "spreading" this over two dimensions?

Thank you for the insight, @philippjfr. :)