Example #1
0
    def test_dynamic_groupby_kdims_and_streams(self):
        def plot_function(mydim, data):
            return Scatter(data[data[:, 2]==mydim])

        buff = Buffer(data=np.empty((0, 3)))
        dmap = DynamicMap(plot_function, streams=[buff], kdims='mydim').redim.values(mydim=[0, 1, 2])
        ndlayout = dmap.groupby('mydim', container_type=NdLayout)
        self.assertIsInstance(ndlayout[0], DynamicMap)
        data = np.array([(0, 0, 0), (1, 1, 1), (2, 2, 2)])
        buff.send(data)
        self.assertEqual(ndlayout[0][()], Scatter([(0, 0)]))
        self.assertEqual(ndlayout[1][()], Scatter([(1, 1)]))
        self.assertEqual(ndlayout[2][()], Scatter([(2, 2)]))
class BokehApp:
    def __init__(self):
        self.switch_key = 'peak_8'
        self.maxlen = 1000000

        # Initialize buffers
        self.b_th_peak = Buffer(pd.DataFrame({
            'peak': [],
            'lowerbound': [],
            'higherbound': []
        }),
                                length=1000000)

        # Initialize callbacks
        self.callback_id_th_b = None

    def clear_buffer(self):
        """
        Modified version of hv.buffer.clear() since original appears to be
        buggy

        Clear buffer/graph whenever switch is toggled

        """
        with util.disable_constant(self.b_th_peak):

            self.b_th_peak.data = self.b_th_peak.data.iloc[:0]

        self.b_th_peak.send(
            pd.DataFrame({
                'peak': [],
                'lowerbound': [],
                'higherbound': []
            }))

    def produce_timehistory(self, context, doc):
        """
        Create timetool data timehistory
        
        Parameters
        ----------
        
        context = zmq.Context()
            Creates zmq socket to receive data
            
        doc: bokeh.document (I think)
            Bokeh document to be displayed on webpage
        
        """

        # Port to connect to master
        port = 5000
        socket = context.socket(zmq.SUB)

        # MUST BE FROM SAME MACHINE, CHANGE IF NECESSARY!!!
        socket.connect("tcp://localhost:%d" % port)
        socket.setsockopt(zmq.SUBSCRIBE, b"")

        # Dynamic Maps
        plot_peak_b = hv.DynamicMap(
            partial(hv.Points, kdims=['index', 'peak']),
            streams=[self.b_th_peak]).options(
                width=1000, finalize_hooks=[apply_formatter
                                            ]).redim.label(index='Time in UTC')

        plot_peak_std_low = hv.DynamicMap(
            partial(hv.Curve, kdims=['index', 'lowerbound']),
            streams=[self.b_th_peak]).options(
                line_alpha=0.5,
                line_color='gray').redim.label(index='Time in UTC')

        plot_peak_std_high = hv.DynamicMap(
            partial(hv.Curve, kdims=['index', 'higherbound']),
            streams=[self.b_th_peak]).options(
                line_alpha=0.5,
                line_color='gray').redim.label(index='Time in UTC')

        # Decimate and datashade
        pointTest = decimate(plot_peak_b, streams=[hv.streams.PlotSize])

        test1 = datashade(plot_peak_std_low,
                          streams=[hv.streams.PlotSize],
                          normalization='linear').options(
                              width=1000, finalize_hooks=[apply_formatter])

        test2 = datashade(plot_peak_std_high,
                          streams=[hv.streams.PlotSize],
                          normalization='linear')

        plot = (pointTest * test1 * test2)

        # Use bokeh to render plot
        hvplot = renderer.get_plot(plot, doc)

        def push_data(stream):
            """
            Push data to timetool time history graph
            
            """

            median = pd.DataFrame({'peak': []})
            lowerbound = pd.DataFrame({'peak': []})
            higherbound = pd.DataFrame({'peak': []})

            # Maybe fix this for stopping no data coming in? And switching issue? (Right now it's a feature)
            if socket.poll(timeout=0):
                data_dict = socket.recv_pyobj()
                peakDict = data_dict['peakDict']
                peakTSDict = data_dict['peakTSDict']

                TS_key = self.switch_key + '_TS'
                data = list(peakDict[self.switch_key])
                timestamp = list(peakTSDict[TS_key])

                times = [1000 * time for time in timestamp]
                dataSeries = pd.Series(data, index=times)

                zipped = basic_event_builder(peak=dataSeries)
                median = zipped.rolling(120, min_periods=1).median()
                std = zipped.rolling(120, min_periods=1).std()
                lowerbound = median - std
                higherbound = median + std

            df = pd.DataFrame({
                'peak': median['peak'],
                'lowerbound': lowerbound['peak'],
                'higherbound': higherbound['peak']
            })

            stream.send(df)

        def switch(attr, old, new):
            """
            Update drop down menu value

            """
            self.switch_key = select.value
            self.clear_buffer()
            print("Yes!")

        def play_graph():
            """
            Provide play and pause functionality to the graph

            """

            if startButton.label == '► Play':
                startButton.label = '❚❚ Pause'

                self.callback_id_th_b = doc.add_periodic_callback(
                    partial(push_data, stream=self.b_th_peak), 1000)

            else:
                startButton.label = '► Play'
                doc.remove_periodic_callback(self.callback_id_th_b)

        peak_list = [
            'peak_8', 'peak_9', 'peak_10', 'peak_11', 'peak_12', 'peak_13',
            'peak_14', 'peak_15'
        ]
        select = Select(title='Peak:', value='peak_8', options=peak_list)
        select.on_change('value', switch)

        startButton = Button(label='❚❚ Pause')
        startButton.on_click(play_graph)

        self.callback_id_th_b = doc.add_periodic_callback(
            partial(push_data, stream=self.b_th_peak), 1000)

        plot = column(select, startButton, hvplot.state)

        doc.title = "Time History Graphs"
        doc.add_root(plot)
