Source code for vaex.jupyter

# -*- coding: utf-8 -*-
import os
import logging
import time
from .utils import debounced, flush, gather, kernel_tick, interactive_selection, interactive_cleanup  # noqa
import vaex
import IPython.display


base_path = os.path.dirname(__file__)
logger = logging.getLogger("vaex.jupyter")


def _add_toolbar(viz):
    from .widgets import ToolsToolbar, tools_items_default
    from traitlets import link
    interact_items = [k for k in tools_items_default if k['value'] in viz.TOOLS_SUPPORTED]
    toolbar = ToolsToolbar(supports_transforms=viz.supports_transforms,
                           supports_normalize=viz.supports_normalize,
                           interact_items=interact_items)
    viz.children = [toolbar, ] + viz.children
    link((viz, 'tool'), (toolbar, 'interact_value'))
    link((viz, 'transform'), (toolbar, 'transform_value'))
    link((viz, 'normalize'), (toolbar, 'normalize'))
    link((viz, 'selection_mode'), (toolbar, 'selection_mode'))
    return toolbar


[docs]class DataFrameAccessorWidget(object):
[docs] def __init__(self, df): self.df = df import vaex.jupyter.grid self.grid = vaex.jupyter.model.GridCalculator(df, []) self._last_grid = None
[docs] @debounced(delay_seconds=0.1, reentrant=False) async def execute_debounced(self): """Schedules an execution of dataframe tasks in the near future (debounced).""" try: logger.debug("Execute tasks... tasks=%r", self.df.executor.tasks) await self.df.execute_async() logger.debug("Execute tasks done") except vaex.execution.UserAbort: pass # this is fine except Exception: logger.exception("Error while executing tasks")
def clear(self): self.grid = vaex.jupyter.model.GridCalculator(self.df, [])
[docs] def data_array(self, axes=[], selection=None, shared=False, display_function=IPython.display.display, **kwargs): '''Create a :func:`vaex.jupyter.model.DataArray` model and :func:`vaex.jupyter.view.DataArray` widget and links them. This is a convenience method to create the model and view, and hook them up. ''' import vaex.jupyter.model import vaex.jupyter.view if selection is not None: selection = selection.copy() model = vaex.jupyter.model.DataArray(df=self.df, axes=axes, selection=selection, **kwargs) if shared: grid = self.grid else: grid = vaex.jupyter.model.GridCalculator(self.df, []) grid.model_add(model) view = vaex.jupyter.view.DataArray(model=model, display_function=display_function) return view
def axis_model(self, expression, limits=None): return self._axes([expression], limits=[limits])[0] def _axes(self, expressions, limits): limits = self.df.limits(expressions, limits) axes = [vaex.jupyter.model.Axis(df=self.df, expression=expression, min=min, max=max) for expression, (min, max) in zip(expressions, limits)] return axes def histogram(self, x, limits=None, selection=None, selection_interact='default', toolbar=True, shared=False, **kwargs): import vaex.jupyter.model import vaex.jupyter.view if selection is not None: selection = selection.copy() x, = self._axes([x], limits) model = vaex.jupyter.model.Histogram(df=self.df, x=x, selection=selection, selection_interact=selection_interact, **kwargs) if shared: grid = self.grid else: grid = vaex.jupyter.model.GridCalculator(self.df, []) grid.model_add(model) viz = vaex.jupyter.view.Histogram(model=model) if toolbar: viz.toolbar = _add_toolbar(viz) return viz def pie(self, x, limits=None, shared=False, **kwargs): import vaex.jupyter.model import vaex.jupyter.view x, = self._axes([x], limits) model = vaex.jupyter.model.Histogram(df=self.df, x=x, **kwargs) if shared: grid = self.grid else: grid = vaex.jupyter.model.GridCalculator(self.df, []) grid.model_add(model) viz = vaex.jupyter.view.PieChart(model=model) return viz def heatmap(self, x, y, limits=None, selection=None, selection_interact='default', transform='log', toolbar=True, shape=256, shared=False, **kwargs): import vaex.jupyter.model import vaex.jupyter.view x, y = self._axes([x, y], limits) if selection is not None: selection = selection.copy() model = vaex.jupyter.model.Heatmap(df=self.df, x=x, y=y, selection=selection, shape=shape, **kwargs) if shared: grid = self.grid else: grid = vaex.jupyter.model.GridCalculator(self.df, []) self._last_grid = grid grid.model_add(model) viz = vaex.jupyter.view.Heatmap(model=model, transform=transform) if toolbar: viz.toolbar = _add_toolbar(viz) return viz
[docs] def expression(self, value=None, label='Custom expression'): '''Create a widget to edit a vaex expression. If value is an :class:`vaex.jupyter.model.Axis` object, its expression will be (bi-directionally) linked to the widget. :param value: Valid expression (string or Expression object), or Axis ''' from .widgets import ExpressionTextArea import vaex.jupyter.model if isinstance(value, vaex.jupyter.model.Axis): expression_value = str(value.expression) else: expression_value = str(value) if value is not None else None expression_widget = ExpressionTextArea(df=self.df, v_model=expression_value, label=label) if isinstance(value, vaex.jupyter.model.Axis): import traitlets traitlets.link((value, 'expression'), (expression_widget, 'value')) return expression_widget
def column(self, value=None, label='Choose a column'): from .widgets import ColumnPicker if isinstance(value, vaex.jupyter.model.Axis): expression_value = str(value.expression) else: expression_value = str(value) if value is not None else None column_widget = ColumnPicker(df=self.df, value=expression_value, label=label) if isinstance(value, vaex.jupyter.model.Axis): import traitlets traitlets.link((value, 'expression'), (column_widget, 'value')) return column_widget def selection_expression(self, initial_value=None, name='default'): from .widgets import ExpressionSelectionTextArea if initial_value is None: if not self.df.has_selection(name): raise ValueError(f'No selection with name {name!r}') else: initial_value = self.df.get_selection(name).boolean_expression return ExpressionSelectionTextArea(df=self.df, selection_name=name, v_model=str(initial_value) if initial_value is not None else None) def progress_circular(self, width=10, size=70, color='#82B1FF', text='', auto_hide=False): from .widgets import ProgressCircularNoAnimation progress_circular = ProgressCircularNoAnimation(width=width, size=size, color=color, text=text, value=0) @self.df.executor.signal_begin.connect def progress_begin(): if auto_hide: progress_circular.hidden = False @self.df.executor.signal_progress.connect def update_progress(value): progress_circular.value = value*100 return True @self.df.executor.signal_end.connect def progress_update(): if auto_hide: progress_circular.hidden = True return progress_circular def counter_processed(self, postfix="rows processed", update_interval=0.2): from .widgets import Counter counter_processed = Counter(value=0, postfix=postfix) last_time = 0 @self.df.executor.signal_begin.connect def progress_begin(): nonlocal last_time last_time = time.time() @self.df.executor.signal_progress.connect def update_progress(value): nonlocal last_time number = int(value * len(self.df)) current_time = time.time() if (current_time - last_time) > update_interval or value in [0, 1]: counter_processed.value = number last_time = current_time return True return counter_processed def counter_selection(self, selection, postfix="rows selected", update_interval=0.2, lazy=False): from .widgets import Counter selected = self.df.count(selection=selection).item() if self.df.has_selection(name=selection) else 0 counter_selected = Counter(value=selected, postfix=postfix) dirty = False @self.df.signal_selection_changed.connect def selection_changed(df, name): nonlocal dirty if name == selection: # we only need to run once if not dirty: dirty = True def update_value(value): nonlocal dirty dirty = False try: value = value.item() except: # noqa pass counter_selected.value = value # if lazy is True, this will only schedule the calculation, not yet execute it if lazy: vaex.delayed(update_value)(self.df.count(selection=selection, delay=True)) else: update_value(self.df.count(selection=selection)) return counter_selected
# from .widgets import Tools # from traitlets import link # viz = [] if viz is None else viz # viz = [viz] if not isinstance(viz, (tuple, list)) else viz # tools = Tools(value=initial_value, children=[k.widget for k in viz]) # for v in viz: # link((tools, 'value'), (v, 'tool')) # return tools # def card(plot, title=None, subtitle=None, **kwargs): # from .widget import Card # return Card(main=plot, title=title, subtitle, def add_namespace(): pass