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

Interactive fixes #630

Merged
merged 2 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions examples/homepage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,7 @@
"\n",
"| | |\n",
"| --- | --- |\n",
"| Build Status | [![Build Status](https://github.com/holoviz/hvplot/workflows/tests/badge.svg)](https://github.com/holoviz/hvplot/actions?query=workflow%3Atests) |\n",
"| Coverage | [![Coverage Status](https://coveralls.io/repos/github/holoviz/hvplot/badge.svg?branch=master)](https://coveralls.io/github/holoviz/hvplot?branch=master) |\n",
"| Latest dev release | [![Github tag](https://img.shields.io/github/tag/holoviz/hvplot.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/hvplot/tags) |\n",
"| Latest release | [![Github release](https://img.shields.io/github/release/holoviz/hvplot.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/hvplot/releases) [![PyPI version](https://img.shields.io/pypi/v/hvplot.svg?colorB=cc77dd)](https://pypi.python.org/pypi/hvplot) [![hvplot version](https://img.shields.io/conda/v/pyviz/hvplot.svg?colorB=4488ff&style=flat)](https://anaconda.org/pyviz/hvplot) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/hvplot.svg?label=conda%7Cconda-forge&colorB=4488ff)](https://anaconda.org/conda-forge/hvplot) [![defaults version](https://img.shields.io/conda/v/anaconda/hvplot.svg?label=conda%7Cdefaults&style=flat&colorB=4488ff)](https://anaconda.org/anaconda/hvplot) |\n",
"| Docs | [![gh-pages](https://img.shields.io/github/last-commit/holoviz/hvplot/gh-pages.svg)](https://github.com/holoviz/hvplot/tree/gh-pages) [![site](https://img.shields.io/website-up-down-green-red/http/hvplot.holoviz.org.svg)](http://hvplot.holoviz.org) |\n",
"\n",
"hvPlot works with [Python 2.7 and Python 3](https://travis-ci.org/pyviz/hvplot) on Linux, Windows, or Mac. The recommended way to install hvPlot is using the [conda](http://conda.pydata.org/docs/) command provided by [Anaconda](http://docs.continuum.io/anaconda/install) or [Miniconda](http://conda.pydata.org/miniconda.html):\n",
"\n",
Expand Down
47 changes: 36 additions & 11 deletions hvplot/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from panel.layout import Column, Row, VSpacer, HSpacer
from panel.widgets.base import Widget

from .util import is_tabular, is_xarray, is_xarray_dataarray


def _find_widgets(op):
widgets = []
Expand Down Expand Up @@ -51,14 +53,19 @@ class Interactive():
def __init__(self, obj, transform=None, plot=False, depth=0,
loc='top_left', center=False, dmap=False, inherit_kwargs={},
**kwargs):
self._init = False
self._obj = obj
self._method = None
if transform is None:
import xarray as xr
if isinstance(obj, xr.DataArray):
self._transform = hv.dim(obj.name)
else:
self._transform = hv.dim('*')
dim = '*'
transform = hv.util.transform.dim
if is_xarray(obj):
transform = hv.util.transform.xr_dim
if is_xarray_dataarray(obj):
dim = obj.name
elif is_tabular(obj):
transform = hv.util.transform.pd_dim
self._transform = transform(dim)
else:
self._transform = transform
self._plot = plot
Expand All @@ -70,6 +77,7 @@ def __init__(self, obj, transform=None, plot=False, depth=0,
self._kwargs = kwargs
ds = hv.Dataset(self._obj)
self._current = self._transform.apply(ds, keep_index=True, compute=False)
self._init = True

@property
def _params(self):
Expand Down Expand Up @@ -106,10 +114,23 @@ def __dir__(self):
current = self._current
if self._method:
current = getattr(current, self._method)
return [d for d in dir(current) if d[0] != '_']

def __getattr__(self, name):
if name in dir(self):
extras = {attr for attr in dir(current) if not attr.startswith('_')}
try:
return sorted(set(super(Interactive, self).__dir__()) | extras)
except Exception:
return sorted(set(dir(type(self))) | set(self.__dict__) | extras)

def __getattribute__(self, name):
self_dict = super(Interactive, self).__getattribute__('__dict__')
if not self_dict.get('_init'):
return super(Interactive, self).__getattribute__(name)

current = self_dict['_current']
method = self_dict['_method']
if method:
current = getattr(current, method)
extras = [d for d in dir(current) if not d.startswith('_')]
if name in extras and name not in super(Interactive, self).__dir__():
if self._method:
transform = hv.dim(self._transform, self._method, accessor=True)
inherit_kwargs = {}
Expand All @@ -124,7 +145,7 @@ def __getattr__(self, name):
except Exception:
pass
return new
raise AttributeError(name)
return super(Interactive, self).__getattribute__(name)

@staticmethod
def _get_ax_fn():
Expand All @@ -147,7 +168,9 @@ def __call__(self, *args, **kwargs):
method = type(self._transform)(self._transform, self._method,
accessor=True)
kwargs = dict(self._inherit_kwargs, **kwargs)
return self._clone(method(*args, **kwargs), plot=self._method == 'plot')
clone = self._clone(method(*args, **kwargs), plot=self._method == 'plot')
self._method = None
return clone

#----------------------------------------------------------------
# Interactive pipeline APIs
Expand Down Expand Up @@ -302,6 +325,8 @@ def __rtruediv__(self, other):
return self._clone(transform)

def __getitem__(self, other):
if self._method:
self._method = None
other = other._transform if isinstance(other, Interactive) else other
transform = type(self._transform)(self._transform, operator.getitem, other)
return self._clone(transform)
Expand Down