Example #3
0
    def _process_data(self, kind, data, x, y, by, groupby, row, col, use_dask,
                      persist, backlog, label, value_label, hover_cols, kwds):
        gridded = kind in self._gridded_types
        gridded_data = False

        # Validate DataSource
        self.data_source = data
        self.is_series = is_series(data)
        if self.is_series:
            data = data.to_frame()
        if is_intake(data):
            data = process_intake(data, use_dask or persist)

        if groupby is not None and not isinstance(groupby, list):
            groupby = [groupby]
        if by is not None and not isinstance(by, list):
            by = [by]

        streaming = False
        if isinstance(data, pd.DataFrame):
            self.data = data
            if is_geopandas(data) and kind is None:
                geom_types = set(
                    [gt[5:] if 'Multi' in gt else gt for gt in data.geom_type])
                if len(geom_types) > 1:
                    raise ValueError(
                        'The GeopandasInterface can only read dataframes which '
                        'share a common geometry type')
                geom_type = list(geom_types)[0]
                if geom_type == 'Point':
                    kind = 'points'
                elif geom_type == 'Polygon':
                    kind = 'polygons'
                elif geom_type in ('LineString', 'LineRing'):
                    kind = 'paths'
        elif is_dask(data):
            self.data = data.persist() if persist else data
        elif is_streamz(data):
            self.data = data.example
            self.stream_type = data._stream_type
            streaming = True
            self.cb = data
            if data._stream_type == 'updating':
                self.stream = Pipe(data=self.data)
            else:
                self.stream = Buffer(data=self.data,
                                     length=backlog,
                                     index=False)
            data.stream.gather().sink(self.stream.send)
        elif is_xarray(data):
            import xarray as xr
            z = kwds.get('z')
            if z is None and isinstance(data, xr.Dataset):
                z = list(data.data_vars)[0]
            if gridded and isinstance(data,
                                      xr.Dataset) and not isinstance(z, list):
                data = data[z]

            ignore = (groupby or []) + (by or [])
            dims = [
                c for c in data.coords
                if data[c].shape != () and c not in ignore
            ]
            if kind is None and (not (x or y) or all(c in data.coords
                                                     for c in (x, y))):
                if len(dims) == 1:
                    kind = 'line'
                elif len(dims) == 2 or (x and y):
                    kind = 'image'
                    gridded = True
                else:
                    kind = 'hist'

            if gridded:
                gridded_data = True
            data, x, y, by_new, groupby_new = process_xarray(
                data, x, y, by, groupby, use_dask, persist, gridded, label,
                value_label)

            if kind not in self._stats_types:
                if by is None: by = by_new
                if groupby is None: groupby = groupby_new

            if groupby:
                groupby = [g for g in groupby if g not in (row, col)]
            self.data = data
        else:
            raise ValueError('Supplied data type %s not understood' %
                             type(data).__name__)

        # Validate data and arguments
        if by is None: by = []
        if groupby is None: groupby = []

        if gridded:
            if not gridded_data:
                raise ValueError('%s plot type requires gridded data, '
                                 'e.g. a NumPy array or xarray Dataset, '
                                 'found %s type' %
                                 (kind, type(self.data).__name__))
            not_found = [g for g in groupby if g not in data.coords]
            data_vars = list(data.data_vars) if isinstance(
                data, xr.Dataset) else [data.name]
            indexes = list(data.coords)
            self.variables = list(data.coords) + data_vars
            if groupby and not_found:
                raise ValueError('The supplied groupby dimension(s) %s '
                                 'could not be found, expected one or '
                                 'more of: %s' %
                                 (not_found, list(data.coords)))
        else:
            # Determine valid indexes
            if isinstance(self.data, pd.DataFrame):
                if self.data.index.names == [None]:
                    indexes = [self.data.index.name or 'index']
                else:
                    indexes = list(self.data.index.names)
            else:
                indexes = [
                    c for c in self.data.reset_index().columns
                    if c not in self.data.columns
                ]

            if len(indexes) == 2 and not (x or y or by):
                if kind == 'heatmap':
                    x, y = indexes
                elif kind in ('bar', 'barh'):
                    x, by = indexes

            # Rename non-string columns
            renamed = {
                c: str(c)
                for c in data.columns if not isinstance(c, hv.util.basestring)
            }
            if renamed:
                self.data = self.data.rename(columns=renamed)
            self.variables = indexes + list(self.data.columns)

            # Reset groupby dimensions
            groupby_index = [g for g in groupby if g in indexes]
            if groupby_index:
                self.data = self.data.reset_index(groupby_index)
            not_found = [
                g for g in groupby
                if g not in list(self.data.columns) + indexes
            ]
            if groupby and not_found:
                raise ValueError('The supplied groupby dimension(s) %s '
                                 'could not be found, expected one or '
                                 'more of: %s' %
                                 (not_found, list(self.data.columns)))

        # Set data-level options
        self.x = x
        self.y = y
        self.kind = kind or 'line'
        self.gridded = gridded
        self.use_dask = use_dask
        self.indexes = indexes
        if isinstance(by, (np.ndarray, pd.Series)):
            self.data['by'] = by
            self.by = ['by']
        elif not by:
            self.by = []
        else:
            self.by = by if isinstance(by, list) else [by]
        self.groupby = groupby
        self.streaming = streaming
        self.hover_cols = hover_cols
