hvplot 0.9.3a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. hvplot/__init__.py +322 -0
  2. hvplot/_version.py +16 -0
  3. hvplot/backend_transforms.py +329 -0
  4. hvplot/converter.py +2855 -0
  5. hvplot/cudf.py +26 -0
  6. hvplot/dask.py +42 -0
  7. hvplot/data/crime.csv +56 -0
  8. hvplot/datasets.yaml +48 -0
  9. hvplot/fugue.py +64 -0
  10. hvplot/ibis.py +21 -0
  11. hvplot/intake.py +32 -0
  12. hvplot/interactive.py +968 -0
  13. hvplot/networkx.py +625 -0
  14. hvplot/pandas.py +30 -0
  15. hvplot/plotting/__init__.py +63 -0
  16. hvplot/plotting/andrews_curves.py +99 -0
  17. hvplot/plotting/core.py +2288 -0
  18. hvplot/plotting/lag_plot.py +34 -0
  19. hvplot/plotting/parallel_coordinates.py +85 -0
  20. hvplot/plotting/scatter_matrix.py +220 -0
  21. hvplot/polars.py +21 -0
  22. hvplot/sample_data.py +30 -0
  23. hvplot/streamz.py +21 -0
  24. hvplot/tests/__init__.py +0 -0
  25. hvplot/tests/conftest.py +44 -0
  26. hvplot/tests/data/README.md +5 -0
  27. hvplot/tests/data/RGB-red.byte.tif +0 -0
  28. hvplot/tests/plotting/__init__.py +0 -0
  29. hvplot/tests/plotting/testcore.py +108 -0
  30. hvplot/tests/plotting/testohlc.py +34 -0
  31. hvplot/tests/plotting/testscattermatrix.py +138 -0
  32. hvplot/tests/test_links.py +99 -0
  33. hvplot/tests/testbackend_transforms.py +89 -0
  34. hvplot/tests/testcharts.py +452 -0
  35. hvplot/tests/testfugue.py +46 -0
  36. hvplot/tests/testgeo.py +468 -0
  37. hvplot/tests/testgeowithoutgv.py +60 -0
  38. hvplot/tests/testgridplots.py +259 -0
  39. hvplot/tests/testhelp.py +75 -0
  40. hvplot/tests/testibis.py +17 -0
  41. hvplot/tests/testinteractive.py +1442 -0
  42. hvplot/tests/testnetworkx.py +26 -0
  43. hvplot/tests/testoperations.py +385 -0
  44. hvplot/tests/testoptions.py +596 -0
  45. hvplot/tests/testoverrides.py +74 -0
  46. hvplot/tests/testpanel.py +70 -0
  47. hvplot/tests/testpatch.py +135 -0
  48. hvplot/tests/testplotting.py +69 -0
  49. hvplot/tests/teststreaming.py +28 -0
  50. hvplot/tests/testtransforms.py +39 -0
  51. hvplot/tests/testui.py +383 -0
  52. hvplot/tests/testutil.py +378 -0
  53. hvplot/tests/util.py +82 -0
  54. hvplot/ui.py +1032 -0
  55. hvplot/util.py +677 -0
  56. hvplot/utilities.py +129 -0
  57. hvplot/xarray.py +62 -0
  58. hvplot-0.9.3a1.dist-info/LICENSE +29 -0
  59. hvplot-0.9.3a1.dist-info/METADATA +243 -0
  60. hvplot-0.9.3a1.dist-info/RECORD +63 -0
  61. hvplot-0.9.3a1.dist-info/WHEEL +5 -0
  62. hvplot-0.9.3a1.dist-info/entry_points.txt +2 -0
  63. hvplot-0.9.3a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,34 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ from ..util import with_hv_extension
