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.
- hvplot/__init__.py +322 -0
- hvplot/_version.py +16 -0
- hvplot/backend_transforms.py +329 -0
- hvplot/converter.py +2855 -0
- hvplot/cudf.py +26 -0
- hvplot/dask.py +42 -0
- hvplot/data/crime.csv +56 -0
- hvplot/datasets.yaml +48 -0
- hvplot/fugue.py +64 -0
- hvplot/ibis.py +21 -0
- hvplot/intake.py +32 -0
- hvplot/interactive.py +968 -0
- hvplot/networkx.py +625 -0
- hvplot/pandas.py +30 -0
- hvplot/plotting/__init__.py +63 -0
- hvplot/plotting/andrews_curves.py +99 -0
- hvplot/plotting/core.py +2288 -0
- hvplot/plotting/lag_plot.py +34 -0
- hvplot/plotting/parallel_coordinates.py +85 -0
- hvplot/plotting/scatter_matrix.py +220 -0
- hvplot/polars.py +21 -0
- hvplot/sample_data.py +30 -0
- hvplot/streamz.py +21 -0
- hvplot/tests/__init__.py +0 -0
- hvplot/tests/conftest.py +44 -0
- hvplot/tests/data/README.md +5 -0
- hvplot/tests/data/RGB-red.byte.tif +0 -0
- hvplot/tests/plotting/__init__.py +0 -0
- hvplot/tests/plotting/testcore.py +108 -0
- hvplot/tests/plotting/testohlc.py +34 -0
- hvplot/tests/plotting/testscattermatrix.py +138 -0
- hvplot/tests/test_links.py +99 -0
- hvplot/tests/testbackend_transforms.py +89 -0
- hvplot/tests/testcharts.py +452 -0
- hvplot/tests/testfugue.py +46 -0
- hvplot/tests/testgeo.py +468 -0
- hvplot/tests/testgeowithoutgv.py +60 -0
- hvplot/tests/testgridplots.py +259 -0
- hvplot/tests/testhelp.py +75 -0
- hvplot/tests/testibis.py +17 -0
- hvplot/tests/testinteractive.py +1442 -0
- hvplot/tests/testnetworkx.py +26 -0
- hvplot/tests/testoperations.py +385 -0
- hvplot/tests/testoptions.py +596 -0
- hvplot/tests/testoverrides.py +74 -0
- hvplot/tests/testpanel.py +70 -0
- hvplot/tests/testpatch.py +135 -0
- hvplot/tests/testplotting.py +69 -0
- hvplot/tests/teststreaming.py +28 -0
- hvplot/tests/testtransforms.py +39 -0
- hvplot/tests/testui.py +383 -0
- hvplot/tests/testutil.py +378 -0
- hvplot/tests/util.py +82 -0
- hvplot/ui.py +1032 -0
- hvplot/util.py +677 -0
- hvplot/utilities.py +129 -0
- hvplot/xarray.py +62 -0
- hvplot-0.9.3a1.dist-info/LICENSE +29 -0
- hvplot-0.9.3a1.dist-info/METADATA +243 -0
- hvplot-0.9.3a1.dist-info/RECORD +63 -0
- hvplot-0.9.3a1.dist-info/WHEEL +5 -0
- hvplot-0.9.3a1.dist-info/entry_points.txt +2 -0
- hvplot-0.9.3a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from unittest import TestCase, SkipTest
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
import numpy as np
|
|
5
|
+
import networkx as nx
|
|
6
|
+
import hvplot.networkx as hvnx
|
|
7
|
+
except ImportError:
|
|
8
|
+
raise SkipTest('NetworkX not available')
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestOptions(TestCase):
|
|
12
|
+
def setUp(self):
|
|
13
|
+
# Create nodes (1-10) in unsorted order
|
|
14
|
+
nodes = np.array([1, 4, 5, 10, 8, 9, 3, 7, 2, 6])
|
|
15
|
+
edges = list(zip(nodes[:-1], nodes[1:]))
|
|
16
|
+
|
|
17
|
+
g = nx.Graph()
|
|
18
|
+
g.add_nodes_from(nodes)
|
|
19
|
+
g.add_edges_from(edges)
|
|
20
|
+
|
|
21
|
+
self.nodes = nodes
|
|
22
|
+
self.g = g
|
|
23
|
+
|
|
24
|
+
def test_nodes_are_not_sorted(self):
|
|
25
|
+
plot = hvnx.draw(self.g)
|
|
26
|
+
assert all(self.nodes == plot.nodes.dimension_values(2))
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from unittest import SkipTest
|
|
4
|
+
from parameterized import parameterized
|
|
5
|
+
|
|
6
|
+
import holoviews as hv
|
|
7
|
+
import hvplot.pandas # noqa
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from holoviews import Store, render
|
|
13
|
+
from holoviews.element import Image, QuadMesh, Points
|
|
14
|
+
from holoviews.core.spaces import DynamicMap
|
|
15
|
+
from holoviews.core.overlay import Overlay
|
|
16
|
+
from holoviews.element.chart import Scatter
|
|
17
|
+
from holoviews.element.comparison import ComparisonTestCase
|
|
18
|
+
from hvplot.converter import HoloViewsConverter
|
|
19
|
+
from hvplot.tests.util import makeTimeDataFrame
|
|
20
|
+
from packaging.version import Version
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TestDatashader(ComparisonTestCase):
|
|
24
|
+
def setUp(self):
|
|
25
|
+
try:
|
|
26
|
+
import datashader # noqa
|
|
27
|
+
except ImportError:
|
|
28
|
+
raise SkipTest('Datashader not available')
|
|
29
|
+
if sys.maxsize < 2**32:
|
|
30
|
+
raise SkipTest('Datashader does not support 32-bit systems')
|
|
31
|
+
import hvplot.pandas # noqa
|
|
32
|
+
|
|
33
|
+
self.df = pd.DataFrame(
|
|
34
|
+
[[1, 2, 'A', 0.1], [3, 4, 'B', 0.2], [5, 6, 'C', 0.3]],
|
|
35
|
+
columns=['x', 'y', 'category', 'number'],
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def test_rasterize_by_cat(self):
|
|
39
|
+
from datashader.reductions import count_cat
|
|
40
|
+
|
|
41
|
+
dmap = self.df.hvplot.scatter('x', 'y', by='category', rasterize=True)
|
|
42
|
+
agg = dmap.callback.inputs[0].callback.operation.p.aggregator
|
|
43
|
+
self.assertIsInstance(agg, count_cat)
|
|
44
|
+
self.assertEqual(agg.column, 'category')
|
|
45
|
+
|
|
46
|
+
def test_rasterize_by_cat_agg(self):
|
|
47
|
+
from datashader.reductions import count_cat
|
|
48
|
+
|
|
49
|
+
dmap = self.df.hvplot.scatter('x', 'y', aggregator=count_cat('category'), rasterize=True)
|
|
50
|
+
agg = dmap.callback.inputs[0].callback.operation.p.aggregator
|
|
51
|
+
self.assertIsInstance(agg, count_cat)
|
|
52
|
+
self.assertEqual(agg.column, 'category')
|
|
53
|
+
|
|
54
|
+
@parameterized.expand([('rasterize',), ('datashade',)])
|
|
55
|
+
def test_color_dim_with_default_agg(self, operation):
|
|
56
|
+
from datashader.reductions import mean
|
|
57
|
+
|
|
58
|
+
dmap = self.df.hvplot.scatter('x', 'y', c='number', **{operation: True})
|
|
59
|
+
agg = dmap.callback.inputs[0].callback.operation.p.aggregator
|
|
60
|
+
self.assertIsInstance(agg, mean)
|
|
61
|
+
self.assertEqual(agg.column, 'number')
|
|
62
|
+
|
|
63
|
+
@parameterized.expand([('rasterize',), ('datashade',)])
|
|
64
|
+
def test_color_dim_with_string_agg(self, operation):
|
|
65
|
+
from datashader.reductions import sum
|
|
66
|
+
|
|
67
|
+
dmap = self.df.hvplot.scatter('x', 'y', c='number', aggregator='sum', **{operation: True})
|
|
68
|
+
agg = dmap.callback.inputs[0].callback.operation.p.aggregator
|
|
69
|
+
self.assertIsInstance(agg, sum)
|
|
70
|
+
self.assertEqual(agg.column, 'number')
|
|
71
|
+
|
|
72
|
+
@parameterized.expand([('rasterize',), ('datashade',)])
|
|
73
|
+
def test_color_dim_also_an_axis(self, operation):
|
|
74
|
+
from datashader.reductions import mean
|
|
75
|
+
|
|
76
|
+
original_data = self.df.copy(deep=True)
|
|
77
|
+
dmap = self.df.hvplot.scatter('x', 'y', c='y', **{operation: True})
|
|
78
|
+
agg = dmap.callback.inputs[0].callback.operation.p.aggregator
|
|
79
|
+
self.assertIsInstance(agg, mean)
|
|
80
|
+
self.assertEqual(agg.column, '_color')
|
|
81
|
+
assert original_data.equals(self.df)
|
|
82
|
+
|
|
83
|
+
def test_rasterize_color_dim_with_new_column_gets_default_cmap(self):
|
|
84
|
+
plot = self.df.hvplot.scatter('x', 'y', c='y', dynamic=False, rasterize=True)
|
|
85
|
+
opts = Store.lookup_options('bokeh', plot, 'style').kwargs
|
|
86
|
+
self.assertEqual(opts.get('cmap'), 'kbc_r')
|
|
87
|
+
|
|
88
|
+
def test_rasterize_default_cmap(self):
|
|
89
|
+
plot = self.df.hvplot.scatter('x', 'y', dynamic=False, rasterize=True)
|
|
90
|
+
opts = Store.lookup_options('bokeh', plot, 'style').kwargs
|
|
91
|
+
self.assertEqual(opts.get('cmap'), 'kbc_r')
|
|
92
|
+
|
|
93
|
+
def test_rasterize_default_colorbar(self):
|
|
94
|
+
plot = self.df.hvplot.scatter('x', 'y', dynamic=False, rasterize=True)
|
|
95
|
+
opts = Store.lookup_options('bokeh', plot, 'plot').kwargs
|
|
96
|
+
self.assertTrue(opts.get('colorbar'))
|
|
97
|
+
|
|
98
|
+
def test_rasterize_default_colorbar_with_cmap(self):
|
|
99
|
+
cmap = 'Reds'
|
|
100
|
+
plot = self.df.hvplot.scatter('x', 'y', dynamic=False, rasterize=True, cmap=cmap)
|
|
101
|
+
opts = Store.lookup_options('bokeh', plot, 'style').kwargs
|
|
102
|
+
self.assertEqual(opts.get('cmap'), cmap)
|
|
103
|
+
opts = Store.lookup_options('bokeh', plot, 'plot').kwargs
|
|
104
|
+
self.assertTrue(opts.get('colorbar'))
|
|
105
|
+
|
|
106
|
+
def test_rasterize_set_clim(self):
|
|
107
|
+
plot = self.df.hvplot.scatter('x', 'y', dynamic=False, rasterize=True, clim=(1, 4))
|
|
108
|
+
opts = Store.lookup_options('bokeh', plot, 'plot').kwargs
|
|
109
|
+
self.assertEqual(opts.get('clim'), (1, 4))
|
|
110
|
+
|
|
111
|
+
@parameterized.expand([('aspect',), ('data_aspect',)])
|
|
112
|
+
def test_aspect_with_datashade(self, opt):
|
|
113
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True, **{opt: 2})
|
|
114
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
115
|
+
self.assertEqual(opts[opt], 2)
|
|
116
|
+
self.assertEqual(opts.get('height'), None)
|
|
117
|
+
self.assertEqual(opts.get('frame_height'), None)
|
|
118
|
+
|
|
119
|
+
@parameterized.expand([('aspect',), ('data_aspect',)])
|
|
120
|
+
def test_aspect_with_datashade_and_dynamic_is_false(self, opt):
|
|
121
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True, dynamic=False, **{opt: 2})
|
|
122
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
123
|
+
self.assertEqual(opts[opt], 2)
|
|
124
|
+
self.assertEqual(opts.get('height'), None)
|
|
125
|
+
self.assertEqual(opts.get('frame_height'), None)
|
|
126
|
+
|
|
127
|
+
@parameterized.expand([('aspect',), ('data_aspect',)])
|
|
128
|
+
def test_aspect_and_frame_height_with_datashade(self, opt):
|
|
129
|
+
plot = self.df.hvplot(x='x', y='y', frame_height=150, datashade=True, **{opt: 2})
|
|
130
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
131
|
+
self.assertEqual(opts[opt], 2)
|
|
132
|
+
self.assertEqual(opts.get('frame_height'), 150)
|
|
133
|
+
self.assertEqual(opts.get('height'), None)
|
|
134
|
+
self.assertEqual(opts.get('frame_width'), None)
|
|
135
|
+
|
|
136
|
+
@parameterized.expand([('aspect',), ('data_aspect',)])
|
|
137
|
+
def test_aspect_and_frame_height_with_datashade_and_dynamic_is_false(self, opt):
|
|
138
|
+
plot = self.df.hvplot(
|
|
139
|
+
x='x', y='y', frame_height=150, datashade=True, dynamic=False, **{opt: 2}
|
|
140
|
+
)
|
|
141
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
142
|
+
self.assertEqual(opts[opt], 2)
|
|
143
|
+
self.assertEqual(opts.get('frame_height'), 150)
|
|
144
|
+
self.assertEqual(opts.get('height'), None)
|
|
145
|
+
self.assertEqual(opts.get('frame_width'), None)
|
|
146
|
+
|
|
147
|
+
def test_cmap_can_be_color_key(self):
|
|
148
|
+
color_key = {'A': '#ff0000', 'B': '#00ff00', 'C': '#0000ff'}
|
|
149
|
+
self.df.hvplot.points(x='x', y='y', by='category', cmap=color_key, datashade=True)
|
|
150
|
+
with self.assertRaises(TypeError):
|
|
151
|
+
self.df.hvplot.points(
|
|
152
|
+
x='x', y='y', by='category', datashade=True, cmap='kbc_r', color_key=color_key
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def test_when_datashade_is_true_set_hover_to_false_by_default(self):
|
|
156
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True)
|
|
157
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
158
|
+
assert 'hover' not in opts.get('tools')
|
|
159
|
+
|
|
160
|
+
def test_when_datashade_is_true_hover_can_still_be_true(self):
|
|
161
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True, hover=True)
|
|
162
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
163
|
+
assert 'hover' in opts.get('tools')
|
|
164
|
+
|
|
165
|
+
def test_xlim_affects_x_range(self):
|
|
166
|
+
data = pd.DataFrame(np.random.randn(100).cumsum())
|
|
167
|
+
img = data.hvplot(xlim=(0, 20000), datashade=True, dynamic=False)
|
|
168
|
+
assert img.range(0) == (0, 20000)
|
|
169
|
+
|
|
170
|
+
@parameterized.expand([('scatter',), ('line',), ('area',)])
|
|
171
|
+
def test_wide_charts_categorically_shaded_explicit_ys(self, kind):
|
|
172
|
+
df = makeTimeDataFrame()
|
|
173
|
+
plot = makeTimeDataFrame().hvplot(y=list(df.columns), datashade=True, kind=kind)
|
|
174
|
+
expected_cmap = HoloViewsConverter._default_cmaps['categorical']
|
|
175
|
+
assert plot.callback.inputs[0].callback.operation.p.cmap == expected_cmap
|
|
176
|
+
assert plot.callback.inputs[0].callback.operation.p.aggregator.column == 'Variable'
|
|
177
|
+
|
|
178
|
+
@parameterized.expand([('scatter',), ('line',), ('area',)])
|
|
179
|
+
def test_wide_charts_categorically_shaded_implicit_ys(self, kind):
|
|
180
|
+
plot = makeTimeDataFrame().hvplot(datashade=True, kind=kind)
|
|
181
|
+
expected_cmap = HoloViewsConverter._default_cmaps['categorical']
|
|
182
|
+
assert plot.callback.inputs[0].callback.operation.p.cmap == expected_cmap
|
|
183
|
+
assert plot.callback.inputs[0].callback.operation.p.aggregator.column == 'Variable'
|
|
184
|
+
|
|
185
|
+
def test_tidy_charts_categorically_datashade_by(self):
|
|
186
|
+
cat_col = 'category'
|
|
187
|
+
plot = self.df.hvplot.scatter('x', 'y', by=cat_col, datashade=True)
|
|
188
|
+
expected_cmap = HoloViewsConverter._default_cmaps['categorical']
|
|
189
|
+
assert plot.callback.inputs[0].callback.operation.p.cmap == expected_cmap
|
|
190
|
+
assert plot.callback.inputs[0].callback.operation.p.aggregator.column == cat_col
|
|
191
|
+
|
|
192
|
+
@pytest.mark.xfail(
|
|
193
|
+
reason='Assume this is fixed: https://github.com/holoviz/holoviews/issues/6187'
|
|
194
|
+
)
|
|
195
|
+
def test_tidy_charts_categorically_rasterized_by(self):
|
|
196
|
+
cat_col = 'category'
|
|
197
|
+
plot = self.df.hvplot.scatter('x', 'y', by=cat_col, rasterize=True)
|
|
198
|
+
expected_cmap = HoloViewsConverter._default_cmaps['categorical']
|
|
199
|
+
opts = Store.lookup_options('bokeh', plot[()], 'style').kwargs
|
|
200
|
+
# Failing line
|
|
201
|
+
assert opts.get('cmap') == expected_cmap
|
|
202
|
+
|
|
203
|
+
assert plot.callback.inputs[0].callback.operation.p.aggregator.column == cat_col
|
|
204
|
+
|
|
205
|
+
def test_tidy_charts_categorically_rasterized_aggregator_count_cat(self):
|
|
206
|
+
cat_col = 'category'
|
|
207
|
+
from datashader.reductions import count_cat
|
|
208
|
+
|
|
209
|
+
plot = self.df.hvplot.scatter('x', 'y', aggregator=count_cat(cat_col), rasterize=True)
|
|
210
|
+
expected_cmap = HoloViewsConverter._default_cmaps['categorical']
|
|
211
|
+
opts = Store.lookup_options('bokeh', plot[()], 'style').kwargs
|
|
212
|
+
assert opts.get('cmap') == expected_cmap
|
|
213
|
+
assert plot.callback.inputs[0].callback.operation.p.aggregator.column == cat_col
|
|
214
|
+
|
|
215
|
+
def test_rasterize_cnorm(self):
|
|
216
|
+
expected = 'eq_hist'
|
|
217
|
+
plot = self.df.hvplot(x='x', y='y', rasterize=True, cnorm=expected)
|
|
218
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
219
|
+
assert opts.get('cnorm') == expected
|
|
220
|
+
|
|
221
|
+
def test_datashade_cnorm(self):
|
|
222
|
+
expected = 'eq_hist'
|
|
223
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True, cnorm=expected)
|
|
224
|
+
actual = plot.callback.inputs[0].callback.operation.p['cnorm']
|
|
225
|
+
assert actual == expected
|
|
226
|
+
|
|
227
|
+
def test_rasterize_rescale_discrete_levels(self):
|
|
228
|
+
expected = False
|
|
229
|
+
plot = self.df.hvplot(
|
|
230
|
+
x='x', y='y', rasterize=True, cnorm='eq_hist', rescale_discrete_levels=expected
|
|
231
|
+
)
|
|
232
|
+
opts = Store.lookup_options('bokeh', plot[()], 'plot').kwargs
|
|
233
|
+
assert opts.get('rescale_discrete_levels') is expected
|
|
234
|
+
|
|
235
|
+
def test_datashade_rescale_discrete_levels(self):
|
|
236
|
+
expected = False
|
|
237
|
+
plot = self.df.hvplot(
|
|
238
|
+
x='x', y='y', datashade=True, cnorm='eq_hist', rescale_discrete_levels=expected
|
|
239
|
+
)
|
|
240
|
+
actual = plot.callback.inputs[0].callback.operation.p['rescale_discrete_levels']
|
|
241
|
+
assert actual is expected
|
|
242
|
+
|
|
243
|
+
def test_datashade_rescale_discrete_levels_default_True(self):
|
|
244
|
+
expected = True
|
|
245
|
+
plot = self.df.hvplot(x='x', y='y', datashade=True, cnorm='eq_hist')
|
|
246
|
+
actual = plot.callback.inputs[0].callback.operation.p['rescale_discrete_levels']
|
|
247
|
+
assert actual is expected
|
|
248
|
+
|
|
249
|
+
def test_rasterize_by(self):
|
|
250
|
+
if Version(hv.__version__) < Version('1.18.0a1'):
|
|
251
|
+
raise SkipTest('hv.ImageStack introduced after 1.18.0a1')
|
|
252
|
+
|
|
253
|
+
from holoviews.element import ImageStack
|
|
254
|
+
|
|
255
|
+
expected = 'category'
|
|
256
|
+
plot = self.df.hvplot(x='x', y='y', by=expected, rasterize=True, dynamic=False)
|
|
257
|
+
assert isinstance(plot, ImageStack)
|
|
258
|
+
assert plot.opts['cmap'] == HoloViewsConverter._default_cmaps['categorical']
|
|
259
|
+
|
|
260
|
+
def test_rasterize_aggregator_count_cat(self):
|
|
261
|
+
if Version(hv.__version__) < Version('1.18.0a1'):
|
|
262
|
+
raise SkipTest('hv.ImageStack introduced after 1.18.0a1')
|
|
263
|
+
|
|
264
|
+
from holoviews.element import ImageStack
|
|
265
|
+
from datashader.reductions import count_cat
|
|
266
|
+
|
|
267
|
+
expected = 'category'
|
|
268
|
+
plot = self.df.hvplot(
|
|
269
|
+
x='x', y='y', aggregator=count_cat(expected), rasterize=True, width=999, dynamic=False
|
|
270
|
+
)
|
|
271
|
+
assert isinstance(plot, ImageStack)
|
|
272
|
+
assert plot.opts['width'] == 999
|
|
273
|
+
assert plot.opts['cmap'] == HoloViewsConverter._default_cmaps['categorical']
|
|
274
|
+
|
|
275
|
+
def test_rasterize_single_y_in_list_linear_cmap(self):
|
|
276
|
+
# Regression, see https://github.com/holoviz/hvplot/issues/1210
|
|
277
|
+
plot = self.df.hvplot.line(y=['y'], rasterize=True)
|
|
278
|
+
opts = Store.lookup_options('bokeh', plot[()], 'style').kwargs
|
|
279
|
+
assert opts.get('cmap') == 'kbc_r'
|
|
280
|
+
|
|
281
|
+
def test_resample_when_error_unset_operation(self):
|
|
282
|
+
with pytest.raises(ValueError, match='At least one resampling operation'):
|
|
283
|
+
self.df.hvplot(x='x', y='y', resample_when=10)
|
|
284
|
+
|
|
285
|
+
@parameterized.expand([('rasterize',), ('datashade',)])
|
|
286
|
+
def test_operation_resample_when(self, operation):
|
|
287
|
+
df = pd.DataFrame(
|
|
288
|
+
np.random.multivariate_normal((0, 0), [[0.1, 0.1], [0.1, 1.0]], (5000,))
|
|
289
|
+
).rename({0: 'x', 1: 'y'}, axis=1)
|
|
290
|
+
dmap = df.hvplot.scatter('x', 'y', resample_when=1000, **{operation: True})
|
|
291
|
+
assert isinstance(dmap, DynamicMap)
|
|
292
|
+
|
|
293
|
+
render(dmap) # trigger dynamicmap
|
|
294
|
+
overlay = dmap.items()[0][1]
|
|
295
|
+
assert isinstance(overlay, Overlay)
|
|
296
|
+
|
|
297
|
+
image = overlay.get(0)
|
|
298
|
+
assert isinstance(image, Image)
|
|
299
|
+
assert len(image.data) > 0
|
|
300
|
+
|
|
301
|
+
scatter = overlay.get(1)
|
|
302
|
+
assert isinstance(scatter, Scatter)
|
|
303
|
+
assert len(scatter.data) == 0
|
|
304
|
+
|
|
305
|
+
@parameterized.expand([('points', Points), ('scatter', Scatter)])
|
|
306
|
+
def test_downsample_resample_when(self, kind, eltype):
|
|
307
|
+
df = pd.DataFrame(
|
|
308
|
+
np.random.multivariate_normal((0, 0), [[0.1, 0.1], [0.1, 1.0]], (5000,))
|
|
309
|
+
).rename({0: 'x', 1: 'y'}, axis=1)
|
|
310
|
+
dmap = df.hvplot(kind=kind, x='x', y='y', resample_when=1000, downsample=True)
|
|
311
|
+
assert isinstance(dmap, DynamicMap)
|
|
312
|
+
|
|
313
|
+
render(dmap) # trigger dynamicmap
|
|
314
|
+
overlay = dmap.items()[0][1]
|
|
315
|
+
assert isinstance(overlay, Overlay)
|
|
316
|
+
|
|
317
|
+
downsampled = overlay.get(0)
|
|
318
|
+
assert isinstance(downsampled, eltype)
|
|
319
|
+
assert len(downsampled) > 0
|
|
320
|
+
|
|
321
|
+
element = overlay.get(1)
|
|
322
|
+
assert isinstance(element, eltype)
|
|
323
|
+
assert len(element) == 0
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class TestChart2D(ComparisonTestCase):
|
|
327
|
+
def setUp(self):
|
|
328
|
+
try:
|
|
329
|
+
import xarray as xr
|
|
330
|
+
import datashader as ds # noqa
|
|
331
|
+
except ImportError:
|
|
332
|
+
raise SkipTest('xarray or datashader not available')
|
|
333
|
+
if sys.maxsize < 2**32:
|
|
334
|
+
raise SkipTest('Datashader does not support 32-bit systems')
|
|
335
|
+
import hvplot.xarray # noqa
|
|
336
|
+
|
|
337
|
+
data = np.arange(0, 60).reshape(6, 10)
|
|
338
|
+
x = np.arange(10)
|
|
339
|
+
y = np.arange(6)
|
|
340
|
+
self.da = xr.DataArray(data, coords={'y': y, 'x': x}, dims=('y', 'x'))
|
|
341
|
+
|
|
342
|
+
@parameterized.expand([('image', Image), ('quadmesh', QuadMesh)])
|
|
343
|
+
def test_plot_resolution(self, kind, element):
|
|
344
|
+
plot = self.da.hvplot(kind=kind)
|
|
345
|
+
assert all(plot.data.x.diff('x').round(0) == 1)
|
|
346
|
+
assert all(plot.data.y.diff('y').round(0) == 1)
|
|
347
|
+
|
|
348
|
+
@parameterized.expand([('image', Image), ('quadmesh', QuadMesh)])
|
|
349
|
+
def test_plot_resolution_with_rasterize(self, kind, element):
|
|
350
|
+
plot = self.da.hvplot(kind=kind, dynamic=False, rasterize=True, x_sampling=5, y_sampling=2)
|
|
351
|
+
assert all(plot.data.x.diff('x').round(0) == 5)
|
|
352
|
+
assert all(plot.data.y.diff('y').round(0) == 2)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class TestDownsample(ComparisonTestCase):
|
|
356
|
+
def setUp(self):
|
|
357
|
+
import hvplot.pandas # noqa
|
|
358
|
+
|
|
359
|
+
self.df = pd.DataFrame(np.random.random(100))
|
|
360
|
+
|
|
361
|
+
def test_downsample_default(self):
|
|
362
|
+
from holoviews.operation.downsample import downsample1d
|
|
363
|
+
|
|
364
|
+
plot = self.df.hvplot.line(downsample=True)
|
|
365
|
+
|
|
366
|
+
assert isinstance(plot.callback.operation, downsample1d)
|
|
367
|
+
assert plot.callback.operation.algorithm == 'lttb'
|
|
368
|
+
|
|
369
|
+
def test_downsample_opts(self):
|
|
370
|
+
plot = self.df.hvplot.line(
|
|
371
|
+
downsample=True, width=100, height=50, x_sampling=5, xlim=(0, 5)
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
assert plot.callback.operation.p.width == 100
|
|
375
|
+
assert plot.callback.operation.p.height == 50
|
|
376
|
+
assert plot.callback.operation.p.x_sampling == 5
|
|
377
|
+
assert plot.callback.operation.p.x_range == (0, 5)
|
|
378
|
+
|
|
379
|
+
def test_downsample_algorithm_minmax(self):
|
|
380
|
+
from holoviews.operation.downsample import downsample1d
|
|
381
|
+
|
|
382
|
+
plot = self.df.hvplot.line(downsample='minmax')
|
|
383
|
+
|
|
384
|
+
assert isinstance(plot.callback.operation, downsample1d)
|
|
385
|
+
assert plot.callback.operation_kwargs['algorithm'] == 'minmax'
|