Example #4
0
 def get_stream(data):
     return Buffer(data, length=buffer_length, index=index)
Example #5
0
def produce_correlation_graphs(doc, diode_t_dict, diode_dict):
    """
    Produce correlation graphs and push them onto the web page document.
    
    Parameters
    ----------
    
    doc: bokeh.document (I think)
        Bokeh document to be displayed on webpage
    
    diode_t_dict: dictionary
        diciontary with deques containing timestamps of the diode readings
    
    diode_dict: dictionary
        dictionary with deques containing diode readins
    
    """

    # Initialize formatting variables
    buffer_length = 40000
    width = 500

    # Initialize Streams
    b_dcc_dco = Buffer(pd.DataFrame({
        'x_diode': [],
        'y_diode': []
    }),
                       length=buffer_length)
    b_t4d_dd = Buffer(pd.DataFrame({
        'x_diode': [],
        'y_diode': []
    }),
                      length=buffer_length)
    b_do_di = Buffer(pd.DataFrame({
        'x_diode': [],
        'y_diode': []
    }),
                     length=buffer_length)
    b_t4d_dco = Buffer(pd.DataFrame({
        'x_diode': [],
        'y_diode': []
    }),
                       length=buffer_length)

    # Initialize dynamic maps
    hvPoint_dcc_dco = hv.DynamicMap(
        partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='DCC vs DCO'),
        streams=[b_dcc_dco]).options(width=width).redim.label(x_diode='DCC',
                                                              y_diode='DCO')

    hvPoint_t4d_dd = hv.DynamicMap(
        partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='T4D vs DD'),
        streams=[b_t4d_dd]).options(width=width).redim.label(x_diode='T4D',
                                                             y_diode='DD')

    hvPoint_do_di = hv.DynamicMap(
        partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='DO vs DI'),
        streams=[b_do_di]).options(width=width).redim.label(x_diode='DO',
                                                            y_diode='DI')

    hvPoint_t4d_dco = hv.DynamicMap(
        partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='T4D vs DCO'),
        streams=[b_t4d_dco]).options(width=width).redim.label(x_diode='T4D',
                                                              y_diode='DCO')

    plots_col = (hvPoint_dcc_dco + hvPoint_t4d_dco + hvPoint_do_di +
                 hvPoint_t4d_dd).cols(2)

    # Render plot with bokeh
    hvplot = renderer.get_plot(plots_col, doc)

    # Initialize callbacks
    cb_id_dcc_dco = None
    cb_id_t4d_dd = None
    cb_id_do_di = None
    cb_id_t4d_dco = None

    # Push data into buffers
    def push_data(x_diode, y_diode, x_diode_t, y_diode_t, buffer):
        """
        Push data from x and y diode into buffer to be graphed.

        """

        x_diode_data = pd.Series(x_diode, index=x_diode_t)
        y_diode_data = pd.Series(y_diode, index=y_diode_t)
        zipped = basic_event_builder(x_diode=x_diode_data,
                                     y_diode=y_diode_data)
        buffer.send(zipped)

    #
    def play_graph():
        """
        Provide play and pause functionality to the graph

        """

        nonlocal cb_id_dcc_dco, cb_id_t4d_dd, cb_id_do_di, cb_id_t4d_dco

        cb_time = 1000

        if startButton.label == '► Play':
            startButton.label = '❚❚ Pause'

            cb_id_dcc_dco = doc.add_periodic_callback(
                partial(push_data,
                        x_diode=diode_dict['dcc_d'],
                        y_diode=diode_dict['dco_d'],
                        x_diode_t=diode_t_dict['dcc_t'],
                        y_diode_t=diode_t_dict['dco_t'],
                        buffer=b_dcc_dco), cb_time)

            cb_id_t4d_dd = doc.add_periodic_callback(
                partial(push_data,
                        x_diode=diode_dict['t4d_d'],
                        y_diode=diode_dict['dd_d'],
                        x_diode_t=diode_t_dict['t4d_t'],
                        y_diode_t=diode_t_dict['dd_t'],
                        buffer=b_t4d_dd), cb_time)

            cb_id_do_di = doc.add_periodic_callback(
                partial(push_data,
                        x_diode=diode_dict['do_d'],
                        y_diode=diode_dict['di_d'],
                        x_diode_t=diode_t_dict['do_t'],
                        y_diode_t=diode_t_dict['di_t'],
                        buffer=b_do_di), cb_time)

            cb_id_t4d_dco = doc.add_periodic_callback(
                partial(push_data,
                        x_diode=diode_dict['t4d_d'],
                        y_diode=diode_dict['dco_d'],
                        x_diode_t=diode_t_dict['t4d_t'],
                        y_diode_t=diode_t_dict['dco_t'],
                        buffer=b_t4d_dco), cb_time)

        else:
            startButton.label = '► Play'
            doc.remove_periodic_callback(cb_id_dcc_dco)
            doc.remove_periodic_callback(cb_id_t4d_dd)
            doc.remove_periodic_callback(cb_id_do_di)
            doc.remove_periodic_callback(cb_id_t4d_dco)

    # Create widgets
    startButton = Button(label='► Play')
    startButton.on_click(play_graph)

    plot = layout([startButton, row([hvplot.state])])

    doc.title = "Correlation Graphs"
    doc.add_root(plot)
