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
hvplot/__init__.py
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""
|
|
2
|
+
hvPlot makes data analysis and visualization simple
|
|
3
|
+
===================================================
|
|
4
|
+
|
|
5
|
+
hvPlot provides a familiar, high-level API for interactive data exploration and visualization,
|
|
6
|
+
based on the Pandas `.plot` API and the innovative `.interactive` API.
|
|
7
|
+
|
|
8
|
+
hvPlot
|
|
9
|
+
|
|
10
|
+
- supports a wide range of data sources including Pandas, Dask, XArray
|
|
11
|
+
Rapids cuDF, Streamz, Intake, Geopandas, NetworkX and Ibis.
|
|
12
|
+
- supports the plotting backends Bokeh (default), Matplotlib and Plotly.
|
|
13
|
+
- exposes the powerful tools from the HoloViz ecosystem in a familiar and convenient API, while
|
|
14
|
+
letting you drop down into the underlying HoloViz tools when more power or flexibility is needed.
|
|
15
|
+
|
|
16
|
+
hvPlot is the recommend entrypoint to the HoloViz ecosystem.
|
|
17
|
+
|
|
18
|
+
To learn more check out https://hvplot.holoviz.org/. To report issues or contribute go to
|
|
19
|
+
https://github.com/holoviz/hvplot. To join the community go to
|
|
20
|
+
https://discourse.holoviz.org/.
|
|
21
|
+
|
|
22
|
+
How to use hvPlot in 3 simple steps
|
|
23
|
+
-----------------------------------
|
|
24
|
+
|
|
25
|
+
Work with the data source you already know and ❤️
|
|
26
|
+
|
|
27
|
+
>>> import pandas as pd, numpy as np
|
|
28
|
+
>>> idx = pd.date_range('1/1/2000', periods=1000)
|
|
29
|
+
>>> df = pd.DataFrame(np.random.randn(1000, 4), index=idx, columns=list('ABCD')).cumsum()
|
|
30
|
+
|
|
31
|
+
Import the hvplot extension for your data source and optionally set the plotting backend
|
|
32
|
+
|
|
33
|
+
>>> import hvplot.pandas
|
|
34
|
+
>>> # hvplot.extension('matplotlib')
|
|
35
|
+
|
|
36
|
+
Use the `.hvplot` API as you would use the Pandas `.plot` API.
|
|
37
|
+
|
|
38
|
+
>>> df.hvplot()
|
|
39
|
+
|
|
40
|
+
In a Jupyter Notebook, this will display a line plot of the A, B, C and D time series.
|
|
41
|
+
|
|
42
|
+
For more check out the user guide https://hvplot.holoviz.org/user_guide/index.html
|
|
43
|
+
|
|
44
|
+
How to get help
|
|
45
|
+
---------------
|
|
46
|
+
|
|
47
|
+
To see the available arguments for a specific `kind` of plot run
|
|
48
|
+
|
|
49
|
+
>>> import hvplot
|
|
50
|
+
>>> hvplot.help(kind='scatter')
|
|
51
|
+
|
|
52
|
+
In a notebook or ipython environment the usual
|
|
53
|
+
|
|
54
|
+
- `help` and `?` will provide you with documentation.
|
|
55
|
+
- `TAB` and `SHIFT+TAB` completion will help you navigate.
|
|
56
|
+
|
|
57
|
+
To ask the community go to https://discourse.holoviz.org/.
|
|
58
|
+
To report issues go to https://github.com/holoviz/holoviews.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
import inspect
|
|
62
|
+
import os
|
|
63
|
+
import textwrap
|
|
64
|
+
|
|
65
|
+
import panel as _pn
|
|
66
|
+
import holoviews as _hv
|
|
67
|
+
|
|
68
|
+
from holoviews import Store, render # noqa
|
|
69
|
+
|
|
70
|
+
from .converter import HoloViewsConverter
|
|
71
|
+
from .interactive import Interactive
|
|
72
|
+
from .ui import explorer # noqa
|
|
73
|
+
from .utilities import hvplot_extension, output, save, show # noqa
|
|
74
|
+
from .plotting import (
|
|
75
|
+
hvPlot,
|
|
76
|
+
hvPlotTabular, # noqa
|
|
77
|
+
andrews_curves, # noqa
|
|
78
|
+
lag_plot, # noqa
|
|
79
|
+
parallel_coordinates, # noqa
|
|
80
|
+
scatter_matrix, # noqa
|
|
81
|
+
plot, # noqa
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Define '__version__'
|
|
85
|
+
try:
|
|
86
|
+
# For performance reasons on imports, avoid importing setuptools_scm
|
|
87
|
+
# if not in a .git folder
|
|
88
|
+
if os.path.exists(os.path.join(os.path.dirname(__file__), '..', '.git')):
|
|
89
|
+
# If setuptools_scm is installed (e.g. in a development environment with
|
|
90
|
+
# an editable install), then use it to determine the version dynamically.
|
|
91
|
+
from setuptools_scm import get_version
|
|
92
|
+
|
|
93
|
+
# This will fail with LookupError if the package is not installed in
|
|
94
|
+
# editable mode or if Git is not installed.
|
|
95
|
+
__version__ = get_version(root='..', relative_to=__file__)
|
|
96
|
+
else:
|
|
97
|
+
raise FileNotFoundError
|
|
98
|
+
except (ImportError, LookupError, FileNotFoundError):
|
|
99
|
+
# As a fallback, use the version that is hard-coded in the file.
|
|
100
|
+
try:
|
|
101
|
+
# __version__ was added in _version in setuptools-scm 7.0.0, we rely on
|
|
102
|
+
# the hopefully stable version variable.
|
|
103
|
+
from ._version import version as __version__
|
|
104
|
+
except (ModuleNotFoundError, ImportError):
|
|
105
|
+
# Either _version doesn't exist (ModuleNotFoundError) or version isn't
|
|
106
|
+
# in _version (ImportError). ModuleNotFoundError is a subclass of
|
|
107
|
+
# ImportError, let's be explicit anyway.
|
|
108
|
+
|
|
109
|
+
# Try something else:
|
|
110
|
+
from importlib.metadata import version as mversion, PackageNotFoundError
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
__version__ = mversion('hvplot')
|
|
114
|
+
except PackageNotFoundError:
|
|
115
|
+
# The user is probably trying to run this without having installed
|
|
116
|
+
# the package.
|
|
117
|
+
__version__ = '0.0.0+unknown'
|
|
118
|
+
|
|
119
|
+
_METHOD_DOCS = {}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _get_doc_and_signature(
|
|
123
|
+
cls, kind, completions=False, docstring=True, generic=True, style=True, signature=None
|
|
124
|
+
):
|
|
125
|
+
converter = HoloViewsConverter
|
|
126
|
+
method = getattr(cls, kind)
|
|
127
|
+
kind_opts = converter._kind_options.get(kind, [])
|
|
128
|
+
eltype = converter._kind_mapping[kind]
|
|
129
|
+
|
|
130
|
+
formatter = ''
|
|
131
|
+
if completions:
|
|
132
|
+
formatter = 'hvplot.{kind}({completions})'
|
|
133
|
+
if docstring:
|
|
134
|
+
if formatter:
|
|
135
|
+
formatter += '\n'
|
|
136
|
+
formatter += '{docstring}'
|
|
137
|
+
if generic:
|
|
138
|
+
if formatter:
|
|
139
|
+
formatter += '\n'
|
|
140
|
+
formatter += '{options}'
|
|
141
|
+
|
|
142
|
+
# Bokeh is the default backend
|
|
143
|
+
backend = hvplot_extension.compatibility or Store.current_backend
|
|
144
|
+
if eltype in Store.registry[backend]:
|
|
145
|
+
valid_opts = Store.registry[backend][eltype].style_opts
|
|
146
|
+
if style:
|
|
147
|
+
formatter += '\n{style}'
|
|
148
|
+
else:
|
|
149
|
+
valid_opts = []
|
|
150
|
+
|
|
151
|
+
style_opts = 'Style options\n-------------\n\n' + '\n'.join(sorted(valid_opts))
|
|
152
|
+
|
|
153
|
+
parameters = []
|
|
154
|
+
extra_kwargs = _hv.core.util.unique_iterator(
|
|
155
|
+
valid_opts + kind_opts + converter._axis_options + converter._op_options
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
sig = signature or inspect.signature(method)
|
|
159
|
+
for name, p in list(sig.parameters.items())[1:]:
|
|
160
|
+
if p.kind == 1:
|
|
161
|
+
parameters.append((name, p.default))
|
|
162
|
+
|
|
163
|
+
filtered_signature = [
|
|
164
|
+
p for p in sig.parameters.values() if p.kind != inspect.Parameter.VAR_KEYWORD
|
|
165
|
+
]
|
|
166
|
+
extra_params = [
|
|
167
|
+
inspect.Parameter(k, inspect.Parameter.KEYWORD_ONLY)
|
|
168
|
+
for k in extra_kwargs
|
|
169
|
+
if k not in [p.name for p in filtered_signature]
|
|
170
|
+
]
|
|
171
|
+
all_params = (
|
|
172
|
+
filtered_signature
|
|
173
|
+
+ extra_params
|
|
174
|
+
+ [inspect.Parameter('kwargs', inspect.Parameter.VAR_KEYWORD)]
|
|
175
|
+
)
|
|
176
|
+
signature = inspect.Signature(all_params)
|
|
177
|
+
|
|
178
|
+
parameters += [(o, None) for o in extra_kwargs]
|
|
179
|
+
completions = ', '.join([f'{n}={v}' for n, v in parameters])
|
|
180
|
+
options = textwrap.dedent(converter.__doc__)
|
|
181
|
+
method_doc = _METHOD_DOCS.get(kind, method.__doc__)
|
|
182
|
+
_METHOD_DOCS[kind] = method_doc
|
|
183
|
+
docstring = formatter.format(
|
|
184
|
+
kind=kind,
|
|
185
|
+
completions=completions,
|
|
186
|
+
docstring=textwrap.dedent(method_doc),
|
|
187
|
+
options=options,
|
|
188
|
+
style=style_opts,
|
|
189
|
+
)
|
|
190
|
+
return docstring, signature
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def help(kind=None, docstring=True, generic=True, style=True):
|
|
194
|
+
"""
|
|
195
|
+
Provide a docstring with all valid options which apply to the plot
|
|
196
|
+
type.
|
|
197
|
+
|
|
198
|
+
Parameters
|
|
199
|
+
----------
|
|
200
|
+
kind: str
|
|
201
|
+
The kind of plot to provide help for
|
|
202
|
+
docstring: boolean (default=True)
|
|
203
|
+
Whether to display the docstring
|
|
204
|
+
generic: boolean (default=True)
|
|
205
|
+
Whether to provide list of generic options
|
|
206
|
+
style: boolean (default=True)
|
|
207
|
+
Whether to provide list of style options
|
|
208
|
+
"""
|
|
209
|
+
doc, sig = _get_doc_and_signature(
|
|
210
|
+
cls=hvPlot, kind=kind, docstring=docstring, generic=generic, style=style
|
|
211
|
+
)
|
|
212
|
+
print(doc)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def post_patch(extension='bokeh', logo=False):
|
|
216
|
+
if extension and not getattr(_hv.extension, '_loaded', False):
|
|
217
|
+
hvplot_extension(extension, logo=logo)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _patch_doc(cls, kind, signature=None):
|
|
221
|
+
method = getattr(cls, kind)
|
|
222
|
+
docstring, signature = _get_doc_and_signature(cls, kind, False, signature=signature)
|
|
223
|
+
method.__doc__ = docstring
|
|
224
|
+
method.__signature__ = signature
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class _PatchHvplotDocstrings:
|
|
228
|
+
def __init__(self):
|
|
229
|
+
# Store the original signatures because the method signatures
|
|
230
|
+
# are going to be patched every time an extension is changed.
|
|
231
|
+
signatures = {}
|
|
232
|
+
for cls in [hvPlot, hvPlotTabular]:
|
|
233
|
+
for _kind in HoloViewsConverter._kind_mapping:
|
|
234
|
+
if hasattr(cls, _kind):
|
|
235
|
+
method = getattr(cls, _kind)
|
|
236
|
+
sig = inspect.signature(method)
|
|
237
|
+
signatures[(cls, _kind)] = sig
|
|
238
|
+
self.orig_signatures = signatures
|
|
239
|
+
|
|
240
|
+
def __call__(self):
|
|
241
|
+
for cls in [hvPlot, hvPlotTabular]:
|
|
242
|
+
for _kind in HoloViewsConverter._kind_mapping:
|
|
243
|
+
if hasattr(cls, _kind):
|
|
244
|
+
signature = self.orig_signatures[(cls, _kind)]
|
|
245
|
+
_patch_doc(cls, _kind, signature=signature)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
_patch_hvplot_docstrings = _PatchHvplotDocstrings()
|
|
249
|
+
_patch_hvplot_docstrings()
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _hook_patch_docstrings(backend):
|
|
253
|
+
# Patch or re-patch the docstrings/signatures to display
|
|
254
|
+
# the right styling options.
|
|
255
|
+
from . import _patch_hvplot_docstrings
|
|
256
|
+
|
|
257
|
+
_patch_hvplot_docstrings()
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
Store._backend_switch_hooks.append(_hook_patch_docstrings)
|
|
261
|
+
|
|
262
|
+
extension = hvplot_extension
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def bind(function, *args, **kwargs):
|
|
266
|
+
"""
|
|
267
|
+
Returns a *reactive* function that can be used to start your `.interactive` pipeline by running
|
|
268
|
+
a model or loading data depending on inputs from widgets, parameters or python objects.
|
|
269
|
+
|
|
270
|
+
The widgets can be Panel or ipywidgets.
|
|
271
|
+
|
|
272
|
+
Reference: https://hvplot.holoviz.org/user_guide/Interactive.html#functions-as-inputs
|
|
273
|
+
|
|
274
|
+
Parameters
|
|
275
|
+
----------
|
|
276
|
+
function : callable
|
|
277
|
+
The function to bind constant or dynamic args and kwargs to.
|
|
278
|
+
args : object, param.Parameter, panel.widget.Widget, or ipywidget
|
|
279
|
+
Positional arguments to bind to the function.
|
|
280
|
+
kwargs : object, param.Parameter, panel.widget.Widget, or ipywidget
|
|
281
|
+
Keyword arguments to bind to the function.
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
Returns a new function with the args and kwargs bound to it and
|
|
286
|
+
annotated with all dependencies. This function has an `interactive`
|
|
287
|
+
attribute that can be called to instantiate an `Interactive` pipeline.
|
|
288
|
+
|
|
289
|
+
Examples
|
|
290
|
+
--------
|
|
291
|
+
|
|
292
|
+
Develop your **algorithm** or data extraction method with the tools you know and love.
|
|
293
|
+
|
|
294
|
+
>>> import pandas as pd
|
|
295
|
+
>>> import numpy as np
|
|
296
|
+
|
|
297
|
+
>>> def algorithm(alpha):
|
|
298
|
+
... # An example algorithm that uses alpha ...
|
|
299
|
+
... return pd.DataFrame({"output": (np.array(range(0,100)) ** alpha)*50})
|
|
300
|
+
|
|
301
|
+
Make it **interactive** using `.bind`, `.interactive` and widgets.
|
|
302
|
+
|
|
303
|
+
>>> import hvplot
|
|
304
|
+
>>> import panel as pn
|
|
305
|
+
|
|
306
|
+
>>> alpha = pn.widgets.FloatSlider(value=0.5, start=0, end=1.0, step=0.1, name="Alpha")
|
|
307
|
+
>>> top = pn.widgets.RadioButtonGroup(value=10, options=[5, 10, 25], name="Top")
|
|
308
|
+
>>> interactive_table = (
|
|
309
|
+
... hvplot
|
|
310
|
+
... .bind(algorithm, alpha=alpha)
|
|
311
|
+
... .interactive()
|
|
312
|
+
... .head(n=top)
|
|
313
|
+
... )
|
|
314
|
+
>>> interactive_table
|
|
315
|
+
|
|
316
|
+
In a notebook or data app you can now select the appropriate `alpha` and `top` values via
|
|
317
|
+
widgets and see the `top` results of the algorithm in a table depending on the value of `alpha`
|
|
318
|
+
selected.
|
|
319
|
+
"""
|
|
320
|
+
bound = _pn.bind(function, *args, **kwargs)
|
|
321
|
+
bound.interactive = lambda **kwargs: Interactive(bound, **kwargs)
|
|
322
|
+
return bound
|
hvplot/_version.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '0.9.3a1'
|
|
16
|
+
__version_tuple__ = version_tuple = (0, 9, 3)
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Set of transforms to go from a Bokeh option to another backend's option.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from holoviews.core.overlay import CompositeOverlay
|
|
6
|
+
from holoviews.core.options import Store
|
|
7
|
+
from holoviews.plotting.util import COLOR_ALIASES
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
UNSET = type('UNSET', (), {})
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _transform_size_to_mpl(width, height, aspect):
|
|
14
|
+
opts = {}
|
|
15
|
+
if width and height:
|
|
16
|
+
opts = {'aspect': width / height, 'fig_size': (width / 300.0) * 100}
|
|
17
|
+
elif aspect and width:
|
|
18
|
+
opts = {'aspect': aspect, 'fig_size': (width / 300.0) * 100}
|
|
19
|
+
elif aspect and height:
|
|
20
|
+
opts = {'aspect': aspect, 'fig_size': (height / 300.0) * 100}
|
|
21
|
+
elif width:
|
|
22
|
+
opts = {'fig_size': (width / 300.0) * 100}
|
|
23
|
+
elif height:
|
|
24
|
+
opts = {'fig_size': (height / 300.0) * 100}
|
|
25
|
+
return opts
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _transfer_opts(element, backend):
|
|
29
|
+
"""
|
|
30
|
+
Transfer the bokeh options of an element to another backend
|
|
31
|
+
based on an internal mapping of option transforms.
|
|
32
|
+
"""
|
|
33
|
+
elname = type(element).__name__
|
|
34
|
+
options = Store.options(backend=backend)
|
|
35
|
+
transforms = BACKEND_TRANSFORMS[backend]
|
|
36
|
+
if isinstance(element, CompositeOverlay):
|
|
37
|
+
element = element.apply(_transfer_opts, backend=backend, per_element=True)
|
|
38
|
+
new_opts = {}
|
|
39
|
+
el_options = element.opts.get(backend='bokeh', defaults=False).kwargs
|
|
40
|
+
for grp, el_opts in options[elname].groups.items():
|
|
41
|
+
for opt, val in el_options.items():
|
|
42
|
+
transform = transforms.get(grp, {}).get(opt, None)
|
|
43
|
+
# This condition could be applied to matplotlib only
|
|
44
|
+
# but is applied to plotly too since there seems to be
|
|
45
|
+
# no interactive options available like for the bokeh backend
|
|
46
|
+
if transform is None and _is_interactive_opt(opt):
|
|
47
|
+
transform = UNSET
|
|
48
|
+
if transform is UNSET:
|
|
49
|
+
continue
|
|
50
|
+
elif transform:
|
|
51
|
+
opt, val = transform(opt, val)
|
|
52
|
+
if val is UNSET:
|
|
53
|
+
continue
|
|
54
|
+
if opt not in el_opts.allowed_keywords:
|
|
55
|
+
continue
|
|
56
|
+
new_opts[opt] = val
|
|
57
|
+
if backend == 'matplotlib':
|
|
58
|
+
size_opts = _transform_size_to_mpl(
|
|
59
|
+
el_options.get('width'), el_options.get('height'), el_options.get('aspect')
|
|
60
|
+
)
|
|
61
|
+
new_opts.update(size_opts)
|
|
62
|
+
return element.opts(**new_opts, backend=backend)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _is_interactive_opt(bk_opt):
|
|
66
|
+
"""
|
|
67
|
+
Heuristics to detect if a bokeh option is about interactivity, like
|
|
68
|
+
'selection_alpha'.
|
|
69
|
+
|
|
70
|
+
>>> is_interactive_opt('height')
|
|
71
|
+
False
|
|
72
|
+
>>> is_interactive_opt('annular_muted_alpha')
|
|
73
|
+
True
|
|
74
|
+
"""
|
|
75
|
+
interactive_flags = [
|
|
76
|
+
'hover',
|
|
77
|
+
'muted',
|
|
78
|
+
'nonselection',
|
|
79
|
+
'selection',
|
|
80
|
+
]
|
|
81
|
+
return any(part in interactive_flags for part in bk_opt.split('_'))
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _transfer_opts_cur_backend(element):
|
|
85
|
+
if Store.current_backend != 'bokeh':
|
|
86
|
+
element = element.apply(_transfer_opts, backend=Store.current_backend)
|
|
87
|
+
return element
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Matplotlib transforms
|
|
91
|
+
|
|
92
|
+
_line_cap_bk_mpl_mapping = {
|
|
93
|
+
'butt': 'butt',
|
|
94
|
+
'round': 'round',
|
|
95
|
+
'square': 'projecting',
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
_line_dash_bk_mpl_mapping = {
|
|
99
|
+
'solid': 'solid',
|
|
100
|
+
'dashed': 'dashed',
|
|
101
|
+
'dotted': 'dotted',
|
|
102
|
+
'dotdash': UNSET,
|
|
103
|
+
'dashdot': 'dashdot',
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_text_baseline_bk_mpl_mapping = {
|
|
107
|
+
'top': 'top',
|
|
108
|
+
'middle': 'center',
|
|
109
|
+
'bottom': 'bottom',
|
|
110
|
+
'alphabetic': UNSET,
|
|
111
|
+
'hanging': UNSET,
|
|
112
|
+
'ideographic': UNSET,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
MATPLOTLIB_TRANSFORMS = {
|
|
116
|
+
'plot': {
|
|
117
|
+
'height': UNSET,
|
|
118
|
+
'width': UNSET,
|
|
119
|
+
'min_height': UNSET,
|
|
120
|
+
'min_width': UNSET,
|
|
121
|
+
'max_height': UNSET,
|
|
122
|
+
'max_width': UNSET,
|
|
123
|
+
'frame_width': UNSET,
|
|
124
|
+
'frame_height': UNSET,
|
|
125
|
+
'sizing_mode': UNSET,
|
|
126
|
+
'responsive': UNSET,
|
|
127
|
+
'shared_axes': UNSET,
|
|
128
|
+
'shared_datasource': UNSET,
|
|
129
|
+
'selected': UNSET,
|
|
130
|
+
'tools': UNSET,
|
|
131
|
+
'active_tools': UNSET,
|
|
132
|
+
'default_tools': UNSET,
|
|
133
|
+
'toolbar': UNSET,
|
|
134
|
+
'align': UNSET,
|
|
135
|
+
'lod': UNSET,
|
|
136
|
+
'margin': UNSET,
|
|
137
|
+
'border': UNSET,
|
|
138
|
+
'jitter': UNSET,
|
|
139
|
+
'legend_muted': UNSET,
|
|
140
|
+
'legend_offset': UNSET,
|
|
141
|
+
'gridstyle': UNSET,
|
|
142
|
+
'colorbar_position': UNSET,
|
|
143
|
+
'violin_width': UNSET,
|
|
144
|
+
},
|
|
145
|
+
'style': {
|
|
146
|
+
'bar_width': UNSET,
|
|
147
|
+
'size': lambda k, v: ('s', v),
|
|
148
|
+
'fill_color': lambda k, v: ('facecolor', v),
|
|
149
|
+
'fill_alpha': UNSET,
|
|
150
|
+
'line_alpha': UNSET,
|
|
151
|
+
'line_cap': lambda k, v: ('capstyle', _line_cap_bk_mpl_mapping.get(v, UNSET)),
|
|
152
|
+
'line_color': lambda k, v: ('edgecolor', v),
|
|
153
|
+
'line_dash': lambda k, v: ('linestyle', _line_dash_bk_mpl_mapping.get(v, UNSET)),
|
|
154
|
+
'line_join': lambda k, v: ('joinstyle', v),
|
|
155
|
+
'line_width': lambda k, v: ('linewidth', v),
|
|
156
|
+
'palette': UNSET,
|
|
157
|
+
'click_policy': UNSET,
|
|
158
|
+
'annular_alpha': UNSET,
|
|
159
|
+
'annular_color': UNSET,
|
|
160
|
+
'annular_fill_alpha': UNSET,
|
|
161
|
+
'annular_fill_color': UNSET,
|
|
162
|
+
'annular_line_alpha': UNSET,
|
|
163
|
+
'annular_line_cap': UNSET,
|
|
164
|
+
'annular_line_color': lambda k, v: ('annular_edgecolors', v),
|
|
165
|
+
'annular_line_dash': UNSET,
|
|
166
|
+
'annular_line_join': UNSET,
|
|
167
|
+
'annular_line_width': lambda k, v: ('annular_linewidth', v),
|
|
168
|
+
'annular_visible': UNSET,
|
|
169
|
+
'dilate': UNSET,
|
|
170
|
+
'ticks_text_align': UNSET,
|
|
171
|
+
'ticks_text_alpha': UNSET,
|
|
172
|
+
'ticks_text_baseline': UNSET,
|
|
173
|
+
'ticks_text_color': UNSET,
|
|
174
|
+
'ticks_text_font': UNSET,
|
|
175
|
+
'ticks_text_font_size': UNSET,
|
|
176
|
+
'ticks_text_font_style': UNSET,
|
|
177
|
+
'xmarks_alpha': UNSET,
|
|
178
|
+
'xmarks_color': UNSET,
|
|
179
|
+
'xmarks_line_alpha': UNSET,
|
|
180
|
+
'xmarks_line_cap': UNSET,
|
|
181
|
+
'xmarks_line_color': lambda k, v: ('xmarks_edgecolor', v),
|
|
182
|
+
'xmarks_line_dash': UNSET,
|
|
183
|
+
'xmarks_line_join': UNSET,
|
|
184
|
+
'xmarks_line_width': lambda k, v: ('xmarks_linewidth', v),
|
|
185
|
+
'xmarks_visible': UNSET,
|
|
186
|
+
'ymarks_alpha': UNSET,
|
|
187
|
+
'ymarks_color': UNSET,
|
|
188
|
+
'ymarks_line_alpha': UNSET,
|
|
189
|
+
'ymarks_line_cap': UNSET,
|
|
190
|
+
'ymarks_line_color': lambda k, v: ('ymarks_edgecolor', v),
|
|
191
|
+
'ymarks_line_dash': UNSET,
|
|
192
|
+
'ymarks_line_join': UNSET,
|
|
193
|
+
'ymarks_line_width': lambda k, v: ('ymarks_linewidth', v),
|
|
194
|
+
'ymarks_visible': UNSET,
|
|
195
|
+
'lower_head': lambda k, v: ('lolims', v),
|
|
196
|
+
'upper_head': lambda k, v: ('uplims', v),
|
|
197
|
+
'whisker_color': UNSET,
|
|
198
|
+
'outlier_color': UNSET,
|
|
199
|
+
'text_align': lambda k, v: ('horizontalalignment', v),
|
|
200
|
+
'text_alpha': lambda k, v: ('alpha', v),
|
|
201
|
+
'text_baseline': lambda k, v: (
|
|
202
|
+
'verticalalignment',
|
|
203
|
+
_text_baseline_bk_mpl_mapping.get(v, UNSET),
|
|
204
|
+
),
|
|
205
|
+
'text_color': lambda k, v: ('color', v),
|
|
206
|
+
'text_font': UNSET,
|
|
207
|
+
'text_font_size': lambda k, v: ('size', v),
|
|
208
|
+
'text_font_style': UNSET,
|
|
209
|
+
'box_alpha': UNSET,
|
|
210
|
+
'box_cmap': UNSET,
|
|
211
|
+
'box_fill_alpha': UNSET,
|
|
212
|
+
'box_fill_color': UNSET,
|
|
213
|
+
'box_line_alpha': UNSET,
|
|
214
|
+
'box_line_cap': UNSET,
|
|
215
|
+
'box_line_color': UNSET,
|
|
216
|
+
'box_line_dash': UNSET,
|
|
217
|
+
'box_line_join': UNSET,
|
|
218
|
+
'box_line_width': UNSET,
|
|
219
|
+
'box_visible': UNSET,
|
|
220
|
+
'median_alpha': UNSET,
|
|
221
|
+
'median_color': UNSET,
|
|
222
|
+
'outline_alpha': UNSET,
|
|
223
|
+
'outline_color': UNSET,
|
|
224
|
+
'outline_line_alpha': UNSET,
|
|
225
|
+
'outline_line_cap': UNSET,
|
|
226
|
+
'outline_line_color': UNSET,
|
|
227
|
+
'outline_line_dash': UNSET,
|
|
228
|
+
'outline_line_join': UNSET,
|
|
229
|
+
'outline_line_width': UNSET,
|
|
230
|
+
'outline_visible': UNSET,
|
|
231
|
+
'stats_alpha': UNSET,
|
|
232
|
+
'stats_line_alpha': UNSET,
|
|
233
|
+
'stats_line_cap': UNSET,
|
|
234
|
+
'stats_line_color': UNSET,
|
|
235
|
+
'stats_line_dash': UNSET,
|
|
236
|
+
'stats_line_join': UNSET,
|
|
237
|
+
'stats_line_width': UNSET,
|
|
238
|
+
'stats_visible': UNSET,
|
|
239
|
+
'violin_alpha': UNSET,
|
|
240
|
+
'violin_cmap': UNSET,
|
|
241
|
+
'violin_color': UNSET,
|
|
242
|
+
'violin_fill_alpha': UNSET,
|
|
243
|
+
'violin_fill_color': UNSET,
|
|
244
|
+
'violin_line_alpha': UNSET,
|
|
245
|
+
'violin_line_cap': UNSET,
|
|
246
|
+
'violin_line_color': UNSET,
|
|
247
|
+
'violin_line_dash': UNSET,
|
|
248
|
+
'violin_line_join': UNSET,
|
|
249
|
+
'violin_line_width': UNSET,
|
|
250
|
+
'violin_visible': UNSET,
|
|
251
|
+
'editable': UNSET,
|
|
252
|
+
'fit_columns': UNSET,
|
|
253
|
+
'index_position': UNSET,
|
|
254
|
+
'row_headers': UNSET,
|
|
255
|
+
'scroll_to_selection': UNSET,
|
|
256
|
+
'selectable': UNSET,
|
|
257
|
+
'sortable': UNSET,
|
|
258
|
+
'edge_alpha': lambda k, v: ('edge_alpha', v),
|
|
259
|
+
'edge_cmap': lambda k, v: ('edge_cmap', v),
|
|
260
|
+
'edge_color': lambda k, v: ('edge_color', v),
|
|
261
|
+
'edge_fill_alpha': UNSET,
|
|
262
|
+
'edge_fill_color': UNSET,
|
|
263
|
+
'edge_line_alpha': UNSET,
|
|
264
|
+
'edge_line_cap': UNSET,
|
|
265
|
+
'edge_line_color': lambda k, v: ('edge_color', v),
|
|
266
|
+
'edge_line_dash': lambda k, v: ('edge_linestyle', v),
|
|
267
|
+
'edge_line_join': UNSET,
|
|
268
|
+
'edge_line_width': lambda k, v: ('edge_linewidth', v),
|
|
269
|
+
'edge_visible': UNSET,
|
|
270
|
+
'node_alpha': lambda k, v: ('node_alpha', v),
|
|
271
|
+
'node_cmap': lambda k, v: ('node_cmap', v),
|
|
272
|
+
'node_color': lambda k, v: ('node_color', v),
|
|
273
|
+
'node_fill_alpha': UNSET,
|
|
274
|
+
'node_fill_color': lambda k, v: ('node_facecolors', v),
|
|
275
|
+
'node_line_alpha': UNSET,
|
|
276
|
+
'node_line_cap': UNSET,
|
|
277
|
+
'node_line_color': lambda k, v: ('node_edgecolors', v),
|
|
278
|
+
'node_line_dash': UNSET,
|
|
279
|
+
'node_line_join': UNSET,
|
|
280
|
+
'node_line_width': lambda k, v: ('node_linewidth', v),
|
|
281
|
+
'node_marker': lambda k, v: ('node_marker', v),
|
|
282
|
+
'node_radius': UNSET,
|
|
283
|
+
'node_size': lambda k, v: ('node_size', v),
|
|
284
|
+
'node_visible': lambda k, v: ('visible', v),
|
|
285
|
+
},
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
# Plotly transforms
|
|
289
|
+
|
|
290
|
+
_line_dash_bk_plotly_mapping = {
|
|
291
|
+
'solid': 'solid',
|
|
292
|
+
'dashed': 'dash',
|
|
293
|
+
'dotted': 'dot',
|
|
294
|
+
'dotdash': UNSET,
|
|
295
|
+
'dashdot': 'dashdot',
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
PLOTLY_TRANSFORMS = {
|
|
299
|
+
'plot': {
|
|
300
|
+
'alpha': lambda k, v: ('opacity', v),
|
|
301
|
+
'min_height': UNSET,
|
|
302
|
+
'min_width': UNSET,
|
|
303
|
+
'max_height': UNSET,
|
|
304
|
+
'max_width': UNSET,
|
|
305
|
+
'frame_width': UNSET,
|
|
306
|
+
'frame_height': UNSET,
|
|
307
|
+
'batched': UNSET,
|
|
308
|
+
'legend_limit': UNSET,
|
|
309
|
+
'tools': UNSET,
|
|
310
|
+
'shared_xaxis': UNSET,
|
|
311
|
+
'shared_yaxis': UNSET,
|
|
312
|
+
},
|
|
313
|
+
'style': {
|
|
314
|
+
'alpha': lambda k, v: ('opacity', v),
|
|
315
|
+
'color': lambda k, v: (k, COLOR_ALIASES.get(v, v)),
|
|
316
|
+
'fill_color': lambda k, v: ('fillcolor', COLOR_ALIASES.get(v, v)),
|
|
317
|
+
'line_color': lambda k, v: (k, COLOR_ALIASES.get(v, v)),
|
|
318
|
+
'line_dash': lambda k, v: ('dash', _line_dash_bk_plotly_mapping.get(v, UNSET)),
|
|
319
|
+
'line_width': lambda k, v: ('line_width', v),
|
|
320
|
+
'muted_alpha': UNSET,
|
|
321
|
+
'palette': UNSET,
|
|
322
|
+
},
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
BACKEND_TRANSFORMS = dict(
|
|
327
|
+
matplotlib=MATPLOTLIB_TRANSFORMS,
|
|
328
|
+
plotly=PLOTLY_TRANSFORMS,
|
|
329
|
+
)
|