def single_chart(self, element, x, y, data=None): labelled = ['y' if self.invert else 'x'] if x != 'index' else [] if not self.is_series: labelled.append('x' if self.invert else 'y') elif not self.label: self._relabel['label'] = y opts = { element.__name__: dict(plot=dict(self._plot_opts, labelled=labelled), 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] for p in 'cs': if p in self.kwds and self.kwds[p] in data.columns: ys += [self.kwds[p]] if self.by: chart = Dataset(data, self.by + [x], ys).to(element, x, ys, self.by).relabel(**self._relabel) chart = chart.layout() if self.subplots else chart.overlay( ).options(batched=False) else: chart = element(data, x, ys).relabel(**self._relabel) return chart.redim.range(**ranges).redim(**self._redim).opts(opts)
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)
def kde(self, x, y, data=None): data, x, y = self._process_args(data, x, y) opts = dict(plot=self._plot_opts, style=self._style_opts, norm=self._norm_opts) opts = { 'Distribution': opts, 'Area': opts, 'NdOverlay': { 'plot': dict(self._plot_opts, legend_limit=0) } } if not isinstance(y, (list, tuple)): ranges = {y: self._dim_ranges['x']} if self.by: dists = Dataset(data).to(Distribution, y, [], self.by) dists = dists.layout() if self.subplots else dists.overlay() else: dists = Distribution(data, y, []) else: ranges = {self.value_label: self._dim_ranges['x']} data = data[y] df = pd.melt(data, var_name=self.group_label, value_name=self.value_label) ds = Dataset(df) if len(df): dists = ds.to(Distribution, self.value_label).overlay() else: vdim = self.value_label + ' Density' dists = NdOverlay({0: Area([], self.value_label, vdim)}, [self.group_label]) return dists.redim(**self._redim).redim.range(**ranges).relabel( **self._relabel).opts(opts)
def test_quadmesh_update_cbar(self): xs = ys = np.linspace(0, 6, 10) zs = np.linspace(1, 2, 5) XS, YS, ZS = np.meshgrid(xs, ys, zs) values = np.sin(XS) * ZS ds = Dataset((xs, ys, zs, values.T), ['x', 'y', 'z'], 'values') hmap = ds.to(QuadMesh).options(colorbar=True, framewise=True) plot = mpl_renderer.get_plot(hmap) self.assertEqual(plot.handles['cbar'].get_clim(), (-0.9989549170979283, 0.9719379013633127)) plot.update(3) self.assertEqual(plot.handles['cbar'].get_clim(), (-1.7481711049213744, 1.7008913273857973))
def hist(self, x, y, data=None): data, x, y = self._process_args(data, x, y) labelled = ['y'] if self.invert else ['x'] plot_opts = dict(self._plot_opts, labelled=labelled) opts = dict(plot=plot_opts, style=self._style_opts, norm=self._norm_opts) hist_opts = { 'bin_range': self.kwds.get('bin_range', None), 'normed': self.kwds.get('normed', False), 'cumulative': self.kwds.get('cumulative', False) } if 'bins' in self.kwds: bins = self.kwds['bins'] if isinstance(bins, int): hist_opts['num_bins'] = bins else: hist_opts['bins'] = bins if not isinstance(y, (list, tuple)): if self.stacked and not self.subplots and not 'bin_range' in self.kwds: ys = data[y] hist_opts['bin_range'] = (ys.min(), ys.max()) ds = Dataset(data, self.by, y) hist = hists = histogram(ds.to(Dataset, [], y, self.by), **hist_opts) if self.by: hist = hists.last hists = hists.layout() if self.subplots else hists.overlay() ranges = { hist.kdims[0].name: self._dim_ranges['x'], hist.vdims[0].name: self._dim_ranges['y'] } return hists.opts({ 'Histogram': opts }).redim(**self._redim).redim.range(**ranges) ds = Dataset(data) hists = [] for col in y: hist = histogram(ds, dimension=col, **hist_opts) ranges = { hist.kdims[0].name: self._dim_ranges['x'], hist.vdims[0].name: self._dim_ranges['y'] } hists.append((col, hist.redim.range(**ranges).relabel( **self._relabel).opts(**opts))) return self._by_type(hists, sort=False).redim(**self._redim)
def test_histogram_datetime64_plot(self): dates = np.array([dt.datetime(2017, 1, i) for i in range(1, 5)]) hist = histogram(Dataset(dates, 'Date'), num_bins=4) plot = bokeh_renderer.get_plot(hist) source = plot.handles['source'] data = { 'top': np.array([ 3.85802469e-18, 3.85802469e-18, 3.85802469e-18, 3.85802469e-18 ]), 'left': np.array([ '2017-01-01T00:00:00.000000', '2017-01-01T17:59:59.999999', '2017-01-02T12:00:00.000000', '2017-01-03T06:00:00.000000' ], dtype='datetime64[us]'), 'right': np.array([ '2017-01-01T17:59:59.999999', '2017-01-02T12:00:00.000000', '2017-01-03T06:00:00.000000', '2017-01-04T00:00:00.000000' ], dtype='datetime64[us]') } for k, v in data.items(): self.assertEqual(source.data[k], v) xaxis = plot.handles['xaxis'] range_x = plot.handles['x_range'] self.assertIsInstance(xaxis, DatetimeAxis) self.assertEqual(range_x.start, np.datetime64('2017-01-01T00:00:00.000000', 'us')) self.assertEqual(range_x.end, np.datetime64('2017-01-04T00:00:00.000000', 'us'))
def test_histogram_datetime64_plot(self): dates = np.array([dt.datetime(2017, 1, i) for i in range(1, 5)]) hist = histogram(Dataset(dates, 'Date'), num_bins=4) plot = mpl_renderer.get_plot(hist) artist = plot.handles['artist'] ax = plot.handles['axis'] self.assertEqual(ax.get_xlim(), (17167.0, 17170.0)) bounds = [17167.0, 17167.75, 17168.5, 17169.25] self.assertEqual([p.get_x() for p in artist.patches], bounds)
def test_histogram_datetime64_plot(self): dates = np.array([dt.datetime(2017, 1, i) for i in range(1, 5)]) hist = histogram(Dataset(dates, 'Date'), num_bins=4) plot = mpl_renderer.get_plot(hist) artist = plot.handles['artist'] ax = plot.handles['axis'] self.assertEqual(ax.get_xlim(), (736330.0, 736333.0)) self.assertEqual([p.get_x() for p in artist.patches], [736330.0, 736330.75, 736331.5, 736332.25])
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)
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 _category_plot(self, element, x, y, data): """ Helper method to generate element from indexed dataframe. """ labelled = ['y' if self.invert else 'x'] if x != 'index' else [] if self.value_label != 'value': labelled.append('x' if self.invert else 'y') opts = { 'plot': dict(self._plot_opts, labelled=labelled), 'style': dict(self._style_opts), 'norm': self._norm_opts } ranges = {self.value_label: self._dim_ranges['y']} id_vars = [x] if any(v in self.indexes for v in id_vars): data = data.reset_index() data = data[y + [x]] if check_library(data, 'dask'): from dask.dataframe import melt else: melt = pd.melt df = melt(data, id_vars=[x], var_name=self.group_label, value_name=self.value_label) kdims = [x, self.group_label] vdims = [self.value_label] + self.hover_cols if self.subplots: obj = Dataset(df, kdims, vdims).to(element, x).layout() else: obj = element(df, kdims, vdims) return obj.redim.range(**ranges).redim(**self._redim).relabel( **self._relabel).opts(**opts)
def dataset(self, x=None, y=None, data=None): data = self.data if data is None else data return Dataset(data, self.kwds.get('columns'), []).redim(**self._redim)
def __call__(self, kind, x, y): kind = self.kind or kind method = getattr(self, kind) groups = self.groupby zs = self.kwds.get('z', []) if not isinstance(zs, list): zs = [zs] grid = [] if self.row: grid.append(self.row) if self.col: grid.append(self.col) groups += grid if groups or len(zs) > 1: if self.streaming: raise NotImplementedError( "Streaming and groupby not yet implemented") data = self.data if not self.gridded and any(g in self.indexes for g in groups): data = data.reset_index() dataset = Dataset(data) if groups: dataset = dataset.groupby(groups, dynamic=self.dynamic) if len(zs) > 1: dimensions = [Dimension(self.group_label, values=zs) ] + dataset.kdims if self.dynamic: obj = DynamicMap( lambda *args: getattr(self, kind) (x, y, args[0], dataset[args[1:]].data), kdims=dimensions) else: obj = HoloMap( {(z, ) + k: getattr(self, kind)(x, y, z, dataset[k]) for k, v in dataset.data.items() for z in zs}, kdims=dimensions) else: obj = dataset.map( lambda ds: getattr(self, kind)(x, y, data=ds.data), Dataset) elif len(zs) > 1: if self.dynamic: dataset = DynamicMap( lambda z: getattr(self, kind) (x, y, z, data=dataset.data), kdims=[Dimension(self.group_label, values=zs)]) else: dataset = HoloMap( { z: getattr(self, kind)(x, y, z, data=dataset.data) for z in zs }, kdims=[self.group_label]) else: obj = getattr(self, kind)(x, y, data=dataset.data) if grid: obj = obj.grid(grid).options(shared_xaxis=True, shared_yaxis=True) else: if self.streaming: cbcallable = StreamingCallable(partial(method, x, y), periodic=self.cb) obj = DynamicMap(cbcallable, streams=[self.stream]) else: obj = method(x, y) if not (self.datashade or self.rasterize): return obj try: from holoviews.operation.datashader import datashade, rasterize, dynspread from datashader import count_cat except: raise ImportError('Datashading is not available') opts = dict(width=self._plot_opts['width'], height=self._plot_opts['height'], dynamic=self.dynamic) if 'cmap' in self._style_opts and self.datashade: levels = self._plot_opts.get('color_levels') opts['cmap'] = process_cmap(self._style_opts['cmap'], levels) opts['color_key'] = opts['cmap'] if self.by: opts['aggregator'] = count_cat(self.by[0]) if self.aggregator: opts['aggregator'] = self.aggregator if self.precompute: opts['precompute'] = self.precompute if self.x_sampling: opts['x_sampling'] = self.x_sampling if self.y_sampling: opts['y_sampling'] = self.y_sampling style = {} if self.datashade: operation = datashade eltype = 'RGB' else: operation = rasterize eltype = 'Image' if 'cmap' in self._style_opts: style['cmap'] = self._style_opts['cmap'] if self.crs: # Apply projection before rasterizing import cartopy.crs as ccrs from geoviews import project projection = self._plot_opts.get('projection', ccrs.GOOGLE_MERCATOR) obj = project(obj, projection=projection) processed = operation(obj, **opts) if self.dynspread: if self.datashade: processed = dynspread(processed, max_px=self.kwds.get('max_px', 3), threshold=self.kwds.get( 'threshold', 0.5)) else: self.warning( 'dynspread may only be applied on datashaded plots, ' 'use datashade=True instead of rasterize=True.') return processed.opts( {eltype: { 'plot': self._plot_opts, 'style': style }})
def __call__(self, kind, x, y): kind = self.kind or kind method = getattr(self, kind) groups = self.groupby zs = self.kwds.get('z', []) if not isinstance(zs, list): zs = [zs] grid = [] if self.row: grid.append(self.row) if self.col: grid.append(self.col) groups += grid if groups or len(zs) > 1: if self.streaming: raise NotImplementedError( "Streaming and groupby not yet implemented") dataset = Dataset(self.data) if groups: dataset = dataset.groupby(groups, dynamic=self.dynamic) if len(zs) > 1: dimensions = [Dimension(self.group_label, values=zs) ] + dataset.kdims if self.dynamic: obj = DynamicMap( lambda *args: getattr(self, kind) (x, y, args[0], dataset[args[1:]].data), kdims=dimensions) else: obj = HoloMap( {(z, ) + k: getattr(self, kind)(x, y, z, dataset[k]) for k, v in dataset.data.items() for z in zs}, kdims=dimensions) else: obj = dataset.map( lambda ds: getattr(self, kind)(x, y, data=ds.data), Dataset) elif len(zs) > 1: if self.dynamic: dataset = DynamicMap( lambda z: getattr(self, kind) (x, y, z, data=dataset.data), kdims=[Dimension(self.group_label, values=zs)]) else: dataset = HoloMap( { z: getattr(self, kind)(x, y, z, data=dataset.data) for z in zs }, kdims=[self.group_label]) else: obj = getattr(self, kind)(x, y, data=dataset.data) if grid: obj = obj.grid(grid).options(shared_xaxis=True, shared_yaxis=True) else: if self.streaming: cbcallable = StreamingCallable(partial(method, x, y), periodic=self.cb) obj = DynamicMap(cbcallable, streams=[self.stream]) else: obj = method(x, y) if not (self.datashade or self.rasterize): return obj try: from holoviews.operation.datashader import datashade, rasterize from datashader import count_cat except: raise ImportError('Datashading is not available') opts = dict(width=self._plot_opts['width'], height=self._plot_opts['height']) if 'cmap' in self._style_opts and self.datashade: opts['cmap'] = self._style_opts['cmap'] if self.by: opts['aggregator'] = count_cat(self.by[0]) if self.aggregator: opts['aggregator'] = self.aggregator style = {} if self.datashade: operation = datashade eltype = 'RGB' else: operation = rasterize eltype = 'Image' if 'cmap' in self._style_opts: style['cmap'] = self._style_opts['cmap'] if self.crs: # Apply projection before rasterizing import cartopy.crs as ccrs from geoviews import project projection = self._plot_opts.get('projection', ccrs.GOOGLE_MERCATOR) obj = project(obj, projection=projection) return operation(obj, **opts).opts( {eltype: { 'plot': self._plot_opts, 'style': style }})