Example #6
0
    def __init__(self,
                 data,
                 kind=None,
                 by=None,
                 width=700,
                 height=300,
                 shared_axes=False,
                 columns=None,
                 grid=False,
                 legend=True,
                 rot=None,
                 title=None,
                 xlim=None,
                 ylim=None,
                 xticks=None,
                 yticks=None,
                 fontsize=None,
                 colormap=None,
                 stacked=False,
                 logx=False,
                 logy=False,
                 loglog=False,
                 hover=True,
                 style_opts={},
                 plot_opts={},
                 use_index=False,
                 value_label='value',
                 group_label='Group',
                 colorbar=False,
                 streaming=False,
                 backlog=1000,
                 timeout=1000,
                 persist=False,
                 use_dask=False,
                 datashade=False,
                 **kwds):

        # Validate DataSource
        if not isinstance(data, DataSource):
            raise TypeError('Can only plot intake DataSource types')
        elif data.container != 'dataframe':
            raise NotImplementedError('Plotting interface currently only '
                                      'supports DataSource objects with '
                                      'dataframe container.')
        self.data_source = data
        self.streaming = streaming
        self.use_dask = use_dask
        if streaming:
            self.data = data.read()
            self.stream = Buffer(self.data, length=backlog)
            if gen is None:
                raise ImportError('Streaming support requires tornado.')

            @gen.coroutine
            def f():
                self.stream.send(data.read())

            self.cb = PeriodicCallback(f, timeout)
        elif (use_dask or persist) and dd is not None:
            ddf = data.to_dask()
            self.data = ddf.persist() if persist else ddf
        else:
            self.data = data.read()

        # High-level options
        self.by = by or []
        self.columns = columns
        self.stacked = stacked
        self.use_index = use_index
        self.kwds = kwds
        self.value_label = value_label
        self.group_label = group_label
        self.datashade = datashade

        # Process style options
        if 'cmap' in kwds and colormap:
            raise TypeError("Only specify one of `cmap` and `colormap`.")
        elif 'cmap' in kwds:
            cmap = kwds.pop('cmap')
        else:
            cmap = colormap

        self._style_opts = dict(**style_opts)
        if cmap:
            self._style_opts['cmap'] = cmap
        if 'size' in kwds:
            self._style_opts['size'] = kwds.pop('size')
        if 'alpha' in kwds:
            self._style_opts['alpha'] = kwds.pop('alpha')

        # Process plot options
        plot_options = dict(plot_opts)
        plot_options['logx'] = logx or loglog
        plot_options['logy'] = logy or loglog
        plot_options['show_grid'] = grid
        plot_options['shared_axes'] = shared_axes
        plot_options['show_legend'] = legend
        if xticks:
            plot_options['xticks'] = xticks
        if yticks:
            plot_options['yticks'] = yticks
        if width:
            plot_options['width'] = width
        if height:
            plot_options['height'] = height
        if fontsize:
            plot_options['fontsize'] = fontsize
        if colorbar:
            plot_options['colorbar'] = colorbar
        if self.kwds.get('vert', False):
            plot_options['invert_axes'] = True
        if rot:
            if (kind == 'barh' or kwds.get('orientation') == 'horizontal'
                    or kwds.get('vert')):
                axis = 'yrotation'
            else:
                axis = 'xrotation'
            plot_options[axis] = rot
        if hover:
            plot_options['tools'] = ['hover']
        self._hover = hover
        self._plot_opts = plot_options

        self._relabel = {'label': title}
        self._dim_ranges = {
            'x': xlim or (None, None),
            'y': ylim or (None, None)
        }
        self._norm_opts = {'framewise': True}
