lets-plot 4.8.0rc1__cp313-cp313-macosx_12_0_arm64.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.
Potentially problematic release.
This version of lets-plot might be problematic. Click here for more details.
- lets_plot/__init__.py +283 -0
- lets_plot/_global_settings.py +192 -0
- lets_plot/_kbridge.py +149 -0
- lets_plot/_type_utils.py +133 -0
- lets_plot/_version.py +6 -0
- lets_plot/bistro/__init__.py +16 -0
- lets_plot/bistro/_plot2d_common.py +106 -0
- lets_plot/bistro/corr.py +448 -0
- lets_plot/bistro/im.py +196 -0
- lets_plot/bistro/joint.py +192 -0
- lets_plot/bistro/qq.py +207 -0
- lets_plot/bistro/residual.py +341 -0
- lets_plot/bistro/waterfall.py +332 -0
- lets_plot/export/__init__.py +6 -0
- lets_plot/export/ggsave_.py +170 -0
- lets_plot/frontend_context/__init__.py +8 -0
- lets_plot/frontend_context/_configuration.py +151 -0
- lets_plot/frontend_context/_frontend_ctx.py +16 -0
- lets_plot/frontend_context/_html_contexts.py +117 -0
- lets_plot/frontend_context/_intellij_python_json_ctx.py +38 -0
- lets_plot/frontend_context/_json_contexts.py +39 -0
- lets_plot/frontend_context/_jupyter_notebook_ctx.py +119 -0
- lets_plot/frontend_context/_mime_types.py +7 -0
- lets_plot/frontend_context/_static_html_page_ctx.py +27 -0
- lets_plot/frontend_context/_static_svg_ctx.py +26 -0
- lets_plot/frontend_context/_webbr_html_page_ctx.py +29 -0
- lets_plot/frontend_context/sandbox.py +5 -0
- lets_plot/geo_data/__init__.py +19 -0
- lets_plot/geo_data/core.py +335 -0
- lets_plot/geo_data/geocoder.py +988 -0
- lets_plot/geo_data/geocodes.py +512 -0
- lets_plot/geo_data/gis/__init__.py +0 -0
- lets_plot/geo_data/gis/fluent_dict.py +201 -0
- lets_plot/geo_data/gis/geocoding_service.py +42 -0
- lets_plot/geo_data/gis/geometry.py +91 -0
- lets_plot/geo_data/gis/json_request.py +232 -0
- lets_plot/geo_data/gis/json_response.py +308 -0
- lets_plot/geo_data/gis/request.py +492 -0
- lets_plot/geo_data/gis/response.py +247 -0
- lets_plot/geo_data/livemap_helper.py +65 -0
- lets_plot/geo_data/to_geo_data_frame.py +141 -0
- lets_plot/geo_data/type_assertion.py +34 -0
- lets_plot/geo_data_internals/__init__.py +4 -0
- lets_plot/geo_data_internals/constants.py +13 -0
- lets_plot/geo_data_internals/utils.py +33 -0
- lets_plot/mapping.py +115 -0
- lets_plot/package_data/lets-plot.min.js +3 -0
- lets_plot/plot/__init__.py +64 -0
- lets_plot/plot/_global_theme.py +14 -0
- lets_plot/plot/annotation.py +290 -0
- lets_plot/plot/coord.py +242 -0
- lets_plot/plot/core.py +1025 -0
- lets_plot/plot/expand_limits_.py +78 -0
- lets_plot/plot/facet.py +210 -0
- lets_plot/plot/font_features.py +71 -0
- lets_plot/plot/geom.py +9144 -0
- lets_plot/plot/geom_extras.py +53 -0
- lets_plot/plot/geom_function_.py +219 -0
- lets_plot/plot/geom_imshow_.py +393 -0
- lets_plot/plot/geom_livemap_.py +343 -0
- lets_plot/plot/ggbunch_.py +96 -0
- lets_plot/plot/gggrid_.py +139 -0
- lets_plot/plot/ggtb_.py +81 -0
- lets_plot/plot/guide.py +231 -0
- lets_plot/plot/label.py +187 -0
- lets_plot/plot/marginal_layer.py +181 -0
- lets_plot/plot/plot.py +245 -0
- lets_plot/plot/pos.py +344 -0
- lets_plot/plot/sampling.py +338 -0
- lets_plot/plot/sandbox_.py +26 -0
- lets_plot/plot/scale.py +3580 -0
- lets_plot/plot/scale_colormap_mpl.py +300 -0
- lets_plot/plot/scale_convenience.py +155 -0
- lets_plot/plot/scale_identity_.py +662 -0
- lets_plot/plot/scale_position.py +1342 -0
- lets_plot/plot/series_meta.py +209 -0
- lets_plot/plot/stat.py +585 -0
- lets_plot/plot/subplots.py +331 -0
- lets_plot/plot/subplots_util.py +24 -0
- lets_plot/plot/theme_.py +795 -0
- lets_plot/plot/theme_set.py +418 -0
- lets_plot/plot/tooltip.py +486 -0
- lets_plot/plot/util.py +267 -0
- lets_plot/settings_utils.py +244 -0
- lets_plot/tilesets.py +429 -0
- lets_plot-4.8.0rc1.dist-info/METADATA +220 -0
- lets_plot-4.8.0rc1.dist-info/RECORD +95 -0
- lets_plot-4.8.0rc1.dist-info/WHEEL +5 -0
- lets_plot-4.8.0rc1.dist-info/licenses/LICENSE +21 -0
- lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.FreeType +166 -0
- lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.ImageMagick +106 -0
- lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.expat +21 -0
- lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.fontconfig +200 -0
- lets_plot-4.8.0rc1.dist-info/top_level.txt +2 -0
- lets_plot_kotlin_bridge.cpython-313-darwin.so +0 -0
lets_plot/_type_utils.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2019. JetBrains s.r.o.
|
|
3
|
+
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
|
|
4
|
+
#
|
|
5
|
+
import json
|
|
6
|
+
import math
|
|
7
|
+
from datetime import datetime, date, time, timezone
|
|
8
|
+
|
|
9
|
+
from typing import Dict
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import numpy
|
|
13
|
+
except ImportError:
|
|
14
|
+
numpy = None
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import pandas
|
|
18
|
+
except ImportError:
|
|
19
|
+
pandas = None
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import polars
|
|
23
|
+
except ImportError:
|
|
24
|
+
polars = None
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
import shapely
|
|
28
|
+
import shapely.geometry
|
|
29
|
+
except ImportError:
|
|
30
|
+
shapely = None
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
import jax.numpy as jnp
|
|
34
|
+
except ImportError:
|
|
35
|
+
jnp = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Parameter 'value' can also be pandas.DataFrame
|
|
39
|
+
def standardize_dict(value: Dict) -> Dict:
|
|
40
|
+
result = {}
|
|
41
|
+
for k, v in value.items():
|
|
42
|
+
result[_standardize_value(k)] = _standardize_value(v)
|
|
43
|
+
|
|
44
|
+
return result
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def is_pandas_data_frame(v) -> bool:
|
|
48
|
+
return pandas and isinstance(v, pandas.DataFrame)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def is_polars_dataframe(v):
|
|
52
|
+
return polars and isinstance(v, polars.DataFrame)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def is_dict_or_dataframe(v):
|
|
56
|
+
return isinstance(v, dict) or (pandas and isinstance(v, pandas.DataFrame))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def is_int(v):
|
|
60
|
+
return isinstance(v, int) or (numpy and isinstance(v, numpy.integer)) or (jnp and isinstance(v, jnp.integer))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def is_float(v):
|
|
64
|
+
return isinstance(v, float) or (numpy and isinstance(v, numpy.floating)) or (jnp and isinstance(v, jnp.floating))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def is_ndarray(data) -> bool:
|
|
68
|
+
return (numpy and isinstance(data, numpy.ndarray)) or (jnp and isinstance(data, jnp.ndarray))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def is_number(v):
|
|
72
|
+
return is_int(v) or is_float(v)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _standardize_value(v):
|
|
76
|
+
if v is None:
|
|
77
|
+
return v
|
|
78
|
+
if isinstance(v, bool):
|
|
79
|
+
return bool(v)
|
|
80
|
+
if isinstance(v, str):
|
|
81
|
+
return str(v)
|
|
82
|
+
if is_float(v):
|
|
83
|
+
if math.isfinite(v):
|
|
84
|
+
return float(v)
|
|
85
|
+
# None for special values like 'nan' etc. because
|
|
86
|
+
# some JSON parsers (like com.google.gson.Gson) do not handle them well.
|
|
87
|
+
return None
|
|
88
|
+
if is_int(v):
|
|
89
|
+
return float(v)
|
|
90
|
+
if is_dict_or_dataframe(v):
|
|
91
|
+
return standardize_dict(v)
|
|
92
|
+
if is_polars_dataframe(v):
|
|
93
|
+
return standardize_dict(v.to_dict(as_series=False))
|
|
94
|
+
if isinstance(v, list):
|
|
95
|
+
return [_standardize_value(elem) for elem in v]
|
|
96
|
+
if isinstance(v, tuple):
|
|
97
|
+
return tuple(_standardize_value(elem) for elem in v)
|
|
98
|
+
|
|
99
|
+
if (numpy and isinstance(v, numpy.ndarray)):
|
|
100
|
+
# Process each array element individually.
|
|
101
|
+
# Don't use '.tolist()' because this will implicitly
|
|
102
|
+
# convert 'datetime64' values to unpredictable 'datetime' objects.
|
|
103
|
+
return [_standardize_value(x) for x in v]
|
|
104
|
+
|
|
105
|
+
if (pandas and isinstance(v, pandas.Series)) or (jnp and isinstance(v, jnp.ndarray)):
|
|
106
|
+
return _standardize_value(v.tolist())
|
|
107
|
+
|
|
108
|
+
# Universal NaT/NaN check
|
|
109
|
+
if pandas and pandas.isna(v):
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
if isinstance(v, datetime):
|
|
113
|
+
# Datetime: to milliseconds since epoch (time zone aware)
|
|
114
|
+
return v.timestamp() * 1000
|
|
115
|
+
if isinstance(v, date):
|
|
116
|
+
# Local date: to milliseconds since epoch (midnight UTC)
|
|
117
|
+
return datetime.combine(v, time.min, tzinfo=timezone.utc).timestamp() * 1000
|
|
118
|
+
if isinstance(v, time):
|
|
119
|
+
# Local time: to milliseconds since midnight
|
|
120
|
+
return float(v.hour * 3600_000 + v.minute * 60_000 + v.second * 1000 + v.microsecond // 1000)
|
|
121
|
+
if numpy and isinstance(v, numpy.datetime64):
|
|
122
|
+
try:
|
|
123
|
+
# numpy.datetime64: to milliseconds since epoch (Unix time)
|
|
124
|
+
return float(v.astype('datetime64[ms]').astype(numpy.int64))
|
|
125
|
+
except:
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
if shapely and isinstance(v, shapely.geometry.base.BaseGeometry):
|
|
129
|
+
return json.dumps(shapely.geometry.mapping(v))
|
|
130
|
+
try:
|
|
131
|
+
return repr(v)
|
|
132
|
+
except Exception:
|
|
133
|
+
raise Exception('Unsupported type: {0}({1})'.format(v, type(v)))
|
lets_plot/_version.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copyright (c) 2020. JetBrains s.r.o.
|
|
2
|
+
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
from .corr import *
|
|
5
|
+
from .im import *
|
|
6
|
+
from .qq import *
|
|
7
|
+
from .residual import *
|
|
8
|
+
from .joint import *
|
|
9
|
+
from .waterfall import *
|
|
10
|
+
|
|
11
|
+
__all__ = (im.__all__ +
|
|
12
|
+
corr.__all__ +
|
|
13
|
+
qq.__all__ +
|
|
14
|
+
residual.__all__ +
|
|
15
|
+
joint.__all__ +
|
|
16
|
+
waterfall.__all__)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023. JetBrains s.r.o.
|
|
3
|
+
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
|
|
4
|
+
#
|
|
5
|
+
from ..plot.core import DummySpec, aes
|
|
6
|
+
from ..plot.geom import *
|
|
7
|
+
from ..plot.marginal_layer import ggmarginal
|
|
8
|
+
|
|
9
|
+
_BINS_DEF = 30
|
|
10
|
+
_COLOR_DEF = "pen"
|
|
11
|
+
|
|
12
|
+
_MARGINAL_ALPHA = .1
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_bin_params_2d(xs, ys, binwidth, bins):
|
|
16
|
+
if isinstance(bins, int):
|
|
17
|
+
bins = [bins, bins]
|
|
18
|
+
if isinstance(binwidth, int) or isinstance(binwidth, float):
|
|
19
|
+
binwidth = [binwidth, binwidth]
|
|
20
|
+
if binwidth is not None or bins is not None or len(xs) == 0:
|
|
21
|
+
return binwidth, bins
|
|
22
|
+
binwidth_x = (max(xs) - min(xs)) / _BINS_DEF
|
|
23
|
+
binwidth_y = (max(ys) - min(ys)) / _BINS_DEF
|
|
24
|
+
binwidth_max = max(binwidth_x, binwidth_y)
|
|
25
|
+
|
|
26
|
+
return [binwidth_max, binwidth_max], bins
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _get_geom2d_layer(geom_kind, binwidth2d, bins2d, color, color_by, size, alpha, show_legend):
|
|
30
|
+
if geom_kind == 'point':
|
|
31
|
+
return geom_point(color=color, size=size, alpha=alpha, show_legend=show_legend)
|
|
32
|
+
if geom_kind == 'tile':
|
|
33
|
+
return geom_bin2d(
|
|
34
|
+
aes(fill=('..count..' if color_by is None else color_by)),
|
|
35
|
+
bins=bins2d, binwidth=binwidth2d,
|
|
36
|
+
color=color, size=size, alpha=alpha,
|
|
37
|
+
show_legend=show_legend
|
|
38
|
+
)
|
|
39
|
+
if geom_kind == 'hex':
|
|
40
|
+
return geom_hex(
|
|
41
|
+
aes(fill=('..count..' if color_by is None else color_by)),
|
|
42
|
+
bins=bins2d, binwidth=binwidth2d,
|
|
43
|
+
color=color, size=size, alpha=alpha,
|
|
44
|
+
show_legend=show_legend
|
|
45
|
+
)
|
|
46
|
+
if geom_kind == 'density2d':
|
|
47
|
+
return geom_density2d(
|
|
48
|
+
aes(color=('..group..' if color_by is None else color_by)),
|
|
49
|
+
color=color, size=size, alpha=alpha,
|
|
50
|
+
show_legend=show_legend
|
|
51
|
+
)
|
|
52
|
+
if geom_kind == 'density2df':
|
|
53
|
+
return geom_density2df(
|
|
54
|
+
aes(fill=('..group..' if color_by is None else color_by)),
|
|
55
|
+
color=color, size=size, alpha=alpha,
|
|
56
|
+
show_legend=show_legend
|
|
57
|
+
)
|
|
58
|
+
if geom_kind == 'pointdensity':
|
|
59
|
+
return geom_pointdensity(
|
|
60
|
+
aes(color=('..density..' if color_by is None else color_by)),
|
|
61
|
+
color=color, size=size, alpha=alpha,
|
|
62
|
+
show_legend=show_legend
|
|
63
|
+
)
|
|
64
|
+
if geom_kind == 'none':
|
|
65
|
+
return None
|
|
66
|
+
raise Exception("Unknown geom '{0}'".format(geom_kind))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _get_marginal_layers(marginal, binwidth2d, bins2d, color, color_by, show_legend):
|
|
70
|
+
marginal_color = None if color_by is not None else (color or _COLOR_DEF)
|
|
71
|
+
|
|
72
|
+
def bin_param_to_1d(param2d, side):
|
|
73
|
+
if param2d is None:
|
|
74
|
+
return None
|
|
75
|
+
else:
|
|
76
|
+
if side in ['t', 'b']:
|
|
77
|
+
return param2d[0]
|
|
78
|
+
else:
|
|
79
|
+
return param2d[1]
|
|
80
|
+
|
|
81
|
+
def _get_marginal_layer(geom_kind, side, size):
|
|
82
|
+
if geom_kind in ['dens', 'density']:
|
|
83
|
+
layer = geom_area(stat='density', position='identity', color=marginal_color, fill=marginal_color,
|
|
84
|
+
alpha=_MARGINAL_ALPHA, show_legend=show_legend)
|
|
85
|
+
elif geom_kind in ['hist', 'histogram']:
|
|
86
|
+
binwidth = bin_param_to_1d(binwidth2d, side)
|
|
87
|
+
bins = bin_param_to_1d(bins2d, side)
|
|
88
|
+
layer = geom_histogram(bins=bins, binwidth=binwidth,
|
|
89
|
+
color=marginal_color, fill=marginal_color, alpha=_MARGINAL_ALPHA,
|
|
90
|
+
show_legend=show_legend)
|
|
91
|
+
elif geom_kind in ['box', 'boxplot']:
|
|
92
|
+
layer = geom_boxplot(color=marginal_color, fill=marginal_color, alpha=_MARGINAL_ALPHA, show_legend=show_legend)
|
|
93
|
+
else:
|
|
94
|
+
raise Exception("Unknown geom '{0}'".format(geom_kind))
|
|
95
|
+
|
|
96
|
+
return ggmarginal(side, size=size, layer=layer)
|
|
97
|
+
|
|
98
|
+
result = DummySpec()
|
|
99
|
+
for layer_description in filter(bool, marginal.split(",")):
|
|
100
|
+
params = layer_description.strip().split(":")
|
|
101
|
+
geom_kind, sides = params[0].strip(), params[1].strip()
|
|
102
|
+
size = float(params[2].strip()) if len(params) > 2 else None
|
|
103
|
+
for side in sides:
|
|
104
|
+
result += _get_marginal_layer(geom_kind, side, size)
|
|
105
|
+
|
|
106
|
+
return result
|