5
+ from .core import hvPlotTabular
6
+
7
+
8
+ @with_hv_extension
9
+ def lag_plot(data, lag=1, **kwds):
10
+ """Lag plot for time series.
11
+
12
+ Parameters:
13
+ -----------
14
+ data: Time series
15
+ lag: lag of the scatter plot, default 1
16
+ kwds: hvplot.scatter options, optional
17
+
18
+ Returns:
19
+ --------
20
+ obj : HoloViews object
21
+ The HoloViews representation of the plot.
22
+ """
23
+ if lag != int(lag) or int(lag) <= 0:
24
+ raise ValueError('lag must be a positive integer')
25
+ lag = int(lag)
26
+
27
+ values = data.values
28
+ y1 = 'y(t)'
29
+ y2 = f'y(t + {lag})'
30
+ lags = pd.DataFrame({y1: values[:-lag].T.ravel(), y2: values[lag:].T.ravel()})
31
+ if isinstance(data, pd.DataFrame):
32
+ lags['variable'] = np.repeat(data.columns, lags.shape[0] / data.shape[1])
33
+ kwds['c'] = 'variable'
34
+ return hvPlotTabular(lags)(y1, y2, kind='scatter', **kwds)
@@ -0,0 +1,85 @@
1
+ import holoviews as hv
2
+ import colorcet as cc
3
+
4
+ from ..backend_transforms import _transfer_opts_cur_backend
5
+ from ..util import with_hv_extension
6
+
7
+
8
+ @with_hv_extension
9
+ def parallel_coordinates(
10
+ data,
11
+ class_column,
12
+ cols=None,
13
+ alpha=0.5,
14
+ width=600,
15
+ height=300,
16
+ var_name='variable',
17
+ value_name='value',
18
+ cmap=None,
19
+ colormap=None,
20
+ **kwds,
21
+ ):
22
+ """
23
+ Parallel coordinates plotting.
24
+
25
+ To show a set of points in an n-dimensional space, a backdrop is drawn
26
+ consisting of n parallel lines. A point in n-dimensional space is
27
+ represented as a polyline with vertices on the parallel axes; the
28
+ position of the vertex on the i-th axis corresponds to the i-th coordinate
29
+ of the point.
30
+
31
+ Parameters
32
+ ----------
33
+ frame: DataFrame
34
+ class_column: str
35
+ Column name containing class names
36
+ cols: list, optional
37
+ A list of column names to use
38
+ alpha: float, optional
39
+ The transparency of the lines
40
+ cmap/colormap: str or colormap object
41
+ Colormap to use for groups
42
+
43
+ Returns
44
+ -------
45
+ obj : HoloViews object
46
+ The HoloViews representation of the plot.
47
+
48
+ See Also
49
+ --------
50
+ pandas.plotting.parallel_coordinates : matplotlib version of this routine
51
+ """
52
+ # Transform the dataframe to be used in Vega-Lite
53
+ if cols is not None:
54
+ data = data[list(cols) + [class_column]]
55
+ cols = data.columns
56
+ df = data.reset_index()
57
+ index = (set(df.columns) - set(cols)).pop()
58
+ assert index in df.columns
59
+ df = df.melt([index, class_column], var_name=var_name, value_name=value_name)
60
+
61
+ labelled = [] if var_name == 'variable' else ['x']
62
+ if value_name != 'value':
63
+ labelled.append('y')
64
+ options = {
65
+ 'Curve': dict(kwds, labelled=labelled, alpha=alpha, width=width, height=height),
66
+ 'Overlay': dict(legend_limit=5000),
67
+ }
68
+
69
+ dataset = hv.Dataset(df)
70
+ groups = dataset.to(hv.Curve, var_name, value_name).overlay(index).items()
71
+
72
+ if cmap and colormap:
73
+ raise TypeError('Only specify one of `cmap` and `colormap`.')
74
+ cmap = cmap or colormap or cc.palette['glasbey_category10']
75
+ colors = hv.plotting.util.process_cmap(cmap, categorical=True, ncolors=len(groups))
76
+
77
+ el = hv.Overlay(
78
+ [
79
+ curve.relabel(k).options('Curve', color=c, backend='bokeh')
80
+ for c, (k, v) in zip(colors, groups)
81
+ for curve in v
82
+ ]
83
+ ).options(options, backend='bokeh')
84
+ el = _transfer_opts_cur_backend(el)
85
+ return el
@@ -0,0 +1,220 @@
1
+ from functools import partial
2
+ import warnings
3
+
4
+ import holoviews as _hv
5
+ import numpy as _np
6
+
7
+ from packaging.version import Version
8
+
9
+ from ..backend_transforms import _transfer_opts_cur_backend
10
+ from ..converter import HoloViewsConverter
11
+ from ..util import with_hv_extension, _convert_col_names_to_str
12
+
13
+
14
+ @with_hv_extension
15
+ def scatter_matrix(
16
+ data,
17
+ c=None,
18
+ chart='scatter',
19
+ diagonal='hist',
20
+ alpha=0.5,
21
+ nonselection_alpha=0.1,
22
+ tools=None,
23
+ cmap=None,
24
+ colormap=None,
25
+ diagonal_kwds=None,
26
+ hist_kwds=None,
27
+ density_kwds=None,
28
+ datashade=False,
29
+ rasterize=False,
30
+ dynspread=False,
31
+ spread=False,
32
+ **kwds,
33
+ ):
34
+ """
35
+ Scatter matrix of numeric columns.
36
+
37
+ A scatter_matrix shows all the pairwise relationships between the columns.
38
+ Each non-diagonal plots the corresponding columns against each other,
39
+ while the diagonal plot shows the distribution of each individual column.
40
+
41
+ This function is closely modelled on :func:`pandas.plotting.scatter_matrix`.
42
+
43
+ Parameters:
44
+ -----------
45
+ data: DataFrame
46
+ The data to plot. Every column is compared to every other column.
47
+ c: str, optional
48
+ Column to color by
49
+ chart: str, optional
50
+ Chart type for the off-diagonal plots (one of 'scatter', 'bivariate', 'hexbin')
51
+ diagonal: str, optional
52
+ Chart type for the diagonal plots (one of 'hist', 'kde')
53
+ alpha: float, optional
54
+ Transparency level for the off-diagonal plots
55
+ nonselection_alpha: float, optional
56
+ Transparency level for nonselected object in the off-diagonal plots
57
+ tools: list of str, optional
58
+ Interaction tools to include
59
+ Defaults are 'box_select' and 'lasso_select'
60
+ cmap/colormap: str or colormap object, optional
61
+ Colormap to use when ``c`` is set.
62
+ Default is `Category10 <https://github.com/d3/d3-3.x-api-reference/blob/master/Ordinal-Scales.md#category10>`.
63
+ diagonal_kwds/hist_kwds/density_kwds: dict, optional
64
+ Keyword options for the diagonal plots
65
+ datashade (default=False):
66
+ Whether to apply rasterization and shading (colormapping) using
67
+ the Datashader library, returning an RGB object instead of
68
+ individual points
69
+ rasterize (default=False):
70
+ Whether to apply rasterization using the Datashader library,
71
+ returning an aggregated Image (to be colormapped by the
72
+ plotting backend) instead of individual points
73
+ dynspread (default=False):
74
+ For plots generated with datashade=True or rasterize=True,
75
+ automatically increase the point size when the data is sparse
76
+ so that individual points become more visible.
77
+ kwds supported include ``max_px``, ``threshold``, ``shape``, ``how`` and ``mask``.
78
+ spread (default=False):
79
+ Make plots generated with datashade=True or rasterize=True
80
+ increase the point size to make points more visible, by
81
+ applying a fixed spreading of a certain number of cells/pixels. kwds
82
+ supported include: ``px``, ``shape``, ``how`` and ``mask``.
83
+ kwds: Keyword options for the off-diagonal plots and datashader's spreading , optional
84
+
85
+ Returns:
86
+ --------
87
+ obj : HoloViews object
88
+ The HoloViews representation of the plot.
89
+
90
+ See Also
91
+ --------
92
+ :func:`pandas.plotting.scatter_matrix` : Equivalent pandas function.
93
+ """
94
+
95
+ data = _hv.Dataset(_convert_col_names_to_str(data))
96
+ supported = list(HoloViewsConverter._kind_mapping)
97
+ if diagonal not in supported:
98
+ raise ValueError(f'diagonal type must be one of: {supported}, found {diagonal}')
99
+ if chart not in supported:
100
+ raise ValueError(f'Chart type must be one of: {supported}, found {chart}')
101
+ diagonal = HoloViewsConverter._kind_mapping[diagonal]
102
+ chart = HoloViewsConverter._kind_mapping[chart]
103
+
104
+ if rasterize or datashade:
105
+ try:
106
+ import datashader # noqa
107
+ except ImportError:
108
+ raise ImportError('rasterize and datashade require datashader to be installed.')
109
+ from ..util import hv_version
110
+
111
+ if hv_version <= Version('1.14.6'):
112
+ warnings.warn(
113
+ 'Versions of holoviews before 1.14.7 did not support '
114
+ 'dynamic update of rasterized/datashaded scatter matrix. '
115
+ 'Update holoviews to a newer version.'
116
+ )
117
+
118
+ if rasterize and datashade:
119
+ raise ValueError('Choose to either rasterize or datashade the scatter matrix, not both.')
120
+
121
+ if not rasterize and not datashade and (spread or dynspread):
122
+ raise ValueError('dynspread or spread need rasterize or datashade to be set to True.')
123
+
124
+ if rasterize:
125
+ import holoviews.operation.datashader as hd
126
+
127
+ if dynspread or spread:
128
+ if hd.ds_version < Version('0.12.0'):
129
+ raise RuntimeError(
130
+ 'Any version of datashader less than 0.12.0 does '
131
+ 'not support rasterize with dynspread or spread.'
132
+ )
133
+
134
+ # remove datashade kwds
135
+ if datashade or rasterize:
136
+ import holoviews.operation.datashader as hd
137
+
138
+ ds_kwds = {}
139
+ if 'aggregator' in kwds:
140
+ ds_kwds['aggregator'] = kwds.pop('aggregator')
141
+
142
+ # remove dynspread kwds
143
+ sp_kwds = {}
144
+ if dynspread:
145
+ if 'max_px' in kwds:
146
+ sp_kwds['max_px'] = kwds.pop('max_px')
147
+ if 'threshold' in kwds:
148
+ sp_kwds['threshold'] = kwds.pop('threshold')
149
+ if 'shape' in kwds:
150
+ sp_kwds['shape'] = kwds.pop('shape')
151
+ if 'how' in kwds:
152
+ sp_kwds['how'] = kwds.pop('how')
153
+ if 'mask' in kwds:
154
+ sp_kwds['mask'] = kwds.pop('mask')
155
+ if spread:
156
+ if 'px' in kwds:
157
+ sp_kwds['px'] = kwds.pop('px')
158
+ if 'shape' in kwds:
159
+ sp_kwds['shape'] = kwds.pop('shape')
160
+ if 'how' in kwds:
161
+ sp_kwds['how'] = kwds.pop('how')
162
+ if 'mask' in kwds:
163
+ sp_kwds['mask'] = kwds.pop('mask')
164
+
165
+ tools = tools or ['box_select', 'lasso_select']
166
+ chart_opts = dict(alpha=alpha, tools=tools, nonselection_alpha=nonselection_alpha, **kwds)
167
+ if c:
168
+ if cmap and colormap:
169
+ raise TypeError('Only specify `cmap` or `colormap`.')
170
+ ncolors = len(_np.unique(data.dimension_values(c)))
171
+ cmap = cmap or colormap or 'Category10'
172
+ cmap = _hv.plotting.util.process_cmap(cmap, ncolors=ncolors, categorical=True)
173
+ chart_opts['cmap'] = cmap
174
+
175
+ # get initial scatter matrix. No color.
176
+ grid = _hv.operation.gridmatrix(data, diagonal_type=diagonal, chart_type=chart)
177
+
178
+ if c:
179
+ # change colors for scatter matrix
180
+ chart_opts['color'] = c
181
+ # Add color vdim to each plot.
182
+ grid = grid.map(lambda x: x.clone(vdims=x.vdims + [c]), 'Scatter')
183
+ # create a new scatter matrix with groups for each catetory, so now the histogram will
184
+ # show separate colors for each group.
185
+ groups = _hv.operation.gridmatrix(
186
+ data.groupby(c).overlay(), chart_type=chart, diagonal_type=diagonal
187
+ )
188
+ # take the correct layer from each Overlay object within the scatter matrix.
189
+ grid = (grid * groups).map(
190
+ lambda x: x.get(0) if isinstance(x.get(0), chart) else x.get(1), _hv.Overlay
191
+ )
192
+
193
+ if (
194
+ (diagonal_kwds and hist_kwds)
195
+ or (diagonal_kwds and density_kwds)
196
+ or (hist_kwds and density_kwds)
197
+ ):
198
+ raise TypeError('Specify at most one of `diagonal_kwds`, `hist_kwds`, or `density_kwds`.')
199
+
200
+ diagonal_opts = diagonal_kwds or hist_kwds or density_kwds or {}
201
+ # set the histogram colors
202
+ if c:
203
+ diagonal_opts['fill_color'] = _hv.Cycle(cmap)
204
+ # actually changing to the same color scheme for both scatter and histogram plots.
205
+ grid = grid.options(
206
+ {chart.__name__: chart_opts, diagonal.__name__: diagonal_opts},
207
+ backend='bokeh',
208
+ )
209
+
210
+ # Perform datashade options after all the coloring is finished.
211
+ if datashade or rasterize:
212
+ aggregatefn = hd.datashade if datashade else hd.rasterize
213
+ grid = grid.map(partial(aggregatefn, **ds_kwds), specs=chart)
214
+ if spread or dynspread:
215
+ spreadfn = hd.dynspread if dynspread else (hd.spread if spread else lambda z, **_: z)
216
+ eltype = _hv.RGB if datashade else _hv.Image
217
+ grid = grid.map(partial(spreadfn, **sp_kwds), specs=eltype)
218
+
219
+ grid = _transfer_opts_cur_backend(grid)
220
+ return grid
hvplot/polars.py ADDED
@@ -0,0 +1,21 @@
1
+ """Adds the `.hvplot` method to pl.DataFrame, pl.LazyFrame and pl.Series"""
2
+
3
+ from hvplot import post_patch
4
+ from hvplot.plotting.core import hvPlotTabularPolars
5
+
6
+
7
+ def patch(name='hvplot', extension='bokeh', logo=False):
8
+ try:
9
+ import polars as pl
10
+ except ImportError:
11
+ raise ImportError(
12
+ 'Could not patch plotting API onto Polars. Polars could not be imported.'
13
+ )
14
+ pl.api.register_dataframe_namespace(name)(hvPlotTabularPolars)
15
+ pl.api.register_series_namespace(name)(hvPlotTabularPolars)
16
+ pl.api.register_lazyframe_namespace(name)(hvPlotTabularPolars)
17
+
18
+ post_patch(extension, logo)
19
+
20
+
21
+ patch()
hvplot/sample_data.py ADDED
@@ -0,0 +1,30 @@
1
+ """
2
+ Loads hvPlot sample data using intake catalogue.
3
+ """
4
+
5
+ import os
6
+
7
+ try:
8
+ from intake import open_catalog
9
+ import intake_parquet # noqa
10
+ import intake_xarray # noqa
11
+ import s3fs # noqa
12
+ except ImportError:
13
+ raise ImportError(
14
+ """Loading hvPlot sample data requires:
15
+ * intake
16
+ * intake-parquet
17
+ * intake-xarray
18
+ * s3fs
19
+ Install these using conda or pip before loading data."""
20
+ )
21
+
22
+ _file_path = os.path.dirname(__file__)
23
+ _cat_path = os.path.join(_file_path, 'datasets.yaml')
24
+
25
+ # Load catalogue
26
+ catalogue = open_catalog(_cat_path)
27
+
28
+ # Add catalogue entries to namespace
29
+ for _c in catalogue:
30
+ globals()[_c] = catalogue[_c]
hvplot/streamz.py ADDED
@@ -0,0 +1,21 @@
1
+ def patch(name='hvplot', extension='bokeh', logo=False):
2
+ from . import hvPlotTabular, post_patch
3
+
4
+ try:
5
+ import streamz.dataframe as sdf
6
+ except ImportError:
7
+ raise ImportError(
8
+ 'Could not patch plotting API onto streamz. Streamz could not be imported.'
9
+ )
10
+ _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
11
+ _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
12
+ patch_property = property(_patch_plot)
13
+ setattr(sdf.DataFrame, name, patch_property)
14
+ setattr(sdf.DataFrames, name, patch_property)
15
+ setattr(sdf.Series, name, patch_property)
16
+ setattr(sdf.Seriess, name, patch_property)
17
+
18
+ post_patch(extension, logo)
19
+
20
+
21
+ patch()
File without changes
@@ -0,0 +1,44 @@
1
+ import dask
2
+
3
+ optional_markers = {
4
+ 'geo': {
5
+ 'help': 'Run the tests that require GeoViews',
6
+ 'marker-descr': 'Geo test marker',
7
+ 'skip-reason': 'Test only runs with the --geo option.',
8
+ },
9
+ }
10
+
11
+
12
+ def pytest_addoption(parser):
13
+ for marker, info in optional_markers.items():
14
+ parser.addoption(
15
+ '--{}'.format(marker), action='store_true', default=False, help=info['help']
16
+ )
17
+
18
+
19
+ def pytest_configure(config):
20
+ for marker, info in optional_markers.items():
21
+ config.addinivalue_line('markers', '{}: {}'.format(marker, info['marker-descr']))
22
+
23
+
24
+ def pytest_collection_modifyitems(config, items):
25
+ skipped, selected = [], []
26
+ markers = [m for m in optional_markers if config.getoption(f'--{m}')]
27
+ empty = not markers
28
+ for item in items:
29
+ if empty and any(m in item.keywords for m in optional_markers):
30
+ skipped.append(item)
31
+ elif empty:
32
+ selected.append(item)
33
+ elif not empty and any(m in item.keywords for m in markers):
34
+ selected.append(item)
35
+ else:
36
+ skipped.append(item)
37
+
38
+ config.hook.pytest_deselected(items=skipped)
39
+ items[:] = selected
40
+
41
+
42
+ # From Dask 2024.3.0 they now use `dask_expr` by default
43
+ # https://github.com/dask/dask/issues/10995
44
+ dask.config.set({'dataframe.query-planning': False})
@@ -0,0 +1,5 @@
1
+ # Test data
2
+
3
+ Test files required by the test suite:
4
+
5
+ * The RGB-red.byte.tif file was obtained from [rasterio](https://github.com/rasterio/rasterio) test suite and downsampled to reduce its size. The original image is derived from USGS Landsat 7 ETM imagery and is licensed under the [CC0 1.0 Universal (CC0 1.0) Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/).
Binary file
File without changes
@@ -0,0 +1,108 @@
1
+ from packaging.version import Version
2
+ from unittest import SkipTest
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+ import hvplot.pandas # noqa
7
+ import pytest
8
+
9
+ from hvplot import hvPlotTabular
10
+ from hvplot.tests.util import makeDataFrame
11
+
12
+ try:
13
+ import polars as pl
14
+ import hvplot.polars # noqa
15
+
16
+ skip_polar = False
17
+ except ImportError:
18
+
19
+ class pl:
20
+ DataFrame = None
21
+ LazyFrame = None
22
+ Series = None
23
+
24
+ skip_polar = True
25
+
26
+ try:
27
+ import dask.dataframe as dd
28
+ import hvplot.dask # noqa
29
+ except ImportError:
30
+ dd = None
31
+
32
+
33
+ TYPES = {t for t in dir(hvPlotTabular) if not t.startswith('_') and t != 'explorer'}
34
+ FRAME_TYPES = TYPES - {'bivariate', 'heatmap', 'hexbin', 'labels', 'vectorfield'}
35
+ SERIES_TYPES = FRAME_TYPES - {'points', 'polygons', 'ohlc', 'paths'}
36
+ frame_kinds = pytest.mark.parametrize('kind', sorted(FRAME_TYPES))
37
+ series_kinds = pytest.mark.parametrize('kind', sorted(SERIES_TYPES))
38
+
39
+ y_combinations = pytest.mark.parametrize(
40
+ 'y',
41
+ (
42
+ ['A', 'B', 'C', 'D'],
43
+ ('A', 'B', 'C', 'D'),
44
+ {'A', 'B', 'C', 'D'},
45
+ np.array(['A', 'B', 'C', 'D']),
46
+ pd.Index(['A', 'B', 'C', 'D']),
47
+ pd.Series(['A', 'B', 'C', 'D']),
48
+ ),
49
+ ids=lambda x: type(x).__name__,
50
+ )
51
+
52
+
53
+ @frame_kinds
54
+ @y_combinations
55
+ def test_dataframe_pandas(kind, y):
56
+ df = makeDataFrame()
57
+ df.hvplot(y=y, kind=kind)
58
+
59
+
60
+ @series_kinds
61
+ def test_series_pandas(kind):
62
+ ser = pd.Series(np.random.rand(10), name='A')
63
+ ser.hvplot(kind=kind)
64
+
65
+
66
+ @pytest.mark.skipif(dd is None, reason='dask not installed')
67
+ @frame_kinds
68
+ @y_combinations
69
+ def test_dataframe_dask(kind, y):
70
+ df = dd.from_pandas(makeDataFrame(), npartitions=2)
71
+ assert isinstance(df, dd.DataFrame)
72
+ df.hvplot(y=y, kind=kind)
73
+
74
+
75
+ @pytest.mark.skipif(dd is None, reason='dask not installed')
76
+ @series_kinds
77
+ def test_series_dask(kind):
78
+ ser = dd.from_pandas(pd.Series(np.random.rand(10), name='A'), npartitions=2)
79
+ assert isinstance(ser, dd.Series)
80
+ ser.hvplot(kind=kind)
81
+
82
+
83
+ @pytest.mark.skipif(skip_polar, reason='polars not installed')
84
+ @pytest.mark.parametrize('cast', (pl.DataFrame, pl.LazyFrame))
85
+ @frame_kinds
86
+ @y_combinations
87
+ def test_dataframe_polars(kind, y, cast):
88
+ df = cast(makeDataFrame())
89
+ assert isinstance(df, cast)
90
+ df.hvplot(y=y, kind=kind)
91
+
92
+
93
+ @pytest.mark.skipif(skip_polar, reason='polars not installed')
94
+ @series_kinds
95
+ def test_series_polars(kind):
96
+ ser = pl.Series(values=np.random.rand(10), name='A')
97
+ assert isinstance(ser, pl.Series)
98
+ ser.hvplot(kind=kind)
99
+
100
+
101
+ @pytest.mark.skipif(skip_polar, reason='polars not installed')
102
+ @series_kinds
103
+ def test_series_polars_downstream(kind):
104
+ if Version(pl.__version__) < Version('0.20.3'):
105
+ raise SkipTest('plot namespace in Polars introduced in 0.20.3')
106
+ ser = pl.Series(values=np.random.rand(10), name='A')
107
+ assert isinstance(ser, pl.Series)
108
+ ser.plot(kind=kind)
@@ -0,0 +1,34 @@
1
+ import pandas as pd
2
+ import hvplot.pandas # noqa
3
+
4
+
5
+ df = pd.DataFrame(
6
+ {
7
+ 'Open': [100.00, 101.25, 102.75],
8
+ 'High': [104.10, 105.50, 110.00],
9
+ 'Low': [94.00, 97.10, 99.20],
10
+ 'Close': [101.15, 99.70, 109.50],
11
+ 'Volume': [10012, 5000, 18000],
12
+ },
13
+ index=[pd.Timestamp('2022-08-01'), pd.Timestamp('2022-08-03'), pd.Timestamp('2022-08-04')],
14
+ )
15
+
16
+ ohlc_cols = ['Open', 'High', 'Low', 'Close']
17
+
18
+
19
+ def test_ohlc_hover_cols():
20
+ plot = df.hvplot.ohlc(y=ohlc_cols, hover_cols=['Volume'])
21
+ segments = plot.Segments.I
22
+ assert 'Volume' in segments
23
+ tooltips = segments.opts.get('plot').kwargs['tools'][0].tooltips
24
+ assert len(tooltips) == len(df.columns) + 1
25
+ assert tooltips[-1] == ('Volume', '@Volume')
26
+
27
+
28
+ def test_ohlc_hover_cols_all():
29
+ plot = df.hvplot.ohlc(y=ohlc_cols, hover_cols='all')
30
+ segments = plot.Segments.I
31
+ assert 'Volume' in segments
32
+ tooltips = segments.opts.get('plot').kwargs['tools'][0].tooltips
33
+ assert len(tooltips) == len(df.columns) + 1
34
+ assert tooltips[-1] == ('Volume', '@Volume')