Example #7
0
class HoloViewsConverter(object):
    def __init__(self,
                 data,
                 kind=None,
                 by=None,
                 width=700,
                 height=300,
                 shared_axes=False,
                 columns=None,
                 grid=False,
                 legend=True,
                 rot=None,
                 title=None,
                 xlim=None,
                 ylim=None,
                 xticks=None,
                 yticks=None,
                 fontsize=None,
                 colormap=None,
                 stacked=False,
                 logx=False,
                 logy=False,
                 loglog=False,
                 hover=True,
                 style_opts={},
                 plot_opts={},
                 use_index=False,
                 value_label='value',
                 group_label='Group',
                 colorbar=False,
                 streaming=False,
                 backlog=1000,
                 timeout=1000,
                 persist=False,
                 use_dask=False,
                 datashade=False,
                 **kwds):

        # Validate DataSource
        if not isinstance(data, DataSource):
            raise TypeError('Can only plot intake DataSource types')
        elif data.container != 'dataframe':
            raise NotImplementedError('Plotting interface currently only '
                                      'supports DataSource objects with '
                                      'dataframe container.')
        self.data_source = data
        self.streaming = streaming
        self.use_dask = use_dask
        if streaming:
            self.data = data.read()
            self.stream = Buffer(self.data, length=backlog)
            if gen is None:
                raise ImportError('Streaming support requires tornado.')

            @gen.coroutine
            def f():
                self.stream.send(data.read())

            self.cb = PeriodicCallback(f, timeout)
        elif (use_dask or persist) and dd is not None:
            ddf = data.to_dask()
            self.data = ddf.persist() if persist else ddf
        else:
            self.data = data.read()

        # High-level options
        self.by = by or []
        self.columns = columns
        self.stacked = stacked
        self.use_index = use_index
        self.kwds = kwds
        self.value_label = value_label
        self.group_label = group_label
        self.datashade = datashade

        # Process style options
        if 'cmap' in kwds and colormap:
            raise TypeError("Only specify one of `cmap` and `colormap`.")
        elif 'cmap' in kwds:
            cmap = kwds.pop('cmap')
        else:
            cmap = colormap

        self._style_opts = dict(**style_opts)
        if cmap:
            self._style_opts['cmap'] = cmap
        if 'size' in kwds:
            self._style_opts['size'] = kwds.pop('size')
        if 'alpha' in kwds:
            self._style_opts['alpha'] = kwds.pop('alpha')

        # Process plot options
        plot_options = dict(plot_opts)
        plot_options['logx'] = logx or loglog
        plot_options['logy'] = logy or loglog
        plot_options['show_grid'] = grid
        plot_options['shared_axes'] = shared_axes
        plot_options['show_legend'] = legend
        if xticks:
            plot_options['xticks'] = xticks
        if yticks:
            plot_options['yticks'] = yticks
        if width:
            plot_options['width'] = width
        if height:
            plot_options['height'] = height
        if fontsize:
            plot_options['fontsize'] = fontsize
        if colorbar:
            plot_options['colorbar'] = colorbar
        if self.kwds.get('vert', False):
            plot_options['invert_axes'] = True
        if rot:
            if (kind == 'barh' or kwds.get('orientation') == 'horizontal'
                    or kwds.get('vert')):
                axis = 'yrotation'
            else:
                axis = 'xrotation'
            plot_options[axis] = rot
        if hover:
            plot_options['tools'] = ['hover']
        self._hover = hover
        self._plot_opts = plot_options

        self._relabel = {'label': title}
        self._dim_ranges = {
            'x': xlim or (None, None),
            'y': ylim or (None, None)
        }
        self._norm_opts = {'framewise': True}

    @streaming
    def table(self, x=None, y=None, data=None):
        allowed = ['width', 'height']
        opts = {k: v for k, v in self._plot_opts.items() if k in allowed}

        data = self.data if data is None else data
        return Table(data, self.columns, []).opts(plot=opts)

    def __call__(self, kind, x, y):
        return getattr(self, kind)(x, y)

    def single_chart(self, element, x, y, data=None):
        opts = {
            element.__name__:
            dict(plot=self._plot_opts,
                 norm=self._norm_opts,
                 style=self._style_opts)
        }
        ranges = {y: self._dim_ranges['y']}
        if x:
            ranges[x] = self._dim_ranges['x']

        data = self.data if data is None else data
        ys = [y]
        if 'c' in self.kwds and self.kwds['c'] in data.columns:
            ys += [self.kwds['c']]

        if self.by:
            chart = Dataset(data, [self.by, x], ys).to(element, x, ys,
                                                       self.by).overlay()
        else:
            chart = element(data, x, ys)
        return chart.redim.range(**ranges).relabel(**self._relabel).opts(opts)

    def chart(self, element, x, y, data=None):
        "Helper method for simple x vs. y charts"
        if x and y:
            return self.single_chart(element, x, y, data)

        # Note: Loading dask dataframe into memory due to rename bug
        data = (self.data if data is None else data)
        if self.use_dask: data = data.compute()
        opts = dict(plot=dict(self._plot_opts, labelled=['x']),
                    norm=self._norm_opts,
                    style=self._style_opts)

        if self.use_index or x:
            if self.use_index is not None and isinstance(self.use_index, bool):
                x = x or data.index.name or 'index'
            else:
                x = self.use_index
            columns = self.columns or data.columns
            charts = {}
            for c in columns:
                chart = element(data, x, c).redim(**{c: self.value_label})
                ranges = {x: self._dim_ranges['x'], c: self._dim_ranges['y']}
                charts[c] = (chart.relabel(**self._relabel).redim.range(
                    **ranges).opts(**opts))
            return NdOverlay(charts)
        else:
            raise ValueError('Could not determine what to plot. Expected '
                             'either x and y parameters to be declared '
                             'or use_index to be enabled.')

    @datashading
    @streaming
    def line(self, x, y, data=None):
        return self.chart(Curve, x, y, data)

    @datashading
    @streaming
    def scatter(self, x, y, data=None):
        scatter = self.chart(Scatter, x, y, data)
        if 'c' in self.kwds:
            color_opts = {
                'Scatter': {
                    'colorbar': self.kwds.get('colorbar', False),
                    'color_index': self.kwds['c']
                }
            }
            return scatter.opts(plot=color_opts)
        return scatter

    @streaming
    def area(self, x, y, data=None):
        areas = self.chart(Area, x, y, data)
        if self.stacked:
            areas = areas.map(Area.stack, NdOverlay)
        return areas

    def _category_plot(self, element, data=None):
        """
        Helper method to generate element from indexed dataframe.
        """
        data = self.data if data is None else data
        if isinstance(self.use_index, bool):
            index = data.index.name or 'index'
        else:
            index = self.use_index

        kdims = [index, self.group_label]
        id_vars = [index]
        invert = not self.kwds.get('vert', True)
        opts = {
            'plot': dict(self._plot_opts, labelled=[]),
            'norm': self._norm_opts
        }
        ranges = {self.value_label: self._dim_ranges['y']}

        if self.columns:
            data = data[self.columns + id_vars]
        if dd and isinstance(data, dd.DataFrame):
            data = data.compute()
        df = pd.melt(data,
                     id_vars=id_vars,
                     var_name=self.group_label,
                     value_name=self.value_label)
        return (element(df, kdims, self.value_label).redim.range(
            **ranges).relabel(**self._relabel).opts(**opts))

    def _stats_plot(self, element, y, data=None):
        """
        Helper method to generate element from indexed dataframe.
        """
        data = self.data if data is None else data

        opts = {
            'plot': dict(self._plot_opts, labelled=[]),
            'norm': self._norm_opts,
            'style': self._style_opts
        }
        if y:
            ranges = {y: self._dim_ranges['y']}
            kdims = [self.by] if self.by else []
            return (element(
                data, kdims,
                y).redim.range(**ranges).relabel(**self._relabel).opts(**opts))

        kdims = [self.group_label]
        ranges = {self.value_label: self._dim_ranges['y']}
        if self.columns:
            data = data[self.columns]
        if dd and isinstance(data, dd.DataFrame):
            data = data.compute()
        df = pd.melt(data,
                     var_name=self.group_label,
                     value_name=self.value_label)
        return (element(df, kdims, self.value_label).redim.range(
            **ranges).relabel(**self._relabel).opts(**opts))

    @streaming
    def bar(self, x, y, data=None):
        if x and y:
            return self.single_chart(Bars, x, y, data)
        elif self.use_index:
            stack_index = 1 if self.stacked else None
            opts = {'Bars': {'stack_index': stack_index}}
            return self._category_plot(Bars, data).opts(plot=opts)
        else:
            raise ValueError('Could not determine what to plot. Expected '
                             'either x and y parameters to be declared '
                             'or use_index to be enabled.')

    @streaming
    def barh(self, x, y, data=None):
        return self.bar(x, y, data).opts(plot={'Bars': dict(invert_axes=True)})

    @streaming
    def box(self, x, y, data=None):
        return self._stats_plot(BoxWhisker, y, data)

    @streaming
    def violin(self, x, y, data=None):
        try:
            from holoviews.element import Violin
        except ImportError:
            raise ImportError('Violin plot requires HoloViews version >=1.10')
        return self._stats_plot(Violin, y, data)

    @streaming
    def hist(self, x, y, data=None):
        plot_opts = dict(self._plot_opts)
        invert = self.kwds.get('orientation', False) == 'horizontal'
        opts = dict(plot=dict(plot_opts, labelled=['x'], invert_axes=invert),
                    style=self._style_opts,
                    norm=self._norm_opts)
        hist_opts = {
            'num_bins': self.kwds.get('bins', 10),
            'bin_range': self.kwds.get('bin_range', None),
            'normed': self.kwds.get('normed', False)
        }

        data = self.data if data is None else data
        ds = Dataset(data)
        if y and self.by:
            return histogram(ds.to(Dataset, [], y, self.by), **hist_opts).\
                overlay().opts({'Histogram': opts})
        elif y:
            return histogram(ds, dimension=y, **hist_opts).\
                opts({'Histogram': opts})

        hists = {}
        columns = self.columns or data.columns
        for col in columns:
            hist = histogram(ds, dimension=col, **hist_opts)
            ranges = {hist.vdims[0].name: self._dim_ranges['y']}
            hists[col] = (hist.redim.range(**ranges).relabel(
                **self._relabel).opts(**opts))
        return NdOverlay(hists)

    @streaming
    def kde(self, x, y, data=None):
        data = self.data if data is None else data
        plot_opts = dict(self._plot_opts)
        invert = self.kwds.get('orientation', False) == 'horizontal'
        opts = dict(plot=dict(plot_opts, invert_axes=invert),
                    style=self._style_opts,
                    norm=self._norm_opts)
        opts = {
            'Distribution': opts,
            'Area': opts,
            'NdOverlay': {
                'plot': dict(plot_opts, legend_limit=0)
            }
        }

        if y and self.by:
            ds = Dataset(data)
            return ds.to(Distribution, y, [], self.by).overlay().opts(opts)
        elif y:
            return Distribution(data, y, []).opts(opts)

        if self.columns:
            data = data[self.columns]
        df = pd.melt(data,
                     var_name=self.group_label,
                     value_name=self.value_label)
        ds = Dataset(df)
        if len(df):
            overlay = ds.to(Distribution, self.value_label).overlay()
        else:
            vdim = self.value_label + ' Density'
            overlay = NdOverlay({0: Area([], self.value_label, vdim)},
                                [self.group_label])
        return overlay.relabel(**self._relabel).opts(opts)

    @streaming
    def heatmap(self, x, y, data=None):
        data = data or self.data
        if not x: x = data.columns[0]
        if not y: y = data.columns[1]
        z = self.kwds.get('C', data.columns[2])

        opts = dict(plot=self._plot_opts,
                    norm=self._norm_opts,
                    style=self._style_opts)
        hmap = HeatMap(data, [x, y], z).opts(**opts)
        if 'reduce_function' in self.kwds:
            return hmap.aggregate(function=self.kwds['reduce_function'])
        return hmap